[seahorse/nielsdg/gtk4: 2/2] Port to GTK4
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/nielsdg/gtk4: 2/2] Port to GTK4
- Date: Thu, 7 Jul 2022 11:30:10 +0000 (UTC)
commit 01e252343cc3cb63572b31f63f445b6ce1a51606
Author: Niels De Graef <nielsdegraef gmail com>
Date: Fri Jul 1 10:40:42 2022 +0200
Port to GTK4
common/add-keyserver-dialog.vala | 3 +-
common/backend.vala | 29 +-
common/catalog.vala | 38 +-
common/config.vapi | 38 +-
common/datepicker.vala | 23 +-
common/deletable.vala | 4 +-
common/delete-dialog.vala | 142 ++---
common/deleter.vala | 20 +-
common/exportable.vala | 440 +++++++-------
common/icons.vala | 44 --
common/interaction.vala | 4 +-
common/item-list.vala | 226 -------
common/meson.build | 9 +-
common/passphrase-prompt.vala | 107 ++--
common/place.vala | 10 +-
common/prefs-keyservers.vala | 40 +-
common/prefs.vala | 2 +-
common/seahorse-prefs-keyservers.ui | 6 +-
common/util.vala | 43 +-
common/viewable.vala | 3 +-
gkr/gkr-backend.vala | 388 ++++++------
gkr/gkr-dialogs.vala | 93 ++-
gkr/gkr-item-add.vala | 32 +-
gkr/gkr-item-properties.vala | 82 ++-
gkr/gkr-item.vala | 10 +-
gkr/gkr-keyring-add.vala | 9 +-
gkr/gkr-keyring.vala | 112 ++--
gkr/gkr-password-entry.vala | 51 --
gkr/meson.build | 6 +-
gkr/seahorse-gkr-add-item.ui | 114 +---
gkr/seahorse-gkr-add-keyring.ui | 89 +--
gkr/seahorse-gkr-item-properties.ui | 116 +---
libseahorse/meson.build | 2 +-
libseahorse/seahorse-progress.c | 2 +-
meson.build | 8 +-
pgp/meson.build | 3 +-
pgp/seahorse-combo-keys.c | 362 ------------
pgp/seahorse-combo-keys.h | 46 --
pgp/seahorse-gpgme-add-uid.c | 43 +-
pgp/seahorse-gpgme-add-uid.ui | 2 -
pgp/seahorse-gpgme-dialogs.h | 3 -
pgp/seahorse-gpgme-expires-dialog.c | 21 +-
pgp/seahorse-gpgme-expires-dialog.ui | 22 +-
pgp/seahorse-gpgme-generate-dialog.c | 159 +++--
pgp/seahorse-gpgme-generate-dialog.ui | 325 +++-------
pgp/seahorse-gpgme-key-deleter.c | 2 +-
pgp/seahorse-gpgme-key-op.c | 6 -
pgp/seahorse-gpgme-keyring.c | 134 ++---
pgp/seahorse-gpgme-photos.c | 129 ++--
pgp/seahorse-gpgme-revoke-dialog.c | 2 +-
pgp/seahorse-gpgme-sign-dialog.c | 37 +-
pgp/seahorse-gpgme-sign-dialog.ui | 79 +--
pgp/seahorse-hkp-source.c | 23 +-
pgp/seahorse-keyserver-results.c | 103 +---
pgp/seahorse-keyserver-results.ui | 13 -
pgp/seahorse-keyserver-search.c | 23 +-
pgp/seahorse-keyserver-search.ui | 42 +-
pgp/seahorse-keyserver-sync.c | 39 +-
pgp/seahorse-keyserver-sync.h | 6 +-
pgp/seahorse-ldap-source.c | 44 +-
pgp/seahorse-pgp-actions.c | 101 ++--
pgp/seahorse-pgp-backend.c | 48 +-
pgp/seahorse-pgp-backend.h | 16 +-
pgp/seahorse-pgp-key-properties.c | 180 ++----
pgp/seahorse-pgp-key.c | 16 +-
pgp/seahorse-pgp-keysets.c | 74 +--
pgp/seahorse-pgp-keysets.h | 14 +-
pgp/seahorse-pgp-private-key-properties.ui | 197 ++-----
pgp/seahorse-pgp-public-key-properties.ui | 202 ++-----
pgp/seahorse-pgp-subkey-list-box-row.ui | 98 ++-
pgp/seahorse-pgp-subkey-list-box.c | 52 +-
pgp/seahorse-pgp-subkey-list-box.h | 4 +-
pgp/seahorse-pgp-uid-list-box-row.ui | 20 +-
pgp/seahorse-pgp-uid-list-box.c | 48 +-
pgp/seahorse-pgp-uid-list-box.h | 4 +-
pgp/seahorse-server-source.c | 192 +++---
pgp/seahorse-server-source.h | 72 ++-
pgp/seahorse-transfer.c | 7 +-
pgp/seahorse-unknown-source.c | 198 +++----
pgp/seahorse-unknown-source.h | 25 +-
pgp/seahorse-unknown.c | 101 +++-
pgp/seahorse-unknown.h | 31 +-
pgp/test-gpgme-backend.c | 4 +-
pkcs11/certificate-der-exporter.vala | 2 +-
pkcs11/meson.build | 2 +-
pkcs11/pkcs11-certificate.vala | 426 +++++++-------
pkcs11/pkcs11-deleter.vala | 12 +-
pkcs11/pkcs11-generate.vala | 68 +--
pkcs11/pkcs11-key-deleter.vala | 2 +-
pkcs11/pkcs11-private-key.vala | 197 +++----
pkcs11/pkcs11-properties.vala | 64 +-
pkcs11/pkcs11-request.vala | 225 ++++---
pkcs11/pkcs11-token-filter.vala | 63 ++
pkcs11/pkcs11-token.vala | 917 ++++++++++++++---------------
pkcs11/seahorse-pkcs11-backend.c | 463 +++++++--------
pkcs11/seahorse-pkcs11-backend.h | 14 +-
pkcs11/seahorse-pkcs11-generate.ui | 211 ++-----
pkcs11/seahorse-pkcs11-properties.ui | 16 +-
src/application.vala | 20 +-
src/import-dialog.vala | 79 +--
src/key-manager-filter.vala | 125 ++++
src/key-manager-item-row.vala | 11 +-
src/key-manager.vala | 280 +++++----
src/meson.build | 5 +-
src/seahorse-key-manager.ui | 484 ++++++---------
src/search-provider.vala | 56 +-
src/sidebar.vala | 299 +++-------
ssh/actions.vala | 19 +-
ssh/backend.vala | 18 +-
ssh/deleter.vala | 2 +-
ssh/exporter.vala | 4 +-
ssh/generate.vala | 10 +-
ssh/key-length-chooser.vala | 25 +-
ssh/key-properties.vala | 53 +-
ssh/key.vala | 4 +-
ssh/meson.build | 9 +-
ssh/operation.vala | 5 -
ssh/seahorse-ssh-askpass.c | 210 +++----
ssh/seahorse-ssh-generate.ui | 225 ++-----
ssh/seahorse-ssh-key-properties.ui | 247 ++------
ssh/source.vala | 53 +-
ssh/upload.vala | 19 +-
122 files changed, 4208 insertions(+), 6453 deletions(-)
---
diff --git a/common/add-keyserver-dialog.vala b/common/add-keyserver-dialog.vala
index 3437d285..55b4fbbb 100644
--- a/common/add-keyserver-dialog.vala
+++ b/common/add-keyserver-dialog.vala
@@ -32,7 +32,6 @@ public class Seahorse.AddKeyserverDialog : Gtk.Dialog {
title: _("Add Key Server"),
transient_for: parent,
modal: true,
- window_position: Gtk.WindowPosition.CENTER_ON_PARENT,
default_width: 400,
use_header_bar: 1
);
@@ -47,7 +46,7 @@ public class Seahorse.AddKeyserverDialog : Gtk.Dialog {
GLib.critical("%s", err.message);
}
Gtk.Box content = (Gtk.Box) builder.get_object("add-keyserver");
- get_content_area().add(content);
+ set_child(content);
this.keyserver_host = (Gtk.Entry) builder.get_object("keyserver-host");
this.keyserver_port = (Gtk.Entry) builder.get_object("keyserver-port");
this.keyserver_type = (Gtk.ComboBoxText) builder.get_object("keyserver-type");
diff --git a/common/backend.vala b/common/backend.vala
index ec0508cc..94d636d0 100644
--- a/common/backend.vala
+++ b/common/backend.vala
@@ -16,24 +16,21 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-namespace Seahorse {
+public interface Seahorse.Backend : GLib.ListModel {
-public interface Backend : Gcr.Collection {
- public abstract string name { get; }
- public abstract string label { get; }
- public abstract string description { get; }
- public abstract ActionGroup actions { owned get; }
- public abstract bool loaded { get; }
+ public abstract string name { get; }
+ public abstract string label { get; }
+ public abstract string description { get; }
+ public abstract ActionGroup actions { owned get; }
+ public abstract bool loaded { get; }
- public abstract Place? lookup_place(string uri);
+ public abstract Place? lookup_place(string uri);
- public void register() {
- Registry.register_object(this, "backend");
- }
-
- public static GLib.List<Backend> get_registered() {
- return (GLib.List<Seahorse.Backend>)Registry.object_instances("backend");
- }
-}
+ public void register() {
+ Registry.register_object(this, "backend");
+ }
+ public static GLib.List<Backend> get_registered() {
+ return (GLib.List<Seahorse.Backend>)Registry.object_instances("backend");
+ }
}
diff --git a/common/catalog.vala b/common/catalog.vala
index 2cff02e5..417f9143 100644
--- a/common/catalog.vala
+++ b/common/catalog.vala
@@ -20,16 +20,14 @@
namespace Seahorse {
-public abstract class Catalog : Gtk.ApplicationWindow {
+public abstract class Catalog : Adw.ApplicationWindow {
/* Set by the derived classes */
public string ui_name { construct; get; }
protected MenuModel context_menu;
- private bool _disposed;
private GLib.Settings _settings;
- public abstract GLib.List<weak Backend> get_backends();
public abstract GLib.List<GLib.Object> get_selected_objects();
private const ActionEntry[] ACTION_ENTRIES = {
@@ -46,7 +44,7 @@ public abstract class Catalog : Gtk.ApplicationWindow {
var width = this._settings.get_int("width");
var height = this._settings.get_int("height");
if (width > 0 && height > 0)
- this.resize (width, height);
+ set_default_size (width, height);
Gtk.Builder builder = new Gtk.Builder.from_resource(
"/org/gnome/Seahorse/seahorse-%s-widgets.ui".printf(this.ui_name)
@@ -56,17 +54,11 @@ public abstract class Catalog : Gtk.ApplicationWindow {
add_action_entries (ACTION_ENTRIES, this);
}
- public override void dispose() {
- if (!this._disposed) {
- this._disposed = true;
+ public override bool close_request() {
+ this._settings.set_int("width", this.default_width);
+ this._settings.set_int("height", this.default_height);
- int width, height;
- this.get_size(out width, out height);
- this._settings.set_int("width", width);
- this._settings.set_int("height", height);
- }
-
- base.dispose();
+ return base.close_request();
}
public virtual signal void selection_changed() {
@@ -97,13 +89,18 @@ public abstract class Catalog : Gtk.ApplicationWindow {
}
public void show_context_menu(Gdk.Event? event) {
- Gtk.Menu menu = new Gtk.Menu.from_model(this.context_menu);
+ var menu = new Gtk.PopoverMenu.from_model(this.context_menu);
menu.insert_action_group("win", this);
- foreach (weak Backend backend in get_backends()) {
+ foreach (unowned var backend in Backend.get_registered()) {
ActionGroup actions = backend.actions;
menu.insert_action_group(actions.prefix, actions);
}
- menu.popup_at_pointer(event);
+
+ if (event != null) {
+ double x, y;
+ event.get_position(out x, out y);
+ menu.set_pointing_to({ (int) x, (int) y, 1, 1 });
+ }
menu.show();
}
@@ -140,10 +137,13 @@ public abstract class Catalog : Gtk.ApplicationWindow {
return;
}
+ var val = Value(typeof(string));
+ val.set_string((string) output);
+
/* TODO: Print message if only partially exported */
- var board = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
- board.set_text ((string)output, output.length);
+ var board = get_clipboard();
+ board.set_value(val);
}
}
diff --git a/common/config.vapi b/common/config.vapi
index 469481b3..3e637b11 100644
--- a/common/config.vapi
+++ b/common/config.vapi
@@ -5,23 +5,23 @@ namespace Config
public const string PROFILE;
- public const string PKGDATADIR;
+ public const string PKGDATADIR;
- public const string EXECDIR;
- public const string LOCALEDIR;
+ public const string EXECDIR;
+ public const string LOCALEDIR;
- public const string VERSION;
- public const string PACKAGE;
- public const string PACKAGE_STRING;
- public const string GETTEXT_PACKAGE;
+ public const string VERSION;
+ public const string PACKAGE;
+ public const string PACKAGE_STRING;
+ public const string GETTEXT_PACKAGE;
- public const string SSH_PATH;
- public const string SSH_KEYGEN_PATH;
+ public const string SSH_PATH;
+ public const string SSH_KEYGEN_PATH;
- public const string GNUPG;
- public const int GPG_MAJOR;
- public const int GPG_MINOR;
- public const int GPG_MICRO;
+ public const string GNUPG;
+ public const int GPG_MAJOR;
+ public const int GPG_MINOR;
+ public const int GPG_MICRO;
}
/*
@@ -43,11 +43,11 @@ public static GLib.EqualFunc<ulong?> ulong_equal;
[CCode (cheader_filename = "libseahorse/seahorse-progress.h")]
namespace Progress {
- public void show(GLib.Cancellable? cancellable, string title, bool delayed);
+ public void show(GLib.Cancellable? cancellable, string title, bool delayed);
}
[CCode (cheader_filename = "pgp/seahorse-pgp-backend.h")]
-public class Pgp.Backend : GLib.Object, Gcr.Collection, Place {
+public class Pgp.Backend : GLib.Object, GLib.ListModel, Place {
public static void initialize(string? gpg_homedir);
public static unowned Pgp.Backend get();
@@ -57,7 +57,7 @@ public class Pgp.Backend : GLib.Object, Gcr.Collection, Place {
}
[CCode (cheader_filename = "pgp/seahorse-server-source.h")]
-public class ServerSource : GLib.Object, Gcr.Collection, Place {
+public class ServerSource : GLib.Object, GLib.ListModel, Place {
}
#if WITH_LDAP
@@ -79,8 +79,8 @@ public static bool hkp_is_valid_uri(string uri);
#endif // WITH_HKP
[CCode (cheader_filename = "pkcs11/seahorse-pkcs11-backend.h")]
-public class Pkcs11.Backend {
- public static void initialize();
- public static Gcr.Collection get_writable_tokens(Pkcs11.Backend? self, ulong with_mechanism);
+public class Pkcs11.Backend : GLib.Object, GLib.ListModel {
+ public static void initialize();
+ public static unowned Pkcs11.Backend get();
}
}
diff --git a/common/datepicker.vala b/common/datepicker.vala
index 2183492c..f584929c 100644
--- a/common/datepicker.vala
+++ b/common/datepicker.vala
@@ -37,15 +37,13 @@ public class Seahorse.DatePicker : Gtk.Box {
this._datetime = value;
this.date_entry.text = value.format("%F");
- // Note: GtkCalendar's months are [0,11] while GDateTime uses [1,12]
- this.calendar.select_month(value.get_month() - 1, value.get_year());
- this.calendar.select_day(value.get_day_of_month());
+ this.calendar.select_day (value);
}
}
construct {
this.orientation = Gtk.Orientation.HORIZONTAL;
- get_style_context().add_class("linked");
+ add_css_class("linked");
// The entry for manual editing
this.date_entry = new Gtk.Entry();
@@ -54,16 +52,16 @@ public class Seahorse.DatePicker : Gtk.Box {
this.date_entry.max_width_chars = 10;
this.date_entry.tooltip_text = _("Enter the date directly");
this.date_entry.activate.connect(on_date_entry_activated);
- add(this.date_entry);
+ append(this.date_entry);
// The button with a popover
var calendar_button = new Gtk.MenuButton();
calendar_button.visible = true;
calendar_button.tooltip_text = _("Select the date from a calendar");
- add(calendar_button);
+ append(calendar_button);
// The popover that contains the calendar
- this.calendar_popover = new Gtk.Popover(calendar_button);
+ this.calendar_popover = new Gtk.Popover();
calendar_button.popover = this.calendar_popover;
// The calendar
@@ -72,8 +70,9 @@ public class Seahorse.DatePicker : Gtk.Box {
this.calendar.show_day_names = true;
this.calendar.show_heading = true;
this.calendar.day_selected.connect(on_calendar_day_selected);
- this.calendar.day_selected_double_click.connect(on_calendar_day_selected_double_click);
- this.calendar_popover.add(this.calendar);
+ // XXX
+ // this.calendar.day_selected_double_click.connect(on_calendar_day_selected_double_click);
+ this.calendar_popover.set_child(this.calendar);
}
[CCode (type="GtkWidget*")]
@@ -97,11 +96,7 @@ public class Seahorse.DatePicker : Gtk.Box {
}
private void on_calendar_day_selected(Gtk.Calendar calendar) {
- uint y, m, d;
-
- calendar.get_date(out y, out m, out d);
- // Note: GtkCalendar's months are [0,11] while GDateTime uses [1,12]
- this.datetime = new DateTime.utc((int) y, (int) m + 1, (int) d, 0, 0, 0);
+ this.datetime = calendar.get_date().to_utc();
}
private void on_calendar_day_selected_double_click(Gtk.Calendar calendar) {
diff --git a/common/deletable.vala b/common/deletable.vala
index 58b78e6d..18e884cd 100644
--- a/common/deletable.vala
+++ b/common/deletable.vala
@@ -62,7 +62,9 @@ public interface Deletable : GLib.Object {
}
/* Now show a prompt choosing between the exporters */
- var ret = deleter.prompt(parent);
+ // XXX
+ // var ret = deleter.prompt(parent);
+ var ret = false;
if (!ret)
break;
diff --git a/common/delete-dialog.vala b/common/delete-dialog.vala
index 013c81fd..8ba8ce85 100644
--- a/common/delete-dialog.vala
+++ b/common/delete-dialog.vala
@@ -19,93 +19,75 @@
* Author: Stef Walter <stefw collabora co uk>
*/
-namespace Seahorse {
+public class Seahorse.DeleteDialog : Adw.MessageDialog {
-public class DeleteDialog : Gtk.MessageDialog {
- private Gtk.ToggleButton _check;
- private bool _check_require;
+ private Gtk.CheckButton _check;
+ private bool _check_require;
- public string? check_label {
- get {
- if (_check.get_visible())
- return _check.get_label();
- return null;
- }
- set {
- if (value == null) {
- _check.hide();
- value = "";
- } else {
- _check.show();
- }
- _check.set_label(value);
- }
- }
+ public string? check_label {
+ get {
+ if (_check.get_visible())
+ return _check.get_label();
+ return null;
+ }
+ set {
+ if (value == null) {
+ _check.hide();
+ value = "";
+ } else {
+ _check.show();
+ }
+ _check.set_label(value);
+ }
+ }
- public bool check_value {
- get {
- if (_check.get_visible())
- return _check.get_active();
- return false;
- }
- set {
- _check.set_active(value);
- }
- }
+ public bool check_value {
+ get {
+ if (_check.get_visible())
+ return _check.get_active();
+ return false;
+ }
+ set {
+ _check.set_active(value);
+ }
+ }
- public bool check_require {
- get {
- return _check_require;
- }
- set {
- _check_require = value;
- update_response_buttons();
- }
- }
+ public bool check_require {
+ get {
+ return _check_require;
+ }
+ set {
+ _check_require = value;
+ update_response_buttons();
+ }
+ }
- [CCode (type = "GtkDialog*")]
- public DeleteDialog(Gtk.Window? parent,
- string format,
- ...) {
- GLib.Object(
- message_type: Gtk.MessageType.QUESTION,
- transient_for: parent,
- text: format.vprintf(va_list())
- );
- }
+ public DeleteDialog(Gtk.Window? parent,
+ string format,
+ ...) {
+ GLib.Object(
+ transient_for: parent,
+ body: format.vprintf(va_list())
+ );
+ }
- construct {
- set_modal(true);
- set_destroy_with_parent(true);
+ construct {
+ set_modal(true);
+ set_destroy_with_parent(true);
- _check = new Gtk.CheckButton();
- ((Gtk.Container)get_message_area()).add(_check);
- _check.toggled.connect((toggle) => {
- update_response_buttons();
- });
+ this._check = new Gtk.CheckButton();
+ set_extra_child(this._check);
+ this._check.toggled.connect((toggle) => {
+ update_response_buttons();
+ });
- var cancel = new Gtk.Button.with_mnemonic(_("_Cancel"));
- add_action_widget(cancel, Gtk.ResponseType.CANCEL);
- cancel.show();
-
- var delet = new Gtk.Button.with_mnemonic(_("_Delete"));
- delet.get_style_context().add_class("destructive-action");
- add_action_widget(delet, Gtk.ResponseType.OK);
- delet.show();
- }
-
- private void update_response_buttons() {
- set_response_sensitive(Gtk.ResponseType.OK,
- !_check_require || _check.get_active());
- }
-
- public static bool prompt (Gtk.Window? parent, string text) {
- Gtk.Dialog? dialog = new DeleteDialog(parent, "%s", text);
- var response = dialog.run();
- dialog.destroy();
- return (response == Gtk.ResponseType.OK);
- }
-
-}
+ add_response("cancel", _("_Cancel"));
+ add_response("delete", _("_Delete"));
+ set_response_appearance("delete", Adw.ResponseAppearance.DESTRUCTIVE);
+ }
+ private void update_response_buttons() {
+ set_response_enabled("delete",
+ !_check_require || _check.get_active());
+ }
}
diff --git a/common/deleter.vala b/common/deleter.vala
index 1c50cdaf..4f3e6d0e 100644
--- a/common/deleter.vala
+++ b/common/deleter.vala
@@ -19,23 +19,13 @@
* Author: Stef Walter <stefw collabora co uk>
*/
-namespace Seahorse {
+public abstract class Seahorse.Deleter : GLib.Object {
-public abstract class Deleter : GLib.Object {
- public abstract Gtk.Dialog create_confirm(Gtk.Window? parent);
+ public abstract Gtk.Window create_confirm(Gtk.Window? parent);
- public abstract unowned GLib.List<GLib.Object> get_objects();
+ public abstract unowned GLib.List<GLib.Object> get_objects();
- public abstract bool add_object (GLib.Object obj);
-
- public abstract async bool delete(GLib.Cancellable? cancellable) throws GLib.Error;
-
- public bool prompt(Gtk.Window? parent) {
- var prompt = this.create_confirm(parent);
- int res = prompt.run();
- prompt.destroy();
- return res == Gtk.ResponseType.OK || res == Gtk.ResponseType.ACCEPT;
- }
-}
+ public abstract bool add_object(GLib.Object obj);
+ public abstract async bool delete(GLib.Cancellable? cancellable) throws GLib.Error;
}
diff --git a/common/exportable.vala b/common/exportable.vala
index 8ed2db46..f02c612c 100644
--- a/common/exportable.vala
+++ b/common/exportable.vala
@@ -21,221 +21,231 @@
namespace Seahorse {
public interface Exportable : GLib.Object {
- public abstract bool exportable { get; }
-
- public abstract GLib.List<Exporter> create_exporters(ExporterType type);
-
- public static bool can_export(GLib.Object object) {
- if (object is Exportable)
- return ((Exportable)object).exportable;
- return false;
- }
-
- public static int export_to_directory_wait(GLib.List<GLib.Object> objects,
- string directory) throws GLib.Error {
- var loop = new GLib.MainLoop (null, false);
- GLib.AsyncResult? result = null;
- int count = 0;
-
- foreach (var object in objects) {
- if (!Exportable.can_export(object))
- continue;
-
- var exporters = ((Exportable)object).create_exporters(ExporterType.ANY);
- if (exporters == null)
- continue;
-
- var exporter = exporters.data;
- string filename = GLib.Path.build_filename (directory, exporter.filename, null);
- var file = GLib.File.new_for_uri(filename);
-
- exporter.export_to_file.begin(file, false, null, (obj, res) => {
- result = res;
- loop.quit();
- });
-
- loop.run();
-
- exporter.export_to_file.end(result);
-
- count++;
- }
-
- return count;
- }
-
- public static uint export_to_text_wait(GLib.List<GLib.Object> objects,
- [CCode (array_length_type = "size_t")] out uint8[] output)
throws GLib.Error {
- GLib.List<Exporter> exporters = null;
-
- foreach (var object in objects) {
- if (!Exportable.can_export(object))
- continue;
-
- /* If we've already found exporters, then add to those */
- if (exporters != null) {
- foreach (var exporter in exporters)
- exporter.add_object(object);
-
- /* Otherwise try and create new exporters for this object */
- } else {
- exporters = ((Exportable)object).create_exporters (ExporterType.TEXTUAL);
- }
- }
-
- /* Find the exporter than has the most objects */
- Exporter? chosen = null;
- uint total = 0;
- foreach (var exporter in exporters) {
- uint count = exporter.get_objects().length();
- if (count > total) {
- total = count;
- chosen = exporter;
- }
- }
-
- if (chosen != null) {
- var loop = new GLib.MainLoop (null, false);
- GLib.AsyncResult? result = null;
-
- chosen.export.begin(null, (obj, res) => {
- result = res;
- loop.quit();
- });
-
- loop.run();
-
- output = chosen.export.end(result);
- return total;
- }
-
- output = { };
- return 0;
- }
-
- public static int export_to_prompt_wait(GLib.List<GLib.Object> objects,
- Gtk.Window? parent) throws GLib.Error {
- int count = 0;
-
- var pending = new GLib.GenericSet<weak GLib.Object>(GLib.direct_hash, GLib.direct_equal);
- foreach (var object in objects)
- pending.add(object);
-
- foreach (var object in objects) {
- if (!pending.contains(object))
- continue;
-
- if (!Exportable.can_export(object)) {
- pending.remove(object);
- continue;
- }
-
- var exporters = ((Exportable)object).create_exporters(ExporterType.ANY);
- if (exporters == null)
- continue;
-
- foreach (var x in objects) {
- if (x == object)
- continue;
- if (pending.contains(x)) {
- foreach (var exporter in exporters)
- exporter.add_object(x);
- }
- }
-
- string? directory = null;
- GLib.File? file;
- Exporter? exporter;
-
- /* Now show a prompt choosing between the exporters */
- bool ret = Exportable.prompt(exporters, parent, ref directory,
- out file, out exporter);
- if (!ret)
- break;
-
- var loop = new GLib.MainLoop(null, false);
- GLib.AsyncResult? result = null;
-
- exporter.export_to_file.begin(file, true, null, (obj, res) => {
- result = res;
- loop.quit();
- });
-
- loop.run();
-
- exporter.export_to_file.end(result);
- foreach (var e in exporter.get_objects()) {
- pending.remove(e);
- count++;
- }
- }
-
- return count;
- }
-
- private static string calculate_basename(GLib.File file,
- string extension) {
- var basename = file.get_basename();
- var dot = basename.last_index_of_char('.');
- if (dot != -1)
- basename = basename.substring(0, dot);
- return "%s%s".printf(basename, extension);
- }
-
- public static bool prompt(GLib.List<Exporter> exporters,
- Gtk.Window? parent,
- ref string? directory,
- out GLib.File chosen_file,
- out Exporter chosen_exporter) {
- var chooser = new Gtk.FileChooserNative(null, parent, Gtk.FileChooserAction.SAVE,
- _("Export"), _("_Cancel"));
-
- chooser.set_local_only(false);
- chooser.set_do_overwrite_confirmation(true);
-
- if (directory != null)
- chooser.set_current_folder(directory);
-
- Gtk.FileFilter? first = null;
- var filters = new GLib.HashTable<Gtk.FileFilter, Exporter>(GLib.direct_hash,
GLib.direct_equal);
- foreach (var exporter in exporters) {
- var filter = exporter.file_filter;
- filters.replace(filter, exporter);
- chooser.add_filter(filter);
- if (first == null)
- first = filter;
- }
-
- chooser.notify.connect((obj, prop) => {
- var exporter = filters.lookup(chooser.get_filter());
- var name = exporter.filename;
- var dot = name.last_index_of_char('.');
- if (dot != -1) {
- var file = chooser.get_file();
- if (file != null) {
- var basename = calculate_basename(file, name.substring(dot));
- chooser.set_current_name(basename);
- } else {
- chooser.set_current_name(name);
- }
- }
- });
-
- chooser.set_filter(first);
-
- if (chooser.run() == Gtk.ResponseType.ACCEPT) {
- chosen_file = chooser.get_file();
- chosen_exporter = filters.lookup(chooser.get_filter());
- directory = chooser.get_current_folder();
- chooser.destroy();
- return true;
- }
-
- chosen_file = null;
- chosen_exporter = null;
- chooser.destroy();
- return false;
- }
+ public abstract bool exportable { get; }
+
+ public abstract GLib.List<Exporter> create_exporters(ExporterType type);
+
+ public static bool can_export(GLib.Object object) {
+ if (object is Exportable)
+ return ((Exportable)object).exportable;
+ return false;
+ }
+
+ public static int export_to_directory_wait(GLib.List<GLib.Object> objects,
+ string directory) throws GLib.Error {
+ var loop = new GLib.MainLoop (null, false);
+ GLib.AsyncResult? result = null;
+ int count = 0;
+
+ foreach (var object in objects) {
+ if (!Exportable.can_export(object))
+ continue;
+
+ var exporters = ((Exportable)object).create_exporters(ExporterType.ANY);
+ if (exporters == null)
+ continue;
+
+ var exporter = exporters.data;
+ string filename = GLib.Path.build_filename (directory, exporter.filename, null);
+ var file = GLib.File.new_for_uri(filename);
+
+ exporter.export_to_file.begin(file, false, null, (obj, res) => {
+ result = res;
+ loop.quit();
+ });
+
+ loop.run();
+
+ exporter.export_to_file.end(result);
+
+ count++;
+ }
+
+ return count;
+ }
+
+ public static uint export_to_text_wait(GLib.List<GLib.Object> objects,
+ [CCode (array_length_type = "size_t")] out uint8[] output) throws
GLib.Error {
+ GLib.List<Exporter> exporters = null;
+
+ foreach (var object in objects) {
+ if (!Exportable.can_export(object))
+ continue;
+
+ /* If we've already found exporters, then add to those */
+ if (exporters != null) {
+ foreach (var exporter in exporters)
+ exporter.add_object(object);
+
+ /* Otherwise try and create new exporters for this object */
+ } else {
+ exporters = ((Exportable)object).create_exporters (ExporterType.TEXTUAL);
+ }
+ }
+
+ /* Find the exporter than has the most objects */
+ Exporter? chosen = null;
+ uint total = 0;
+ foreach (var exporter in exporters) {
+ uint count = exporter.get_objects().length();
+ if (count > total) {
+ total = count;
+ chosen = exporter;
+ }
+ }
+
+ if (chosen != null) {
+ var loop = new GLib.MainLoop (null, false);
+ GLib.AsyncResult? result = null;
+
+ chosen.export.begin(null, (obj, res) => {
+ result = res;
+ loop.quit();
+ });
+
+ loop.run();
+
+ output = chosen.export.end(result);
+ return total;
+ }
+
+ output = { };
+ return 0;
+ }
+
+ public static int export_to_prompt_wait(GLib.List<GLib.Object> objects,
+ Gtk.Window? parent) throws GLib.Error {
+ int count = 0;
+
+ var pending = new GLib.GenericSet<weak GLib.Object>(GLib.direct_hash, GLib.direct_equal);
+ foreach (var object in objects)
+ pending.add(object);
+
+ foreach (var object in objects) {
+ if (!pending.contains(object))
+ continue;
+
+ if (!Exportable.can_export(object)) {
+ pending.remove(object);
+ continue;
+ }
+
+ var exporters = ((Exportable)object).create_exporters(ExporterType.ANY);
+ if (exporters == null)
+ continue;
+
+ foreach (var x in objects) {
+ if (x == object)
+ continue;
+ if (pending.contains(x)) {
+ foreach (var exporter in exporters)
+ exporter.add_object(x);
+ }
+ }
+
+ string? directory = null;
+ GLib.File? file;
+ Exporter? exporter;
+
+ /* Now show a prompt choosing between the exporters */
+ bool ret = Exportable.prompt(exporters, parent, ref directory,
+ out file, out exporter);
+ if (!ret)
+ break;
+
+ var loop = new GLib.MainLoop(null, false);
+ GLib.AsyncResult? result = null;
+
+ exporter.export_to_file.begin(file, true, null, (obj, res) => {
+ result = res;
+ loop.quit();
+ });
+
+ loop.run();
+
+ exporter.export_to_file.end(result);
+ foreach (var e in exporter.get_objects()) {
+ pending.remove(e);
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ private static string calculate_basename(GLib.File file,
+ string extension) {
+ var basename = file.get_basename();
+ var dot = basename.last_index_of_char('.');
+ if (dot != -1)
+ basename = basename.substring(0, dot);
+ return "%s%s".printf(basename, extension);
+ }
+
+ public static bool prompt(GLib.List<Exporter> exporters,
+ Gtk.Window? parent,
+ ref string? directory,
+ out GLib.File chosen_file,
+ out Exporter chosen_exporter) {
+ var chooser = new Gtk.FileChooserNative(null, parent, Gtk.FileChooserAction.SAVE,
+ _("Export"), _("_Cancel"));
+
+ if (directory != null)
+ chooser.set_current_folder(File.new_for_path(directory));
+
+ Gtk.FileFilter? first = null;
+ var filters = new GLib.HashTable<Gtk.FileFilter, Exporter>(GLib.direct_hash, GLib.direct_equal);
+ foreach (var exporter in exporters) {
+ var filter = exporter.file_filter;
+ filters.replace(filter, exporter);
+ chooser.add_filter(filter);
+ if (first == null)
+ first = filter;
+ }
+
+ chooser.notify.connect((obj, prop) => {
+ var exporter = filters.lookup(chooser.get_filter());
+ var name = exporter.filename;
+ var dot = name.last_index_of_char('.');
+ if (dot != -1) {
+ var file = chooser.get_file();
+ if (file != null) {
+ var basename = calculate_basename(file, name.substring(dot));
+ chooser.set_current_name(basename);
+ } else {
+ chooser.set_current_name(name);
+ }
+ }
+ });
+
+ chooser.set_filter(first);
+
+ // XXX check
+ int response = Gtk.ResponseType.CANCEL;
+ bool got_response = false;
+ chooser.response.connect((response) => {
+ got_response = true;
+ });
+
+ chooser.modal = true;
+ var main_context = MainContext.default();
+ while (!got_response) {
+ main_context.iteration(true);
+ }
+
+ if (response == Gtk.ResponseType.ACCEPT) {
+ chosen_file = chooser.get_file();
+ chosen_exporter = filters.lookup(chooser.get_filter());
+ directory = chooser.get_current_folder().get_path();
+ chooser.destroy();
+ return true;
+ }
+
+ chosen_file = null;
+ chosen_exporter = null;
+ chooser.destroy();
+ return false;
+ }
}
}
diff --git a/common/interaction.vala b/common/interaction.vala
index 1e5f0f3e..cd50d520 100644
--- a/common/interaction.vala
+++ b/common/interaction.vala
@@ -45,7 +45,9 @@ public class Seahorse.Interaction : GLib.TlsInteraction {
if (this.parent != null)
dialog.transient_for = this.parent;
- int response = dialog.run();
+ // XXX
+ // int response = dialog.run();
+ int response = Gtk.ResponseType.CANCEL;
if (response == Gtk.ResponseType.ACCEPT)
password.set_value_full((uint8[])gcr_secure_memory_strdup(dialog.get_text()),
diff --git a/common/meson.build b/common/meson.build
index 47a41175..cb5fd44e 100644
--- a/common/meson.build
+++ b/common/meson.build
@@ -10,9 +10,7 @@ common_sources = files(
'deleter.vala',
'exportable.vala',
'exporter.vala',
- 'icons.vala',
'interaction.vala',
- 'item-list.vala',
'lockable.vala',
'object.vala',
'passphrase-prompt.vala',
@@ -29,10 +27,9 @@ common_sources = files(
common_deps = [
glib_deps,
- gtk,
- gcr,
- gcr_ui,
- libhandy_dep,
+ gtk4_dep,
+ gcr4_dep,
+ libadwaita_dep,
config,
]
diff --git a/common/passphrase-prompt.vala b/common/passphrase-prompt.vala
index 373a9b8f..a225fe73 100644
--- a/common/passphrase-prompt.vala
+++ b/common/passphrase-prompt.vala
@@ -25,13 +25,9 @@ public const int SEAHORSE_PASS_BAD = 0x00000001;
public const int SEAHORSE_PASS_NEW = 0x01000000;
public class Seahorse.PassphrasePrompt : Gtk.Dialog {
- // gnome hig small space in pixels
- private const int HIG_SMALL = 6;
- // gnome hig large space in pixels
- private const int HIG_LARGE = 12;
- private Gtk.Entry secure_entry;
- private Gtk.Entry? confirm_entry;
+ private Gtk.PasswordEntry pass_entry;
+ private Gtk.PasswordEntry? confirm_entry;
private Gtk.CheckButton? check_option;
#if ! _DEBUG
@@ -45,42 +41,39 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
icon_name: "dialog-password-symbolic"
);
- Gtk.Box wvbox = new Gtk.Box(Gtk.Orientation.VERTICAL, HIG_LARGE * 2);
- get_content_area().add(wvbox);
- wvbox.set_border_width(HIG_LARGE);
+ Gtk.Box wvbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 24);
+ set_child(wvbox);
- Gtk.Box chbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, HIG_LARGE);
- wvbox.pack_start (chbox, false, false);
+ Gtk.Box chbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 12);
+ wvbox.append(chbox);
// The image
- Gtk.Image img = new Gtk.Image.from_icon_name("dialog-password-symbolic", Gtk.IconSize.DIALOG);
- img.set_alignment(0.0f, 0.0f);
- chbox.pack_start(img, false, false);
+ Gtk.Image img = new Gtk.Image.from_icon_name("dialog-password-symbolic");
+ chbox.append(img);
- Gtk.Box box = new Gtk.Box(Gtk.Orientation.VERTICAL, HIG_SMALL);
- chbox.pack_start (box);
+ Gtk.Box box = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
+ chbox.append(box);
// The description text
if (description != null) {
Gtk.Label desc_label = new Gtk.Label(utf8_validate (description));
- desc_label.set_alignment(0.0f, 0.5f);
- desc_label.set_line_wrap(true);
- box.pack_start(desc_label, true, false);
+ desc_label.xalign = 0;
+ desc_label.wrap = true;
+ box.append(desc_label);
}
Gtk.Grid grid = new Gtk.Grid();
- grid.set_row_spacing(HIG_SMALL);
- grid.set_column_spacing(HIG_LARGE);
- box.pack_start(grid, false, false);
+ grid.set_row_spacing(6);
+ grid.set_column_spacing(12);
+ box.append(grid);
// The first entry (if we have one)
if (confirm) {
Gtk.Label prompt_label = new Gtk.Label(utf8_validate (prompt));
- prompt_label.set_alignment(0.0f, 0.5f);
+ prompt_label.xalign = 0;
grid.attach(prompt_label, 0, 0);
- this.confirm_entry = new Gtk.Entry.with_buffer(new Gcr.SecureEntryBuffer());
- this.confirm_entry.set_visibility(false);
+ this.confirm_entry = new Gtk.PasswordEntry();
this.confirm_entry.set_size_request(200, -1);
this.confirm_entry.activate.connect(confirm_callback);
this.confirm_entry.changed.connect(entry_changed);
@@ -90,21 +83,20 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
// The second and main entry
Gtk.Label confirm_label = new Gtk.Label(utf8_validate (confirm? _("Confirm:") : prompt));
- confirm_label.set_alignment(0.0f, 0.5f);
+ confirm_label.xalign = 0;
grid.attach(confirm_label, 0, 1);
- this.secure_entry = new Gtk.Entry.with_buffer(new Gcr.SecureEntryBuffer());
- this.secure_entry.set_size_request(200, -1);
- this.secure_entry.set_visibility(false);
- this.secure_entry.activate.connect(() => {
+ this.pass_entry = new Gtk.PasswordEntry();
+ this.pass_entry.set_size_request(200, -1);
+ this.pass_entry.activate.connect(() => {
if (get_widget_for_response(Gtk.ResponseType.ACCEPT).sensitive)
response(Gtk.ResponseType.ACCEPT);
});
- grid.attach(secure_entry, 1, 1);
+ grid.attach(pass_entry, 1, 1);
if (confirm)
- this.secure_entry.changed.connect(entry_changed);
+ this.pass_entry.changed.connect(entry_changed);
else
- this.secure_entry.grab_focus();
+ this.pass_entry.grab_focus();
// The checkbox
if (check != null) {
@@ -112,28 +104,20 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
grid.attach(this.check_option, 1, 2);
}
- grid.show_all();
-
Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(_("_Cancel"));
add_action_widget(cancel_button, Gtk.ResponseType.REJECT);
- cancel_button.set_can_default(true);
Gtk.Button ok_button = new Gtk.Button.with_mnemonic(_("_OK"));
add_action_widget(ok_button, Gtk.ResponseType.ACCEPT);
- ok_button.set_can_default(true);
- ok_button.grab_default();
+ set_default_widget(ok_button);
- // Signals
- this.map_event.connect(grab_keyboard);
- this.unmap_event.connect(ungrab_keyboard);
- this.window_state_event.connect(window_state_changed);
- this.key_press_event.connect(key_press);
+ // Signals XXX
+ // this.map_event.connect(grab_keyboard);
+ // this.unmap_event.connect(ungrab_keyboard);
+ // this.window_state_event.connect(window_state_changed);
+ // this.key_press_event.connect(key_press);
- set_position(Gtk.WindowPosition.CENTER);
set_resizable(false);
- set_keep_above(true);
- show_all();
- get_window().focus(Gdk.CURRENT_TIME);
if (confirm)
entry_changed (null);
@@ -146,7 +130,7 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
}
public string get_text() {
- return this.secure_entry.text;
+ return this.pass_entry.text;
}
public bool checked() {
@@ -174,7 +158,9 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
return result;
}
- private bool key_press (Gtk.Widget widget, Gdk.EventKey event) {
+ //XXX
+#if 0
+ private bool key_press(Gtk.EventControllerKey controller, uint keyval, uint keycode, Gdk.ModifierType
state) {
// Close the dialog when hitting "Esc".
if (event.keyval == Gdk.Key.Escape) {
response(Gtk.ResponseType.REJECT);
@@ -213,22 +199,12 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
Gdk.Seat seat = display.get_default_seat();
seat.ungrab();
- }
+ }
this.keyboard_grabbed = false;
#endif
return false;
}
- /* When enter is pressed in the confirm entry, move */
- private void confirm_callback(Gtk.Widget widget) {
- this.secure_entry.grab_focus();
- }
-
- private void entry_changed (Gtk.Editable? editable) {
- set_response_sensitive(Gtk.ResponseType.ACCEPT,
- this.secure_entry.text == this.confirm_entry.text);
- }
-
private bool window_state_changed (Gtk.Widget win, Gdk.EventWindowState event) {
Gdk.WindowState state = win.get_window().get_state();
@@ -242,5 +218,16 @@ public class Seahorse.PassphrasePrompt : Gtk.Dialog {
return false;
}
+#endif
+
+ /* When enter is pressed in the confirm entry, move */
+ private void confirm_callback(Gtk.Widget widget) {
+ this.pass_entry.grab_focus();
+ }
+
+ private void entry_changed (Gtk.Editable? editable) {
+ set_response_sensitive(Gtk.ResponseType.ACCEPT,
+ this.pass_entry.text == this.confirm_entry.text);
+ }
}
diff --git a/common/place.vala b/common/place.vala
index 3beee304..95066da0 100644
--- a/common/place.vala
+++ b/common/place.vala
@@ -22,7 +22,7 @@
* A SeahorsePlace is a collection of objects (passwords/keys/certificates/...).
* An example of this is a keyring.
*/
-public interface Seahorse.Place : Gcr.Collection {
+public interface Seahorse.Place : GLib.ListModel {
/**
* We generally divide a SeahorsePlace in some high level categories.
@@ -51,16 +51,8 @@ public interface Seahorse.Place : Gcr.Collection {
public abstract string label { owned get; set; }
public abstract string description { owned get; }
public abstract string uri { owned get; }
- public abstract Icon icon { owned get; }
public abstract Category category { owned get; }
- /**
- * In some cases, we do not want to show the Place in the sidebar
- * if it's empty (for example p11-kit's System Trust), while we do
- * want this for others (like libsecret keyrings).
- */
- public abstract bool show_if_empty { get; }
-
/**
* Returns the {@link GLib.Action}s that are defined for this Place,
* or null if none.
diff --git a/common/prefs-keyservers.vala b/common/prefs-keyservers.vala
index adc1ed4d..14909d37 100644
--- a/common/prefs-keyservers.vala
+++ b/common/prefs-keyservers.vala
@@ -19,7 +19,7 @@
*/
[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-prefs-keyservers.ui")]
-public class Seahorse.PrefsKeyservers : Hdy.PreferencesPage {
+public class Seahorse.PrefsKeyservers : Adw.PreferencesPage {
[GtkChild]
public unowned Gtk.Grid keyserver_tab;
@@ -42,8 +42,7 @@ public class Seahorse.PrefsKeyservers : Hdy.PreferencesPage {
KeyserverControl skc = new KeyserverControl("server-publish-to",
_("None: Don’t publish keys"));
- this.keyserver_publish.add(skc);
- this.keyserver_publish.show_all();
+ this.keyserver_publish.append(skc);
this.keyserver_publish_to_label.set_mnemonic_widget(skc);
@@ -63,35 +62,32 @@ public class Seahorse.PrefsKeyservers : Hdy.PreferencesPage {
this.server = server;
var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 2);
- box.margin = 6;
- add(box);
+ // box.margin = 6; XXX
+ set_child(box);
this.label = new Gtk.Label(server.uri);
- box.pack_start(this.label, false);
+ box.append(this.label);
this.entry = new Gtk.Entry();
- this.entry.set_no_show_all(true);
this.entry.hide();
this.entry.activate.connect(on_entry_activated);
- box.pack_start(this.entry);
+ box.append(this.entry);
var remove_button = new Gtk.Button.from_icon_name("list-remove-symbolic");
remove_button.get_style_context().add_class("flat");
remove_button.clicked.connect(on_remove_button_clicked);
- box.pack_end(remove_button, false);
+ box.append(remove_button);
var edit_button = new Gtk.Button.from_icon_name("document-edit-symbolic");
edit_button.get_style_context().add_class("flat");
edit_button.clicked.connect(on_edit_button_clicked);
- box.pack_end(edit_button, false);
-
- show_all();
+ box.append(edit_button);
}
private void on_edit_button_clicked(Gtk.Button edit_button) {
this.label.hide();
this.entry.set_text(this.label.get_text());
- this.entry.show_now();
+ this.entry.show();
this.entry.grab_focus();
}
@@ -124,15 +120,17 @@ public class Seahorse.PrefsKeyservers : Hdy.PreferencesPage {
[GtkCallback]
private void on_add_button_clicked(Gtk.Button button) {
- AddKeyserverDialog dialog = new AddKeyserverDialog(get_toplevel() as Gtk.Window);
-
- if (dialog.run() == Gtk.ResponseType.OK) {
- string? result = dialog.calculate_keyserver_uri();
+ AddKeyserverDialog dialog = new AddKeyserverDialog(get_root() as Gtk.Window);
- if (result != null)
- Pgp.Backend.get().add_remote(result, true);
- }
+ dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.OK) {
+ string? result = dialog.calculate_keyserver_uri();
+ if (result != null)
+ Pgp.Backend.get().add_remote(result, true);
+ }
- dialog.destroy();
+ dialog.destroy();
+ });
+ dialog.present();
}
}
diff --git a/common/prefs.vala b/common/prefs.vala
index cd0c8e74..caef69d0 100644
--- a/common/prefs.vala
+++ b/common/prefs.vala
@@ -18,7 +18,7 @@
* <http://www.gnu.org/licenses/>.
*/
-public class Seahorse.Prefs : Hdy.PreferencesWindow {
+public class Seahorse.Prefs : Adw.PreferencesWindow {
/**
* Create a new preferences window.
diff --git a/common/seahorse-prefs-keyservers.ui b/common/seahorse-prefs-keyservers.ui
index 419ab9cf..a103c738 100644
--- a/common/seahorse-prefs-keyservers.ui
+++ b/common/seahorse-prefs-keyservers.ui
@@ -1,11 +1,11 @@
<?xml version="1.0"?>
<interface>
<requires lib="gtk+" version="3.24"/>
- <template class="SeahorsePrefsKeyservers" parent="HdyPreferencesPage">
+ <template class="SeahorsePrefsKeyservers" parent="AdwPreferencesPage">
<property name="visible">True</property>
<property name="title" translatable="yes">Keyservers</property>
<child>
- <object class="HdyPreferencesGroup">
+ <object class="AdwPreferencesGroup">
<property name="visible">True</property>
<property name="title" translatable="yes">Keyservers</property>
<child>
@@ -46,7 +46,7 @@
</object>
</child>
<child>
- <object class="HdyPreferencesGroup">
+ <object class="AdwPreferencesGroup">
<property name="visible">True</property>
<property name="title" translatable="yes">Key Synchronization</property>
<child>
diff --git a/common/util.vala b/common/util.vala
index 06b78bec..ad033412 100644
--- a/common/util.vala
+++ b/common/util.vala
@@ -21,32 +21,31 @@
namespace Seahorse.Util {
- public void show_error (Gtk.Widget? parent,
- string? heading,
- string? message) {
- Gtk.Window? window = null;
+ public void show_error (Gtk.Widget? parent,
+ string? heading,
+ string? message) {
+ Gtk.Window? window = null;
- if (message == null)
- message = "";
+ if (message == null)
+ message = "";
- if (parent != null) {
- if (!(parent is Gtk.Window))
- parent = parent.get_toplevel();
- if (parent is Gtk.Window)
- window = (Gtk.Window)parent;
- }
+ if (parent != null && !(parent is Gtk.Window)) {
+ parent = parent.get_root() as Gtk.Window;
+ }
- var dialog = new Gtk.MessageDialog(window, Gtk.DialogFlags.MODAL,
- Gtk.MessageType.ERROR,
- Gtk.ButtonsType.CLOSE, "");
- if (heading == null)
- dialog.set("text", message);
- else
- dialog.set("text", heading, "secondary-text", message);
+ var dialog = new Gtk.MessageDialog(window, Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.ERROR,
+ Gtk.ButtonsType.CLOSE, "");
+ if (heading == null)
+ dialog.set("text", message);
+ else
+ dialog.set("text", heading, "secondary-text", message);
- dialog.run();
- dialog.destroy();
- }
+ dialog.response.connect(() => {
+ dialog.destroy();
+ });
+ dialog.show();
+ }
public void toggle_action (GLib.SimpleAction action,
GLib.Variant? variant,
diff --git a/common/viewable.vala b/common/viewable.vala
index da5a79fa..73917416 100644
--- a/common/viewable.vala
+++ b/common/viewable.vala
@@ -44,8 +44,9 @@ public interface Viewable : GLib.Object {
return false;
object.set_data("viewable-window", window);
- window.destroy.connect(() => {
+ window.close_request.connect(() => {
object.set_data_full("viewable-window", null, null);
+ return false;
});
}
diff --git a/gkr/gkr-backend.vala b/gkr/gkr-backend.vala
index 6f9b3fa5..8c43b5bb 100644
--- a/gkr/gkr-backend.vala
+++ b/gkr/gkr-backend.vala
@@ -17,170 +17,160 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-namespace Seahorse {
-namespace Gkr {
+namespace Seahorse.Gkr {
private class MyService : Secret.Service {
- public override GLib.Type get_collection_gtype() {
- return typeof(Keyring);
- }
+ public override GLib.Type get_collection_gtype() {
+ return typeof(Keyring);
+ }
- public override GLib.Type get_item_gtype() {
- return typeof(Item);
- }
+ public override GLib.Type get_item_gtype() {
+ return typeof(Item);
+ }
}
-public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
- public string name {
- get { return NAME; }
- }
+public class Backend: GLib.Object, GLib.ListModel, Seahorse.Backend {
- public string label {
- get { return _("Passwords"); }
- }
+ public string name {
+ get { return NAME; }
+ }
- public string description {
- get { return _("Stored personal passwords, credentials and secrets"); }
- }
+ public string label {
+ get { return _("Passwords"); }
+ }
+
+ public string description {
+ get { return _("Stored personal passwords, credentials and secrets"); }
+ }
public ActionGroup actions {
owned get { return this._actions; }
}
- public GLib.HashTable<string, string> aliases {
- get { return this._aliases; }
- }
-
- private bool _loaded;
- public bool loaded {
- get { return this._loaded; }
- }
-
- public Secret.Service? service {
- get { return this._service; }
- }
-
- private static Backend? _instance = null;
- private Secret.Service _service;
- private GLib.HashTable<string, Keyring> _keyrings;
- private GLib.HashTable<string, string> _aliases;
- private ActionGroup _actions;
-
- construct {
- return_val_if_fail(_instance == null, null);
- Backend._instance = this;
-
- this._actions = BackendActions.instance(this);
- this._keyrings = new GLib.HashTable<string, Keyring>(GLib.str_hash, GLib.str_equal);
- this._aliases = new GLib.HashTable<string, string>(GLib.str_hash, GLib.str_equal);
-
- Secret.Service.open.begin(typeof(MyService), null,
- Secret.ServiceFlags.OPEN_SESSION, null, (obj, res) => {
- try {
- this._service = Secret.Service.open.end(res);
- this._service.notify["collections"].connect((obj, pspec) => {
- refresh_collections();
- });
- this._service.load_collections.begin(null, (obj, res) => {
- try {
- this._service.load_collections.end(res);
- refresh_collections();
- } catch (GLib.Error e) {
- warning("couldn't load all secret collections: %s",
e.message);
- }
- });
- refresh_aliases();
- } catch (GLib.Error err) {
- GLib.warning("couldn't connect to secret service: %s", err.message);
- }
- notify_property("service");
- });
- }
-
- public override void dispose() {
- this._aliases.remove_all();
- this._keyrings.remove_all();
- base.dispose();
- }
-
- public void refresh_collections() {
- var seen = new GLib.GenericSet<string>(GLib.str_hash, GLib.str_equal);
- var keyrings = this._service.get_collections();
-
- string object_path;
- foreach (var keyring in keyrings) {
- object_path = keyring.get_object_path();
-
- /* Don't list the session keyring */
- if (this._aliases.lookup("session") == object_path)
- continue;
-
- var uri = "secret-service://%s".printf(object_path);
- seen.add(uri);
- if (this._keyrings.lookup(uri) == null) {
- this._keyrings.insert(uri, (Keyring)keyring);
- emit_added(keyring);
- }
- }
-
- /* Remove any that we didn't find */
- var iter = GLib.HashTableIter<string, Keyring>(this._keyrings);
- string uri;
- while (iter.next(out uri, null)) {
- if (!seen.contains(uri)) {
- var keyring = this._keyrings.lookup(uri);
- iter.remove();
- emit_removed(keyring);
- }
- }
-
- if (!_loaded) {
- _loaded = true;
- notify_property("loaded");
- }
- }
-
- public uint get_length() {
- return this._keyrings.size();
- }
-
- public GLib.List<weak GLib.Object> get_objects() {
- return get_keyrings();
- }
-
- public bool contains(GLib.Object object) {
- var keyring = object as Gkr.Keyring;
- if (keyring == null)
- return false;
-
- return this._keyrings.lookup(keyring.uri) == keyring;
+ public GLib.HashTable<string, string> aliases {
+ get { return this._aliases; }
+ }
+
+ private bool _loaded;
+ public bool loaded {
+ get { return this._loaded; }
+ }
+
+ public Secret.Service? service {
+ get { return this._service; }
+ }
+
+ private static Backend? _instance = null;
+ private Secret.Service _service;
+ private GenericArray<Gkr.Keyring> keyrings;
+ private GLib.HashTable<string, string> _aliases;
+ private ActionGroup _actions;
+
+ construct {
+ return_val_if_fail(_instance == null, null);
+ Backend._instance = this;
+
+ this._actions = BackendActions.instance(this);
+ this.keyrings = new GenericArray<Keyring>();
+ this._aliases = new GLib.HashTable<string, string>(GLib.str_hash, GLib.str_equal);
+
+ Secret.Service.open.begin(typeof(MyService), null,
+ Secret.ServiceFlags.OPEN_SESSION, null, (obj, res) => {
+ try {
+ this._service = Secret.Service.open.end(res);
+ this._service.notify["collections"].connect((obj, pspec) => {
+ refresh_collections();
+ });
+ this._service.load_collections.begin(null, (obj, res) => {
+ try {
+ this._service.load_collections.end(res);
+ refresh_collections();
+ } catch (GLib.Error e) {
+ warning("couldn't load all secret collections: %s", e.message);
+ }
+ });
+ refresh_aliases();
+ } catch (GLib.Error err) {
+ GLib.warning("couldn't connect to secret service: %s", err.message);
+ }
+ notify_property("service");
+ });
+ }
+
+ public Seahorse.Place? lookup_place(string uri) {
+ for (uint i = 0; i < this.keyrings.length; i++) {
+ if (this.keyrings[i].uri == uri)
+ return this.keyrings[i];
+ }
+ return null;
+ }
+
+ public void refresh_collections() {
+ var seen = new GLib.GenericSet<string>(GLib.str_hash, GLib.str_equal);
+ var keyrings = this._service.get_collections();
+
+ string object_path;
+ foreach (var keyring in keyrings) {
+ object_path = keyring.get_object_path();
+
+ /* Don't list the session keyring */
+ if (this._aliases.lookup("session") == object_path)
+ continue;
+
+ var uri = "secret-service://%s".printf(object_path);
+ seen.add(uri);
+ if (lookup_place(uri) == null) {
+ this.keyrings.add((Keyring) keyring);
+ items_changed(this.keyrings.length - 1, 0, 1);
+ }
+ }
+
+ /* Remove any that we didn't find */
+ for (uint i = 0; i < this.keyrings.length; i++) {
+ if (!seen.contains(this.keyrings[i].uri)) {
+ this.keyrings.remove_index(i);
+ items_changed(i, 1, 0);
+ i--;
+ }
+ }
+
+ if (!_loaded) {
+ _loaded = true;
+ notify_property("loaded");
+ }
+ }
+
+ public GLib.Type get_item_type() {
+ return typeof(Gkr.Keyring);
}
- public Place? lookup_place(string uri) {
- return this._keyrings.lookup(uri);
- }
+ public uint get_n_items() {
+ return this.keyrings.length;
+ }
- public static void initialize() {
- return_if_fail(Backend._instance == null);
- (new Backend()).register();
- return_if_fail(Backend._instance != null);
- }
+ public GLib.Object? get_item(uint position) {
+ if (position >= this.keyrings.length)
+ return null;
+ return this.keyrings[position];
+ }
- public static Backend instance() {
- return_val_if_fail(Backend._instance != null, null);
- return Backend._instance;
- }
+ public static void initialize() {
+ return_if_fail(Backend._instance == null);
+ (new Backend()).register();
+ return_if_fail(Backend._instance != null);
+ }
- public GLib.List<unowned Keyring> get_keyrings() {
- return this._keyrings.get_values();
- }
+ public static Backend instance() {
+ return_val_if_fail(Backend._instance != null, null);
+ return Backend._instance;
+ }
- private async void read_alias(string name) {
- if (this._service == null)
- return;
+ private async void read_alias(string name) {
+ if (this._service == null)
+ return;
- try {
- var object_path = this._service.read_alias_dbus_path_sync(name);
+ try {
+ var object_path = this._service.read_alias_dbus_path_sync(name);
if (object_path != null) {
this._aliases[name] = object_path;
notify_property("aliases");
@@ -188,29 +178,30 @@ public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
} catch (GLib.Error err) {
warning("Couldn't read secret service alias %s: %s", name, err.message);
}
- }
-
- private void refresh_aliases() {
- read_alias.begin ("default");
- read_alias.begin ("session");
- read_alias.begin ("login");
- }
-
- public void refresh() {
- refresh_aliases();
- refresh_collections();
- }
- public bool has_alias(string alias,
- Keyring keyring) {
- string object_path = keyring.get_object_path();
- return this._aliases.lookup(alias) == object_path;
- }
+ }
+
+ private void refresh_aliases() {
+ read_alias.begin ("default");
+ read_alias.begin ("session");
+ read_alias.begin ("login");
+ }
+
+ public void refresh() {
+ refresh_aliases();
+ refresh_collections();
+ }
+
+ public bool has_alias(string alias,
+ Keyring keyring) {
+ string object_path = keyring.get_object_path();
+ return this._aliases.lookup(alias) == object_path;
+ }
}
public class BackendActions : Seahorse.ActionGroup {
- public Backend backend { construct; get; }
- private static WeakRef _instance;
- private bool _initialized;
+ public Backend backend { construct; get; }
+ private static WeakRef _instance;
+ private bool _initialized;
private const ActionEntry[] BACKEND_ACTIONS = {
{ "keyring-new", on_new_keyring },
@@ -218,23 +209,23 @@ public class BackendActions : Seahorse.ActionGroup {
{ "copy-secret", on_copy_secret },
};
- construct {
- this._initialized = false;
+ construct {
+ this._initialized = false;
- this.backend.notify.connect_after((pspec) => {
- if (pspec.name == "service")
- return;
- if (this._initialized)
- return;
- if (this.backend.service == null)
- return;
+ this.backend.notify.connect_after((pspec) => {
+ if (pspec.name == "service")
+ return;
+ if (this._initialized)
+ return;
+ if (this.backend.service == null)
+ return;
- this._initialized = true;
+ this._initialized = true;
add_action_entries(BACKEND_ACTIONS, this);
- });
+ });
- this.backend.notify_property("service");
- }
+ this.backend.notify_property("service");
+ }
private BackendActions(Backend backend) {
GLib.Object(
@@ -245,20 +236,22 @@ public class BackendActions : Seahorse.ActionGroup {
private void on_new_keyring(SimpleAction action, Variant? param) {
var dialog = new KeyringAdd(this.catalog);
-
- int response = dialog.run();
- if (response == Gtk.ResponseType.ACCEPT)
- this.catalog.activate_action("focus-place", "secret-service");
- dialog.destroy();
+ dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.ACCEPT)
+ this.catalog.activate_action("focus-place", "secret-service");
+ dialog.destroy();
+ });
+ dialog.show();
}
private void on_new_item(SimpleAction action, Variant? param) {
var dialog = new ItemAdd(this.catalog);
-
- int response = dialog.run();
- if (response == Gtk.ResponseType.ACCEPT)
- this.catalog.activate_action("focus-place", "secret-service");
- dialog.destroy();
+ dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.ACCEPT)
+ this.catalog.activate_action("focus-place", "secret-service");
+ dialog.destroy();
+ });
+ dialog.show();
}
private void on_copy_secret(SimpleAction action, Variant? param) {
@@ -271,7 +264,7 @@ public class BackendActions : Seahorse.ActionGroup {
var selected_item = selected.data as Gkr.Item;
return_if_fail (selected_item != null);
- var clipboard = Gtk.Clipboard.get_default(this.catalog.get_display());
+ var clipboard = this.catalog.get_clipboard();
selected_item.copy_secret_to_clipboard.begin(clipboard, (obj, res) => {
try {
selected_item.copy_secret_to_clipboard.end(res);
@@ -292,15 +285,14 @@ public class BackendActions : Seahorse.ActionGroup {
((SimpleAction) lookup_action("copy-secret")).set_enabled(can_copy_secret);
}
- public static ActionGroup instance(Backend backend) {
- BackendActions? actions = (BackendActions?)_instance.get();
- if (actions != null)
- return actions;
- actions = new BackendActions(backend);
- _instance.set(actions);
- return actions;
- }
+ public static ActionGroup instance(Backend backend) {
+ BackendActions? actions = (BackendActions?)_instance.get();
+ if (actions != null)
+ return actions;
+ actions = new BackendActions(backend);
+ _instance.set(actions);
+ return actions;
+ }
}
}
-}
diff --git a/gkr/gkr-dialogs.vala b/gkr/gkr-dialogs.vala
index d70f41b0..d202846b 100644
--- a/gkr/gkr-dialogs.vala
+++ b/gkr/gkr-dialogs.vala
@@ -17,67 +17,56 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-namespace Seahorse {
-namespace Gkr {
+namespace Seahorse.Gkr.Dialog {
-public class Dialog {
+private void update_wait_cursor(Gtk.Widget widget) {
+ GLib.Cancellable? cancellable = widget.get_data("gkr-request");
- private static void update_wait_cursor(Gtk.Widget widget) {
- GLib.Cancellable? cancellable = widget.get_data("gkr-request");
+ // No request active?
+ if (cancellable == null) {
+ widget.set_cursor(null);
+ return;
+ }
- /* No request active? */
- if (cancellable == null) {
- widget.get_window().set_cursor(null);
- return;
- }
+ // Get the wait cursor. Create a new one and cache it on the widget
+ Gdk.Cursor? cursor = widget.get_data("wait-cursor");
+ if (cursor == null) {
+ cursor = new Gdk.Cursor.from_name ("wait", null);
+ widget.set_data("wait-cursor", cursor);
+ }
- /*
- * Get the wait cursor. Create a new one and cache it on the widget
- * if first time.
- */
- Gdk.Cursor? cursor = widget.get_data("wait-cursor");
- if (cursor == null) {
- cursor = new Gdk.Cursor.from_name (Gdk.Display.get_default(), "wait");
- widget.set_data("wait-cursor", cursor);
- }
-
- /* Indicate that we're loading stuff */
- widget.get_window().set_cursor(cursor);
- }
-
- public static GLib.Cancellable begin_request(Gtk.Widget dialog) {
- /* Cancel any old operation going on */
- complete_request (dialog, true);
+ // Indicate that we're loading stuff
+ widget.set_cursor(cursor);
+}
- /*
- * Start the operation and tie it to the widget so that it will get
- * cancelled if the widget is destroyed before the operation is complete
- */
- var cancellable = new GLib.Cancellable ();
- dialog.set_data_full ("gkr-request", cancellable.ref(), (data) => {
- GLib.Cancellable? c = (GLib.Cancellable?)data;
- c.cancel();
- c.unref();
- });
+public GLib.Cancellable begin_request(Gtk.Widget dialog) {
+ // Cancel any old operation going on
+ complete_request (dialog, true);
- if (dialog.get_realized())
- update_wait_cursor (dialog);
- else
- dialog.realize.connect(update_wait_cursor);
+ // Start the operation and tie it to the widget so that it will get
+ // cancelled if the widget is destroyed before the operation is complete
+ var cancellable = new GLib.Cancellable ();
+ dialog.set_data_full ("gkr-request", cancellable.ref(), (data) => {
+ GLib.Cancellable? c = (GLib.Cancellable?)data;
+ c.cancel();
+ c.unref();
+ });
- dialog.set_sensitive(false);
- return cancellable;
- }
+ if (dialog.get_realized())
+ update_wait_cursor (dialog);
+ else
+ dialog.realize.connect(update_wait_cursor);
- public static void complete_request(Gtk.Widget dialog, bool cancel) {
- GLib.Cancellable? cancellable = dialog.steal_data ("gkr-request");
- if (cancellable != null && cancel)
- cancellable.cancel();
- if (dialog.get_realized())
- update_wait_cursor (dialog);
- dialog.set_sensitive(true);
- }
+ dialog.set_sensitive(false);
+ return cancellable;
}
+public void complete_request(Gtk.Widget dialog, bool cancel) {
+ GLib.Cancellable? cancellable = dialog.steal_data ("gkr-request");
+ if (cancellable != null && cancel)
+ cancellable.cancel();
+ if (dialog.get_realized())
+ update_wait_cursor (dialog);
+ dialog.set_sensitive(true);
}
}
diff --git a/gkr/gkr-item-add.vala b/gkr/gkr-item-add.vala
index aad437c9..ee179cd6 100644
--- a/gkr/gkr-item-add.vala
+++ b/gkr/gkr-item-add.vala
@@ -22,10 +22,9 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
[GtkChild]
private unowned Gtk.ComboBox item_keyring_combo;
[GtkChild]
- private unowned Gtk.Container password_area;
- private Gtk.Entry password_entry;
+ private unowned Gtk.PasswordEntry password_entry;
[GtkChild]
- private unowned Gtk.Entry item_entry;
+ private unowned Adw.EntryRow description_row;
[GtkChild]
private unowned Gtk.LevelBar password_strength_bar;
[GtkChild]
@@ -42,7 +41,9 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
this.item_keyring_combo.pack_start(cell, true);
this.item_keyring_combo.add_attribute(cell, "text", 0);
- foreach (var keyring in Backend.instance().get_keyrings()) {
+ var backend = Backend.instance();
+ for (uint i = 0; i < backend.get_n_items(); i++) {
+ var keyring = (Gkr.Keyring) backend.get_item(i);
Gtk.TreeIter iter;
store.append(out iter);
store.set(iter, 0, keyring.label,
@@ -51,13 +52,10 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
this.item_keyring_combo.set_active_iter(iter);
}
+ this.response.connect(on_response);
set_response_sensitive(Gtk.ResponseType.ACCEPT, false);
- this.password_entry = new PasswordEntry();
- this.password_entry.visibility = false;
this.password_entry.changed.connect(on_password_entry_changed);
- this.password_area.add(this.password_entry);
- this.password_entry.show();
}
public ItemAdd(Gtk.Window? parent) {
@@ -68,8 +66,8 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
}
[GtkCallback]
- private void on_add_item_entry_changed (Gtk.Editable entry) {
- set_response_sensitive(Gtk.ResponseType.ACCEPT, this.item_entry.text != "");
+ private void on_description_row_changed (Gtk.Editable editable) {
+ set_response_sensitive(Gtk.ResponseType.ACCEPT, editable.text != "");
}
private void on_password_entry_changed (Gtk.Editable entry) {
@@ -87,7 +85,7 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
this.password_strength_bar.value = ((score / 25) + 1).clamp(1, 5);
}
- public override void response(int resp) {
+ private void on_response(int resp) {
if (resp != Gtk.ResponseType.ACCEPT)
return;
@@ -101,13 +99,11 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
var keyring = (Keyring) collection;
var cancellable = new Cancellable();
var interaction = new Interaction(this);
- var item_buffer = this.item_entry.buffer;
- var secret_buffer = this.password_entry.buffer;
keyring.unlock.begin(interaction, cancellable, (obj, res) => {
try {
if (keyring.unlock.end(res)) {
- create_secret(item_buffer, secret_buffer, collection);
+ create_secret(this.description_row.text, this.password_entry.text, collection);
}
} catch (Error e) {
Util.show_error(this, _("Couldn’t unlock"), e.message);
@@ -115,10 +111,10 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
});
}
- private void create_secret(Gtk.EntryBuffer item_buffer,
- Gtk.EntryBuffer secret_buffer,
+ private void create_secret(string item,
+ string secret,
Secret.Collection collection) {
- var secret = new Secret.Value(secret_buffer.text, -1, "text/plain");
+ var secret_val = new Secret.Value(secret, -1, "text/plain");
var cancellable = Dialog.begin_request(this);
var attributes = new HashTable<string, string>(GLib.str_hash, GLib.str_equal);
@@ -126,7 +122,7 @@ public class Seahorse.Gkr.ItemAdd : Gtk.Dialog {
var schema = new Secret.Schema("org.gnome.keyring.Note", Secret.SchemaFlags.NONE);
Secret.Item.create.begin(collection, schema, attributes,
- item_buffer.text, secret, Secret.ItemCreateFlags.NONE,
+ item, secret_val, Secret.ItemCreateFlags.NONE,
cancellable, (obj, res) => {
try {
/* Clear the operation without cancelling it since it is complete */
diff --git a/gkr/gkr-item-properties.vala b/gkr/gkr-item-properties.vala
index 08578270..85b83c59 100644
--- a/gkr/gkr-item-properties.vala
+++ b/gkr/gkr-item-properties.vala
@@ -23,27 +23,29 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
public Item item { construct; get; }
[GtkChild]
- private unowned Gtk.Entry description_field;
+ private unowned Adw.WindowTitle window_title;
+ [GtkChild]
+ private unowned Adw.EntryRow description_field;
private bool description_has_changed;
[GtkChild]
private unowned Gtk.Label use_field;
[GtkChild]
private unowned Gtk.Label type_field;
[GtkChild]
- private unowned Hdy.PreferencesGroup details_group;
+ private unowned Adw.PreferencesGroup details_group;
[GtkChild]
private unowned Gtk.ListBox details_box;
[GtkChild]
- private unowned Hdy.ActionRow server_row;
+ private unowned Adw.ActionRow server_row;
[GtkChild]
private unowned Gtk.Label server_field;
[GtkChild]
- private unowned Hdy.ActionRow login_row;
+ private unowned Adw.ActionRow login_row;
[GtkChild]
private unowned Gtk.Label login_field;
[GtkChild]
- private unowned Gtk.Box password_box_area;
- private PasswordEntry password_entry;
+ private unowned Gtk.PasswordEntry password_entry;
+ private string original_password = "";
construct {
// Setup the label properly
@@ -54,8 +56,7 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
});
/* Window title */
- var headerbar = (Gtk.HeaderBar) this.get_header_bar();
- this.item.bind_property("label", headerbar, "subtitle",
+ this.item.bind_property("label", this.window_title, "subtitle",
GLib.BindingFlags.SYNC_CREATE);
/* Update as appropriate */
@@ -77,9 +78,7 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
}
});
- // Create the password entry
- this.password_entry = new PasswordEntry();
- this.password_box_area.pack_start(this.password_entry, true, true, 0);
+ // fill the password entry
fetch_password();
// Sensitivity of the password entry
@@ -97,7 +96,8 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
public override void response(int response) {
// In case of changes: ask for confirmation
- if (!this.password_entry.has_changed && !this.description_has_changed) {
+ if (this.password_entry.text == this.original_password
+ && !this.description_has_changed) {
destroy();
return;
}
@@ -106,7 +106,7 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
Gtk.ButtonsType.OK_CANCEL, _("Save changes for this item?"));
dialog.response.connect((resp) => {
if (resp == Gtk.ResponseType.OK) {
- if (this.password_entry.has_changed)
+ if (this.password_entry.text != this.original_password)
save_password.begin();
if (this.description_has_changed)
save_description.begin();
@@ -114,7 +114,7 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
dialog.destroy();
});
- dialog.run();
+ dialog.show();
}
private void update_use() {
@@ -189,7 +189,7 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
any_details = true;
- var row = new Hdy.ActionRow();
+ var row = new Adw.ActionRow();
row.title = key;
row.can_focus = false;
@@ -199,9 +199,8 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
label.wrap = true;
label.wrap_mode = Pango.WrapMode.WORD_CHAR;
label.max_width_chars = 32;
- row.add(label);
+ row.add_suffix(label);
- row.show_all();
this.details_box.insert(row, -1);
}
@@ -222,14 +221,9 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
private void fetch_password() {
var secret = this.item.get_secret();
if (secret != null) {
- unowned string? password = secret.get_text();
- if (password != null) {
- this.password_entry.set_initial_password(password);
- return;
- }
+ this.original_password = secret.get_text() ?? "";
+ this.password_entry.text = this.original_password;
}
-
- this.password_entry.set_initial_password("");
}
private async void save_description() {
@@ -244,31 +238,33 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
[GtkCallback]
private void on_copy_button_clicked() {
- var clipboard = Gtk.Clipboard.get_default(this.get_display());
- this.item.copy_secret_to_clipboard.begin(clipboard);
+ this.item.copy_secret_to_clipboard.begin(get_clipboard());
}
[GtkCallback]
private void on_delete_button_clicked() {
var deleter = this.item.create_deleter();
- var ret = deleter.prompt(this);
-
- if (!ret)
- return;
-
- deleter.delete.begin(null, (obj, res) => {
- try {
- deleter.delete.end(res);
- this.destroy();
- } catch (GLib.Error e) {
- var dialog = new Gtk.MessageDialog(this,
- Gtk.DialogFlags.MODAL,
- Gtk.MessageType.ERROR,
- Gtk.ButtonsType.OK,
- _("Error deleting the password."));
- dialog.run();
- dialog.destroy();
+ var prompt = deleter.create_confirm(this);
+ //XXX
+ ((Gtk.Dialog) prompt).response.connect((response) => {
+ if (response != Gtk.ResponseType.ACCEPT) {
+ prompt.destroy();
+ return;
}
+ prompt.destroy();
+
+ deleter.delete.begin(null, (obj, res) => {
+ try {
+ deleter.delete.end(res);
+ this.destroy();
+ } catch (GLib.Error e) {
+ var dialog = new Gtk.MessageDialog(this,
+ Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.ERROR,
+ Gtk.ButtonsType.OK,
+ _("Error deleting the password."));
+ }
+ });
});
}
}
diff --git a/gkr/gkr-item.vala b/gkr/gkr-item.vala
index def1c5b2..3126e63c 100644
--- a/gkr/gkr-item.vala
+++ b/gkr/gkr-item.vala
@@ -69,7 +69,9 @@ public class Item : Secret.Item, Deletable, Viewable {
public GLib.Icon icon {
owned get {
ensure_item_info();
- return this._info.icon ?? new GLib.ThemedIcon (ICON_PASSWORD);
+ // XXX
+ // return this._info.icon ?? new GLib.ThemedIcon (ICON_PASSWORD);
+ return this._info.icon ?? new GLib.ThemedIcon ("dialog-password-symbolic");
}
}
@@ -246,7 +248,7 @@ public class Item : Secret.Item, Deletable, Viewable {
return true;
}
- public async void copy_secret_to_clipboard(Gtk.Clipboard clipboard) throws GLib.Error {
+ public async void copy_secret_to_clipboard(Gdk.Clipboard clipboard) throws GLib.Error {
if (this._item_secret == null)
yield load_item_secret();
@@ -259,7 +261,7 @@ public class Item : Secret.Item, Deletable, Viewable {
if (password == null)
return;
- clipboard.set_text(password, -1);
+ clipboard.set_text(password);
debug("Succesfully copied secret to clipboard");
}
}
@@ -334,7 +336,7 @@ private unowned string map_item_type_to_specific(string? item_type,
class ItemDeleter : Deleter {
private GLib.List<Item> _items;
- public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+ public override Gtk.Window create_confirm(Gtk.Window? parent) {
var num = this._items.length();
if (num == 1) {
var label = ((Secret.Item)_items.data).label;
diff --git a/gkr/gkr-keyring-add.vala b/gkr/gkr-keyring-add.vala
index 1dd94e86..df9d2b75 100644
--- a/gkr/gkr-keyring-add.vala
+++ b/gkr/gkr-keyring-add.vala
@@ -19,8 +19,9 @@
[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-gkr-add-keyring.ui")]
public class Seahorse.Gkr.KeyringAdd : Gtk.Dialog {
+
[GtkChild]
- private unowned Gtk.Entry name_entry;
+ private unowned Adw.EntryRow name_row;
construct {
set_response_sensitive(Gtk.ResponseType.ACCEPT, false);
@@ -41,7 +42,7 @@ public class Seahorse.Gkr.KeyringAdd : Gtk.Dialog {
var cancellable = Dialog.begin_request(this);
var service = Backend.instance().service;
- Secret.Collection.create.begin(service, this.name_entry.text, null, 0,
+ Secret.Collection.create.begin(service, this.name_row.text, null, 0,
cancellable, (obj, res) => {
/* Clear the operation without cancelling it since it is complete */
Dialog.complete_request(this, false);
@@ -57,7 +58,7 @@ public class Seahorse.Gkr.KeyringAdd : Gtk.Dialog {
}
[GtkCallback]
- private void on_name_entry_changed(Gtk.Editable editable) {
- set_response_sensitive(Gtk.ResponseType.ACCEPT, this.name_entry.text != "");
+ private void on_name_row_changed(Gtk.Editable editable) {
+ set_response_sensitive(Gtk.ResponseType.ACCEPT, this.name_row.text != "");
}
}
diff --git a/gkr/gkr-keyring.vala b/gkr/gkr-keyring.vala
index a7c8113b..756d8dc7 100644
--- a/gkr/gkr-keyring.vala
+++ b/gkr/gkr-keyring.vala
@@ -18,10 +18,9 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-namespace Seahorse {
-namespace Gkr {
+namespace Seahorse.Gkr {
-public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lockable, Viewable {
+public class Keyring : Secret.Collection, GLib.ListModel, Place, Deletable, Lockable, Viewable {
private const ActionEntry[] KEYRING_ACTIONS = {
{ "set-default", on_action_set_default },
@@ -43,10 +42,6 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
}
}
- public GLib.Icon icon {
- owned get { return new GLib.ThemedIcon("folder"); }
- }
-
public Place.Category category {
get { return Place.Category.PASSWORDS; }
}
@@ -65,10 +60,6 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
owned get { return this._menu_model; }
}
- public bool show_if_empty {
- get { return true; }
- }
-
public bool is_default {
get { return Backend.instance().has_alias ("default", this); }
}
@@ -85,10 +76,9 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
get { return true; }
}
- private GLib.HashTable<string, Item> _items;
+ private GenericArray<Gkr.Item> _items = new GenericArray<Gkr.Item>();
construct {
- this._items = new GLib.HashTable<string, Item>(GLib.str_hash, GLib.str_equal);
this.notify.connect((pspec) => {
if (pspec.name == "items" || pspec.name == "locked")
refresh_collection();
@@ -102,19 +92,27 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
this._menu_model = create_menu_model();
}
- public uint get_length() {
- return _items.size();
- }
+ public GLib.Type get_item_type() {
+ return typeof(Gkr.Item);
+ }
- public GLib.List<weak GLib.Object> get_objects() {
- return _items.get_values();
- }
+ public uint get_n_items() {
+ return this._items.length;
+ }
- public bool contains(GLib.Object obj) {
- if (obj is Item)
- return _items.lookup(((Item)obj).get_object_path()) != null;
- return false;
- }
+ public GLib.Object? get_item(uint index) {
+ if (index >= this._items.length)
+ return null;
+ return this._items[index];
+ }
+
+ private Gkr.Item? lookup_by_path(string object_path) {
+ for (uint i = 0; i < this._items.length; i++) {
+ if (object_path == this._items[i].get_object_path())
+ return this._items[i];
+ }
+ return null;
+ }
public Gtk.Window? create_viewer(Gtk.Window? parent) {
return new KeyringProperties(this, parent);
@@ -153,36 +151,37 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
return true;
}
- private void refresh_collection() {
- var seen = new GLib.GenericSet<string>(GLib.str_hash, GLib.str_equal);
-
- GLib.List<Secret.Item> items = null;
- if (!get_locked())
- items = get_items();
-
- foreach (var item in items) {
- var object_path = item.get_object_path();
- seen.add(object_path);
-
- if (_items.lookup(object_path) == null) {
- item.set("place", this);
- _items.insert(object_path, (Item)item);
- emit_added(item);
- }
- }
-
- /* Remove any that we didn't find */
- var iter = GLib.HashTableIter<string, Item>(_items);
- string object_path;
- while (iter.next (out object_path, null)) {
- if (!seen.contains(object_path)) {
- var item = _items.lookup(object_path);
- item.set("place", null);
- iter.remove();
- emit_removed (item);
- }
- }
- }
+ private void refresh_collection() {
+ var seen = new GLib.GenericSet<string>(GLib.str_hash, GLib.str_equal);
+
+ GLib.List<Secret.Item> items = null;
+ if (!get_locked())
+ items = get_items();
+
+ // NOTE: this is not _items
+ foreach (var item in items) {
+ unowned var object_path = item.get_object_path();
+ seen.add(object_path);
+
+ if (lookup_by_path(object_path) == null) {
+ item.set("place", this);
+ this._items.add((Item) item);
+ items_changed(this._items.length - 1, 0, 1);
+ }
+ }
+
+ /* Remove any that we didn't find */
+ for (uint i = 0; i < this._items.length; i++) {
+ unowned var object_path = this._items[i].get_object_path();
+ if (!seen.contains(object_path)) {
+ var item = lookup_by_path(object_path);
+ item.set("place", null);
+ this._items.remove(item);
+ items_changed(i, 1, 0);
+ i--;
+ }
+ }
+ }
public void on_action_set_default(SimpleAction action, Variant? param) {
set_as_default();
@@ -190,7 +189,7 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
public void set_as_default() {
var parent = null;
- var service = this.service;
+ var service = this.service;
service.set_alias.begin("default", this, null, (obj, res) => {
try {
@@ -258,7 +257,7 @@ class KeyringDeleter : Deleter {
private Keyring? _keyring;
private GLib.List<GLib.Object> _objects;
- public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+ public override Gtk.Window create_confirm(Gtk.Window? parent) {
var dialog = new DeleteDialog(parent,
_("Are you sure you want to delete the password keyring “%s”?"),
this._keyring.label);
@@ -296,4 +295,3 @@ class KeyringDeleter : Deleter {
}
}
-}
diff --git a/gkr/meson.build b/gkr/meson.build
index b530fb8d..479b7418 100644
--- a/gkr/meson.build
+++ b/gkr/meson.build
@@ -10,14 +10,12 @@ gkr_sources = files(
'gkr-keyring-properties.vala',
'gkr-keyring.vala',
'gkr-module.vala',
- 'gkr-password-entry.vala',
)
gkr_dependencies = [
glib_deps,
- gtk,
- gcr,
- gcr_ui,
+ gtk4_dep,
+ gcr4_dep,
libsecret,
libpwquality,
common_dep,
diff --git a/gkr/seahorse-gkr-add-item.ui b/gkr/seahorse-gkr-add-item.ui
index 93336f59..83695bce 100644
--- a/gkr/seahorse-gkr-add-item.ui
+++ b/gkr/seahorse-gkr-add-item.ui
@@ -1,110 +1,63 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGkrItemAdd" parent="GtkDialog">
<property name="title" translatable="yes">Add Password</property>
<property name="modal">True</property>
- <property name="window-position">center-on-parent</property>
- <property name="border_width">5</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="border_width">5</property>
<property name="spacing">6</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
- <object class="GtkGrid">
- <property name="visible">True</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Keyring:</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">_Keyring</property>
<property name="use_underline">True</property>
+ <child type="suffix">
+ <object class="GtkComboBox" id="item_keyring_combo">
+ <property name="valign">center</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="item_keyring_combo">
- <property name="visible">True</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
- </packing>
</child>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Description:</property>
+ <object class="AdwEntryRow" id="description_row">
+ <property name="title" translatable="yes">_Description</property>
<property name="use_underline">True</property>
+ <signal name="changed" handler="on_description_row_changed"/>
</object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="item_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="activates_default">True</property>
- <property name="width_chars">16</property>
- <signal name="changed" handler="on_add_item_entry_changed"/>
- </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="xalign">0</property>
- <property name="label" translatable="yes">_Password:</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">_Password</property>
<property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="password_area">
- <property name="visible">True</property>
- <child>
- <placeholder/>
+ <child type="suffix">
+ <object class="GtkPasswordEntry" id="password_entry">
+ <property name="valign">center</property>
+ </object>
</child>
</object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">1</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
<child>
<object class="GtkImage" id="password_strength_icon">
- <property name="visible">True</property>
<property name="halign">end</property>
<property name="icon-name">dialog-warning-symbolic</property>
<style>
<class name="dim-label"/>
</style>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLevelBar" id="password_strength_bar">
- <property name="visible">True</property>
<property name="valign">start</property>
<property name="min_value">0</property>
<property name="max_value">5</property>
@@ -117,10 +70,6 @@
<offset name="strength-high" value="5"/>
</offsets>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
</child>
</object>
</child>
@@ -128,15 +77,14 @@
</child>
<child type="action">
<object class="GtkButton" id="cancel_button">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Cancel</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="use-underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
- <property name="visible">True</property>
- <property name="can-default">True</property>
- <property name="label" translatable="yes">Add</property>
+ <property name="label" translatable="yes">_Add</property>
+ <property name="use-underline">True</property>
</object>
</child>
<action-widgets>
diff --git a/gkr/seahorse-gkr-add-keyring.ui b/gkr/seahorse-gkr-add-keyring.ui
index 523ac62d..eb1b4015 100644
--- a/gkr/seahorse-gkr-add-keyring.ui
+++ b/gkr/seahorse-gkr-add-keyring.ui
@@ -1,92 +1,45 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGkrKeyringAdd" parent="GtkDialog">
<property name="modal">True</property>
<property name="title" translatable="yes">Add password keyring</property>
- <property name="window-position">center-on-parent</property>
- <property name="border_width">5</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="spacing">2</property>
+ <property name="spacing">6</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="border_width">5</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Please choose a name for the new keyring. You will
be prompted for an unlock password.</property>
- <property name="wrap">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please choose a name for the new keyring. You will be
prompted for an unlock password.</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">New Keyring Name:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="name_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="max_length">32</property>
- <property name="hexpand">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
- <property name="width_chars">16</property>
- <signal name="changed" handler="on_name_entry_changed"/>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
+ <object class="AdwEntryRow" id="name_row">
+ <property name="title" translatable="yes">New Keyring Name:</property>
+ <signal name="changed" handler="on_name_row_changed"/>
</object>
- <packing>
- <property name="position">1</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
<child type="action">
<object class="GtkButton" id="cancel_button">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Cancel</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="use-underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
- <property name="visible">True</property>
- <property name="can-default">True</property>
- <property name="label" translatable="yes">Add</property>
+ <property name="label" translatable="yes">_Add</property>
+ <property name="use-underline">True</property>
</object>
</child>
<action-widgets>
diff --git a/gkr/seahorse-gkr-item-properties.ui b/gkr/seahorse-gkr-item-properties.ui
index 32e46c9d..063b3b62 100644
--- a/gkr/seahorse-gkr-item-properties.ui
+++ b/gkr/seahorse-gkr-item-properties.ui
@@ -1,89 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGkrItemProperties" parent="GtkDialog">
<property name="width_request">400</property>
<property name="height_request">400</property>
- <property name="can_focus">False</property>
- <property name="title" translatable="yes">Item Properties</property>
- <property name="window_position">center-on-parent</property>
- <property name="type_hint">dialog</property>
- <child>
- <placeholder/>
+ <child type="titlebar">
+ <object class="GtkHeaderBar">
+ <property name="show-title-buttons">True</property>
+ <property name="title-widget">
+ <object class="AdwWindowTitle" id="window_title">
+ <property name="title" translatable="yes">Item Properties</property>
+ </object>
+ </property>
+ </object>
</child>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="halign">fill</property>
<property name="orientation">vertical</property>
- <property name="border_width">0</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox">
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<property name="propagate_natural_height">True</property>
<property name="propagate_natural_width">True</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="margin">18</property>
<property name="spacing">12</property>
<child>
- <object class="GtkListBox">
- <property name="visible">True</property>
- <property name="selection_mode">none</property>
- <style>
- <class name="content"/>
- </style>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwEntryRow" id="description_field">
<property name="title" translatable="yes">Description</property>
- <property name="activatable_widget">description_field</property>
- <child>
- <object class="GtkEntry" id="description_field">
- <property name="visible">True</property>
- <property name="valign">center</property>
- <property name="can_focus">True</property>
- <property name="max_width_chars">32</property>
- </object>
- </child>
</object>
</child>
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
<property name="title" translatable="yes">Password</property>
<child>
- <object class="GtkBox" id="password_box_area">
- <property name="visible">True</property>
+ <object class="GtkBox">
<property name="valign">center</property>
+ <child>
+ <object class="GtkPasswordEntry" id="password_entry">
+ </object>
+ </child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Copy</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_copy_button_clicked" swapped="no"/>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
</child>
<style>
<class name="linked"/>
@@ -93,72 +62,49 @@
</object>
</child>
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
<property name="title" translatable="yes" comments="To translators: This is the noun
not the verb.">Use</property>
<child>
<object class="GtkLabel" id="use_field">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
</object>
</child>
</object>
</child>
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
<property name="title" translatable="yes">Type</property>
<child>
<object class="GtkLabel" id="type_field">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
</object>
</child>
</object>
</child>
<child>
- <object class="HdyActionRow" id="server_row">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow" id="server_row">
<property name="title" translatable="yes">Server</property>
<child>
<object class="GtkLabel" id="server_field">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
</object>
</child>
</object>
</child>
<child>
- <object class="HdyActionRow" id="login_row">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow" id="login_row">
<property name="title" translatable="yes">Login</property>
<child>
<object class="GtkLabel" id="login_field">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
</object>
</child>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
- <object class="HdyPreferencesGroup" id="details_group">
+ <object class="AdwPreferencesGroup" id="details_group">
<property name="title" translatable="yes">Details</property>
<child>
<object class="GtkListBox" id="details_box">
- <property name="visible">True</property>
<property name="selection_mode">none</property>
- <property name="can_focus">False</property>
<style>
<class name="content"/>
</style>
@@ -169,8 +115,6 @@
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Delete Password</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">end</property>
<signal name="clicked" handler="on_delete_button_clicked" swapped="no"/>
@@ -178,12 +122,6 @@
<class name="destructive-action"/>
</style>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
diff --git a/libseahorse/meson.build b/libseahorse/meson.build
index 97708275..82c5a98a 100644
--- a/libseahorse/meson.build
+++ b/libseahorse/meson.build
@@ -5,7 +5,7 @@ libseahorse_sources = files(
libseahorse_deps = [
glib_deps,
- gcr,
+ gcr4_dep,
libsecret,
common_dep,
]
diff --git a/libseahorse/seahorse-progress.c b/libseahorse/seahorse-progress.c
index 5226ba53..f289e3d1 100644
--- a/libseahorse/seahorse-progress.c
+++ b/libseahorse/seahorse-progress.c
@@ -136,7 +136,7 @@ tracked_task_free (void *data)
g_free (task->notice);
g_clear_object (&task->builder);
if (task->dialog)
- gtk_widget_destroy (task->dialog);
+ gtk_window_destroy (GTK_WINDOW (task->dialog));
g_free (task);
}
diff --git a/meson.build b/meson.build
index 0e3c7b16..f8bb6645 100644
--- a/meson.build
+++ b/meson.build
@@ -36,10 +36,10 @@ glib_deps = [
dependency('gio-unix-2.0',version: '>=' + min_glib_version),
dependency('gmodule-2.0', version: '>=' + min_glib_version),
]
-gtk = dependency('gtk+-3.0', version: '>= 3.24.0')
-libhandy_dep = dependency('libhandy-1', version: '>= 1.6.0')
-gcr = dependency('gcr-3', version: '>=' + min_gcr_version)
-gcr_ui = dependency('gcr-ui-3', version: '>=' + min_gcr_version)
+gtk4_dep = dependency('gtk4', version: '>= 4.6')
+libadwaita_dep = dependency('libadwaita-1', version: '>= 1.0')
+gcr4_dep = dependency('gcr-4', version: '>=' + min_gcr_version)
+# gcr_ui = dependency('gcr-ui-3', version: '>=' + min_gcr_version)
libsecret = dependency('libsecret-1', version: '>= 0.16')
libpwquality = dependency('pwquality')
posix = valac.find_library('posix')
diff --git a/pgp/meson.build b/pgp/meson.build
index 1d4b6db9..c1f53967 100644
--- a/pgp/meson.build
+++ b/pgp/meson.build
@@ -1,5 +1,4 @@
pgp_sources = files(
- 'seahorse-combo-keys.c',
'seahorse-discovery.c',
'seahorse-gpgme.c',
'seahorse-gpgme-add-subkey.c',
@@ -39,7 +38,7 @@ pgp_sources = files(
pgp_dependencies = [
config,
glib_deps,
- gcr,
+ gcr4_dep,
gpgme_dep,
common_dep,
libseahorse_dep,
diff --git a/pgp/seahorse-gpgme-add-uid.c b/pgp/seahorse-gpgme-add-uid.c
index ed9b70a2..96cbca89 100644
--- a/pgp/seahorse-gpgme-add-uid.c
+++ b/pgp/seahorse-gpgme-add-uid.c
@@ -51,18 +51,18 @@ G_DEFINE_TYPE (SeahorseGpgmeAddUid, seahorse_gpgme_add_uid, GTK_TYPE_DIALOG)
static gboolean
check_name_input (SeahorseGpgmeAddUid *self)
{
- const gchar *name;
+ const char *name;
- name = gtk_entry_get_text (GTK_ENTRY (self->name_entry));
+ name = gtk_editable_get_text (GTK_EDITABLE (self->name_entry));
return strlen (name) >= 5;
}
static gboolean
check_email_input (SeahorseGpgmeAddUid *self)
{
- const gchar *email;
+ const char *email;
- email = gtk_entry_get_text (GTK_ENTRY (self->email_entry));
+ email = gtk_editable_get_text (GTK_EDITABLE (self->email_entry));
return strlen (email) == 0 || g_pattern_match_simple ("?*@?*", email);
}
@@ -220,32 +220,39 @@ on_gpgme_key_op_uid_added (GObject *source, GAsyncResult *result, gpointer user_
}
seahorse_gpgme_key_refresh (key);
- gtk_widget_destroy (GTK_WIDGET (g_steal_pointer (&dialog)));
+ gtk_window_destroy (GTK_WINDOW (g_steal_pointer (&dialog)));
}
-void
-seahorse_gpgme_add_uid_run_dialog (SeahorseGpgmeKey *pkey, GtkWindow *parent)
+static void
+on_response (GtkDialog *dialg, int response, gpointer user_data)
{
g_autoptr(SeahorseGpgmeAddUid) dialog = NULL;
- GtkResponseType response;
- const gchar *name, *email, *comment;
-
- g_return_if_fail (SEAHORSE_GPGME_IS_KEY (pkey));
+ const char *name, *email, *comment;
- dialog = seahorse_gpgme_add_uid_new (pkey, parent);
- response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy (GTK_WIDGET (g_steal_pointer (&dialog)));
+ gtk_window_destroy (GTK_WINDOW (g_steal_pointer (&dialog)));
return;
}
- name = gtk_entry_get_text (GTK_ENTRY (dialog->name_entry));
- email = gtk_entry_get_text (GTK_ENTRY (dialog->email_entry));
- comment = gtk_entry_get_text (GTK_ENTRY (dialog->comment_entry));
+ name = gtk_editable_get_text (GTK_EDITABLE (dialog->name_entry));
+ email = gtk_editable_get_text (GTK_EDITABLE (dialog->email_entry));
+ comment = gtk_editable_get_text (GTK_EDITABLE (dialog->comment_entry));
- seahorse_gpgme_key_op_add_uid_async (pkey,
+ seahorse_gpgme_key_op_add_uid_async (dialog->key,
name, email, comment,
NULL,
on_gpgme_key_op_uid_added,
g_steal_pointer (&dialog));
}
+
+void
+seahorse_gpgme_add_uid_run_dialog (SeahorseGpgmeKey *pkey, GtkWindow *parent)
+{
+ g_autoptr(SeahorseGpgmeAddUid) dialog = NULL;
+
+ g_return_if_fail (SEAHORSE_GPGME_IS_KEY (pkey));
+
+ dialog = seahorse_gpgme_add_uid_new (pkey, parent);
+ g_signal_connect (dialog, "response", G_CALLBACK (on_response), NULL);
+ gtk_window_present (GTK_WINDOW (g_steal_pointer (&dialog)));
+}
diff --git a/pgp/seahorse-gpgme-add-uid.ui b/pgp/seahorse-gpgme-add-uid.ui
index 30f73fdd..316c142b 100644
--- a/pgp/seahorse-gpgme-add-uid.ui
+++ b/pgp/seahorse-gpgme-add-uid.ui
@@ -1,10 +1,8 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGpgmeAddUid" parent="GtkDialog">
<property name="visible">True</property>
<property name="default-width">400</property>
- <property name="border_width">5</property>
<property name="title" translatable="yes">Add User ID</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
diff --git a/pgp/seahorse-gpgme-dialogs.h b/pgp/seahorse-gpgme-dialogs.h
index 3167d298..36de5103 100644
--- a/pgp/seahorse-gpgme-dialogs.h
+++ b/pgp/seahorse-gpgme-dialogs.h
@@ -58,6 +58,3 @@ void seahorse_gpgme_expires_new (SeahorseGpgmeSubkey *subkey
gboolean seahorse_gpgme_photo_add (SeahorseGpgmeKey *pkey,
GtkWindow *parent,
const char *path);
-
-gboolean seahorse_gpgme_photo_delete (SeahorseGpgmePhoto *photo,
- GtkWindow *parent);
diff --git a/pgp/seahorse-gpgme-expires-dialog.c b/pgp/seahorse-gpgme-expires-dialog.c
index a9acebe3..7a7ec90e 100644
--- a/pgp/seahorse-gpgme-expires-dialog.c
+++ b/pgp/seahorse-gpgme-expires-dialog.c
@@ -58,13 +58,11 @@ seahorse_gpgme_expires_dialog_response (GtkDialog *dialog, int response)
if (response != GTK_RESPONSE_OK)
return;
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->never_expires_check))) {
- unsigned int y, m, d;
+ if (!gtk_check_button_get_active (GTK_CHECK_BUTTON (self->never_expires_check))) {
g_autoptr(GDateTime) now = NULL;
- gtk_calendar_get_date (GTK_CALENDAR (self->calendar), &y, &m, &d);
- expires = g_date_time_new_utc (y, m + 1, d, 0, 0, 0);
- now = g_date_time_new_now_utc ();
+ expires = gtk_calendar_get_date (GTK_CALENDAR (self->calendar));
+ now = g_date_time_new_now_local ();
if (g_date_time_compare (expires, now) <= 0) {
seahorse_util_show_error (self->calendar, _("Invalid expiry date"),
@@ -91,7 +89,7 @@ on_gpgme_expire_toggled (GtkWidget *widget,
SeahorseGpgmeExpiresDialog *self = SEAHORSE_GPGME_EXPIRES_DIALOG (user_data);
gtk_widget_set_sensitive (self->calendar,
- !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->never_expires_check)));
+ !gtk_check_button_get_active (GTK_CHECK_BUTTON (self->never_expires_check)));
}
static void
@@ -157,17 +155,12 @@ seahorse_gpgme_expires_dialog_constructed (GObject *obj)
expires = seahorse_pgp_subkey_get_expires (SEAHORSE_PGP_SUBKEY (self->subkey));
if (expires == NULL) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->never_expires_check), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (self->never_expires_check), TRUE);
gtk_widget_set_sensitive (self->calendar, FALSE);
} else {
- int y, m, d;
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->never_expires_check), FALSE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (self->never_expires_check), FALSE);
gtk_widget_set_sensitive (self->calendar, TRUE);
-
- g_date_time_get_ymd (expires, &y, &m, &d);
- gtk_calendar_select_month (GTK_CALENDAR (self->calendar), m - 1, y);
- gtk_calendar_select_day (GTK_CALENDAR (self->calendar), d);
+ gtk_calendar_select_day (GTK_CALENDAR (self->calendar), expires);
}
}
diff --git a/pgp/seahorse-gpgme-expires-dialog.ui b/pgp/seahorse-gpgme-expires-dialog.ui
index 2d73d897..4e66daa5 100644
--- a/pgp/seahorse-gpgme-expires-dialog.ui
+++ b/pgp/seahorse-gpgme-expires-dialog.ui
@@ -1,50 +1,34 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGpgmeExpiresDialog" parent="GtkDialog">
- <property name="visible">True</property>
- <property name="border-width">12</property>
<property name="width-request">400</property>
<property name="modal">True</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox" id="all-controls">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkCheckButton" id="never_expires_check">
<property name="label" translatable="yes">_Never expires</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_gpgme_expire_toggled"/>
</object>
</child>
<child>
<object class="GtkCalendar" id="calendar">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
</object>
</child>
</object>
</child>
<child type="action">
<object class="GtkButton" id="cancel_button">
- <property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
+ <property name="label" translatable="yes">_Change</property>
+ <property name="use_underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">False</property>
<property name="label" translatable="yes">C_hange</property>
<property name="use_underline">True</property>
</object>
diff --git a/pgp/seahorse-gpgme-generate-dialog.c b/pgp/seahorse-gpgme-generate-dialog.c
index d522502b..5857d086 100644
--- a/pgp/seahorse-gpgme-generate-dialog.c
+++ b/pgp/seahorse-gpgme-generate-dialog.c
@@ -49,14 +49,15 @@ struct _SeahorseGpgmeGenerateDialog {
SeahorseGpgmeKeyring *keyring;
- GtkWidget *name_entry;
- GtkWidget *email_entry;
- GtkWidget *comment_entry;
+ GtkWidget *name_row;
+ GtkWidget *name_row_warning;
+ GtkWidget *email_row;
+ GtkWidget *comment_row;
GtkWidget *algorithm_choice;
- GtkWidget *bits_entry;
+ GtkWidget *bits_spin;
- GtkWidget *expires_check;
+ GtkWidget *expires_switch;
GtkWidget *expires_datepicker;
};
@@ -104,6 +105,65 @@ on_generate_key_complete (GObject *source,
g_variant_new_string ("gnupg"));
}
+typedef struct _GenerateClosure {
+ SeahorseGpgmeKeyring *keyring;
+ char *name;
+ char *email;
+ char *comment;
+ unsigned int type;
+ unsigned int bits;
+ GDateTime *expires;
+ GtkWindow *parent;
+} GenerateClosure;
+
+static void
+generate_closure_free (void *data)
+{
+ GenerateClosure *closure = data;
+ g_clear_object (&closure->keyring);
+ g_clear_pointer (&closure->name, g_free);
+ g_clear_pointer (&closure->email, g_free);
+ g_clear_pointer (&closure->comment, g_free);
+ g_clear_object (&closure->expires);
+ g_clear_object (&closure->parent);
+}
+
+static void
+on_pass_prompt_response (GtkDialog *dialog, int response, void *user_data)
+{
+ SeahorsePassphrasePrompt *pdialog = SEAHORSE_PASSPHRASE_PROMPT (dialog);
+ GenerateClosure *closure = user_data;
+ const char *pass;
+ g_autoptr(GCancellable) cancellable = NULL;
+ const char *notice;
+
+ if (response == GTK_RESPONSE_ACCEPT) {
+ pass = seahorse_passphrase_prompt_get_text (pdialog);
+ cancellable = g_cancellable_new ();
+ seahorse_gpgme_key_op_generate_async (closure->keyring,
+ closure->name,
+ closure->email,
+ closure->comment,
+ pass,
+ closure->type,
+ closure->bits,
+ closure->expires,
+ cancellable, on_generate_key_complete,
+ closure->parent);
+
+ /* Has line breaks because GtkLabel is completely broken WRT wrapping */
+ notice = _("When creating a key we need to generate a lot of\n"
+ "random data and we need you to help. It’s a good\n"
+ "idea to perform some other action like typing on\n"
+ "the keyboard, moving the mouse, using applications.\n"
+ "This gives the system the random data that it needs.");
+ seahorse_progress_show_with_notice (cancellable, _("Generating key"), notice, FALSE);
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+ generate_closure_free (closure);
+}
+
/**
* gpgme_generate_key:
* @sksrc: the seahorse source
@@ -129,34 +189,26 @@ seahorse_gpgme_generate_key (SeahorseGpgmeKeyring *keyring,
GDateTime *expires,
GtkWindow *parent)
{
- GCancellable *cancellable;
- const gchar *pass;
SeahorsePassphrasePrompt *dialog;
- const gchar *notice;
+ GenerateClosure *closure;
dialog = seahorse_passphrase_prompt_show_dialog (_("Passphrase for New PGP Key"),
- _("Enter the passphrase for your new key twice."),
- NULL, NULL, TRUE);
+ _("Enter the passphrase for your new key twice."),
+ NULL, NULL, TRUE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- pass = seahorse_passphrase_prompt_get_text (dialog);
- cancellable = g_cancellable_new ();
- seahorse_gpgme_key_op_generate_async (keyring, name, email, comment,
- pass, type, bits, expires,
- cancellable, on_generate_key_complete,
- parent);
- /* Has line breaks because GtkLabel is completely broken WRT wrapping */
- notice = _("When creating a key we need to generate a lot of\n"
- "random data and we need you to help. It’s a good\n"
- "idea to perform some other action like typing on\n"
- "the keyboard, moving the mouse, using applications.\n"
- "This gives the system the random data that it needs.");
- seahorse_progress_show_with_notice (cancellable, _("Generating key"), notice, FALSE);
- g_object_unref (cancellable);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ closure = g_new0 (GenerateClosure, 1);
+ closure->keyring = g_object_ref (keyring);
+ closure->name = g_strdup (name);
+ closure->email = g_strdup (email);
+ closure->comment = g_strdup (comment);
+ closure->type = type;
+ closure->bits = bits;
+ closure->expires = expires? g_object_ref (expires) : NULL;
+ closure->parent = parent? g_object_ref (parent) : NULL;
+
+ g_signal_connect (dialog, "response", G_CALLBACK (on_pass_prompt_response), closure);
+ gtk_window_present (GTK_WINDOW (dialog));
}
/* If the name has more than 5 characters, this sets the ok button sensitive */
@@ -169,31 +221,25 @@ on_gpgme_generate_entry_changed (GtkEditable *editable,
gboolean name_long_enough;
/* A 5 character name is required */
- name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->name_entry)));
+ name = g_strdup (gtk_editable_get_text (GTK_EDITABLE (self->name_row)));
name_long_enough = name && strlen (g_strstrip (name)) >= 5;
/* If not, show the user and disable the create button */
- if (!name_long_enough) {
- g_object_set (self->name_entry,
- "secondary-icon-name", "dialog-warning-symbolic",
- "secondary-icon-tooltip-text", _("Name must be at least 5 characters long."),
- NULL);
- } else {
- g_object_set (self->name_entry, "secondary-icon-name", NULL, NULL);
- }
-
+ gtk_widget_set_visible (self->name_row_warning, !name_long_enough);
gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, name_long_enough);
}
/* Handles the expires toggle button feedback */
static void
-on_gpgme_generate_expires_toggled (GtkToggleButton *button,
- gpointer user_data)
+on_gpgme_generate_expires_notify (GObject *object,
+ GParamSpec *pspec,
+ void *user_data)
{
SeahorseGpgmeGenerateDialog *self = SEAHORSE_GPGME_GENERATE_DIALOG (user_data);
+ gboolean never_expires;
- gtk_widget_set_sensitive (self->expires_datepicker,
- !gtk_toggle_button_get_active (button));
+ never_expires = gtk_switch_get_active (GTK_SWITCH (self->expires_switch));
+ gtk_widget_set_sensitive (self->expires_datepicker, !never_expires);
}
/* Changes the bit range depending on the algorithm set */
@@ -207,15 +253,15 @@ on_gpgme_generate_algorithm_changed (GtkComboBox *combo,
sel = gtk_combo_box_get_active (combo);
g_assert (sel < (int)G_N_ELEMENTS (available_algorithms));
- gtk_spin_button_set_range (GTK_SPIN_BUTTON (self->bits_entry),
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (self->bits_spin),
available_algorithms[sel].min,
available_algorithms[sel].max);
/* Set sane default key length */
if (available_algorithms[sel].def > available_algorithms[sel].max)
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->bits_entry), available_algorithms[sel].max);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->bits_spin), available_algorithms[sel].max);
else
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->bits_entry), available_algorithms[sel].def);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->bits_spin), available_algorithms[sel].def);
}
static void
@@ -233,13 +279,13 @@ seahorse_gpgme_generate_dialog_response (GtkDialog *dialog, int response)
return;
/* Make sure the name is the right length. Should've been checked earlier */
- name = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->name_entry)));
+ name = g_strdup (gtk_editable_get_text (GTK_EDITABLE (self->name_row)));
g_return_if_fail (name);
name = g_strstrip (name);
g_return_if_fail (strlen(name) >= 5);
- email = gtk_entry_get_text (GTK_ENTRY (self->email_entry));
- comment = gtk_entry_get_text (GTK_ENTRY (self->comment_entry));
+ email = gtk_editable_get_text (GTK_EDITABLE (self->email_row));
+ comment = gtk_editable_get_text (GTK_EDITABLE (self->comment_row));
/* The algorithm */
sel = gtk_combo_box_get_active (GTK_COMBO_BOX (self->algorithm_choice));
@@ -247,14 +293,14 @@ seahorse_gpgme_generate_dialog_response (GtkDialog *dialog, int response)
type = available_algorithms[sel].type;
/* The number of bits */
- bits = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (self->bits_entry));
+ bits = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (self->bits_spin));
if (bits < available_algorithms[sel].min || bits > available_algorithms[sel].max) {
bits = available_algorithms[sel].def;
g_message ("invalid key size: %s defaulting to %u", available_algorithms[sel].desc, bits);
}
/* The expiry */
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->expires_check)))
+ if (!gtk_switch_get_active (GTK_SWITCH (self->expires_switch)))
expires = seahorse_date_picker_get_datetime (SEAHORSE_DATE_PICKER (self->expires_datepicker));
/* Less confusing with less on the screen */
@@ -362,15 +408,16 @@ seahorse_gpgme_generate_dialog_class_init (SeahorseGpgmeGenerateDialogClass *kla
g_object_class_install_properties (gobject_class, N_PROPS, obj_props);
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Seahorse/seahorse-gpgme-generate-dialog.ui");
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, name_entry);
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, email_entry);
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, comment_entry);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, name_row);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, name_row_warning);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, email_row);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, comment_row);
gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, algorithm_choice);
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, bits_entry);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, bits_spin);
gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, expires_datepicker);
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, expires_check);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeGenerateDialog, expires_switch);
gtk_widget_class_bind_template_callback (widget_class, on_gpgme_generate_entry_changed);
- gtk_widget_class_bind_template_callback (widget_class, on_gpgme_generate_expires_toggled);
+ gtk_widget_class_bind_template_callback (widget_class, on_gpgme_generate_expires_notify);
gtk_widget_class_bind_template_callback (widget_class, on_gpgme_generate_algorithm_changed);
dialog_class->response = seahorse_gpgme_generate_dialog_response;
diff --git a/pgp/seahorse-gpgme-generate-dialog.ui b/pgp/seahorse-gpgme-generate-dialog.ui
index 35380ce3..940dfccf 100644
--- a/pgp/seahorse-gpgme-generate-dialog.ui
+++ b/pgp/seahorse-gpgme-generate-dialog.ui
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">512</property>
<property name="upper">8192</property>
@@ -16,264 +15,109 @@
</object>
<template class="SeahorseGpgmeGenerateDialog" parent="GtkDialog">
<property name="title" translatable="yes">New PGP key</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">5</property>
<property name="resizable">False</property>
<property name="modal">True</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="orientation">vertical</property>
- <property name="spacing">2</property>
+ <property name="spacing">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <property name="margin">12</property>
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">A PGP key allows you to encrypt email or files to
other people.</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">A PGP key allows you to encrypt email or files to
other people.</property>
+ <object class="AdwEntryRow" id="name_row">
+ <property name="title" translatable="yes" comments="Full name of the key, usually the name
of the user.">Full _Name</property>
+ <property name="use-underline">True</property>
+ <property name="input-purpose">name</property>
+ <signal name="changed" handler="on_gpgme_generate_entry_changed"/>
+ <child type="suffix">
+ <object class="GtkImage" id="name_row_warning">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ <property name="tooltip-text" translatable="yes">Name must be at least 5 characters
long.</property>
+ </object>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
- <object class="GtkGrid">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes" comments="Full name of the key, usually the
name of the user.">Full _Name</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">name_entry</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="name_entry">
- <property name="width_request">180</property>
- <property name="visible">True</property>
- <property name="input-purpose">name</property>
- <property name="activates_default">True</property>
- <signal name="changed" handler="on_gpgme_generate_entry_changed" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="email_label">
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Email Address</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">email_entry</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="email_entry">
- <property name="width_request">180</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="input-purpose">email</property>
- <property name="activates_default">True</property>
- <signal name="changed" handler="on_gpgme_generate_entry_changed" swapped="no"/>
- </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="margin_top">18</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes">_Advanced key options</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- <property name="width">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Comment</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">comment_entry</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="comment_entry">
- <property name="width_request">180</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
- <signal name="changed" handler="on_gpgme_generate_entry_changed" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label49">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Encryption _Type</property>
- <property name="use_underline">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
+ <object class="AdwEntryRow" id="email_row">
+ <property name="title" translatable="yes">_Email Address</property>
+ <property name="use-underline">True</property>
+ <property name="input-purpose">email</property>
+ <signal name="changed" handler="on_gpgme_generate_entry_changed"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Advanced key options</property>
+ <child>
+ <object class="AdwEntryRow" id="comment_row">
+ <property name="title" translatable="yes">_Comment</property>
+ <property name="use-underline">True</property>
+ <signal name="changed" handler="on_gpgme_generate_entry_changed"/>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="algorithm_row">
+ <property name="title" translatable="yes">Encryption _Type</property>
+ <property name="use-underline">True</property>
+ <child type="suffix">
<object class="GtkComboBoxText" id="algorithm_choice">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
+ <property name="valign">center</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
<signal name="changed" handler="on_gpgme_generate_algorithm_changed" swapped="no"/>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label50">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Key _Strength (bits)</property>
- <property name="use_underline">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">5</property>
- <property name="left_attach">0</property>
- </packing>
</child>
- <child>
- <object class="GtkSpinButton" id="bits_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="halign">start</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="bits_row">
+ <property name="title" translatable="yes">Key _Strength (bits)</property>
+ <property name="use-underline">True</property>
+ <child type="suffix">
+ <object class="GtkSpinButton" id="bits_spin">
+ <property name="valign">center</property>
<property name="adjustment">adjustment1</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
- <packing>
- <property name="top_attach">5</property>
- <property name="left_attach">1</property>
- </packing>
</child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">E_xpiration Date</property>
- <property name="use_underline">True</property>
- <property name="mnemonic-widget">expires_datepicker</property>
- <style>
- <class name="dim-label"/>
- </style>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Ne_ver Expires</property>
+ <property name="use-underline">True</property>
+ <child type="suffix">
+ <object class="GtkSwitch" id="expires_switch">
+ <property name="valign">center</property>
+ <property name="active">True</property>
+ <signal name="notify" handler="on_gpgme_generate_expires_notify"/>
</object>
- <packing>
- <property name="top_attach">6</property>
- <property name="left_attach">0</property>
- </packing>
</child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="SeahorseDatePicker" id="expires_datepicker">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- </object>
- </child>
- <child>
- <object class="GtkCheckButton" id="expires_check">
- <property name="label" translatable="yes">Ne_ver Expires</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_gpgme_generate_expires_toggled" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="expires_row">
+ <property name="title" translatable="yes">E_xpiration Date</property>
+ <property name="use-underline">True</property>
+ <child type="suffix">
+ <object class="SeahorseDatePicker" id="expires_datepicker">
+ <property name="valign">center</property>
+ <property name="sensitive">False</property>
</object>
- <packing>
- <property name="top_attach">6</property>
- <property name="left_attach">1</property>
- </packing>
</child>
</object>
</child>
@@ -284,22 +128,13 @@
<child type="action">
<object class="GtkButton" id="cancelbutton1">
<property name="label" translatable="yes">_Cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
<property name="use_underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">C_reate</property>
- <property name="visible">True</property>
<property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Generate a new key</property>
<property name="use_underline">True</property>
<style>
diff --git a/pgp/seahorse-gpgme-key-deleter.c b/pgp/seahorse-gpgme-key-deleter.c
index 61d52c31..39226001 100644
--- a/pgp/seahorse-gpgme-key-deleter.c
+++ b/pgp/seahorse-gpgme-key-deleter.c
@@ -62,7 +62,7 @@ seahorse_gpgme_key_deleter_finalize (GObject *obj)
G_OBJECT_CLASS (seahorse_gpgme_key_deleter_parent_class)->finalize (obj);
}
-static GtkDialog *
+static GtkWindow *
seahorse_gpgme_key_deleter_create_confirm (SeahorseDeleter *deleter,
GtkWindow *parent)
{
diff --git a/pgp/seahorse-gpgme-key-op.c b/pgp/seahorse-gpgme-key-op.c
index 52aaac1a..2b56f746 100644
--- a/pgp/seahorse-gpgme-key-op.c
+++ b/pgp/seahorse-gpgme-key-op.c
@@ -2357,12 +2357,6 @@ photoid_load_transit (unsigned int current_state,
g_unlink (parm->output_file);
- /* Load a 'missing' icon */
- if (!pixbuf) {
- pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
- "gnome-unknown", 48, 0, NULL);
- }
-
seahorse_pgp_photo_set_pixbuf (SEAHORSE_PGP_PHOTO (photo), pixbuf);
g_object_unref (pixbuf);
}
diff --git a/pgp/seahorse-gpgme-keyring.c b/pgp/seahorse-gpgme-keyring.c
index eceb7107..8097cab3 100644
--- a/pgp/seahorse-gpgme-keyring.c
+++ b/pgp/seahorse-gpgme-keyring.c
@@ -51,7 +51,7 @@
struct _SeahorseGpgmeKeyring {
GObject parent_instance;
- GHashTable *keys;
+ GPtrArray *keys;
unsigned int scheduled_refresh; /* Source for refresh timeout */
GFileMonitor *monitor_handle; /* For monitoring the .gnupg directory */
GList *orphan_secret; /* Orphan secret keys */
@@ -62,22 +62,20 @@ enum {
PROP_0,
PROP_LABEL,
PROP_DESCRIPTION,
- PROP_ICON,
PROP_CATEGORY,
PROP_URI,
PROP_ACTIONS,
PROP_ACTION_PREFIX,
PROP_MENU_MODEL,
- PROP_SHOW_IF_EMPTY,
N_PROPS
};
static void seahorse_gpgme_keyring_place_iface (SeahorsePlaceIface *iface);
-static void seahorse_gpgme_keyring_collection_iface (GcrCollectionIface *iface);
+static void seahorse_gpgme_keyring_list_model_iface (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorseGpgmeKeyring, seahorse_gpgme_keyring, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION,
seahorse_gpgme_keyring_collection_iface);
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, seahorse_gpgme_keyring_list_model_iface);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_gpgme_keyring_place_iface);
);
@@ -130,6 +128,8 @@ passphrase_get (void *hook,
NULL,
confirm);
+ // XXX
+#if 0
switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
case GTK_RESPONSE_ACCEPT:
pass = seahorse_passphrase_prompt_get_text (dialog);
@@ -142,6 +142,7 @@ passphrase_get (void *hook,
};
gtk_widget_destroy (GTK_WIDGET (dialog));
+#endif
return err;
}
@@ -229,8 +230,8 @@ add_key_to_context (SeahorseGpgmeKeyring *self,
pkey = seahorse_gpgme_key_new (SEAHORSE_PLACE (self), key, NULL);
/* Add to context */
- g_hash_table_insert (self->keys, g_strdup (keyid), pkey);
- gcr_collection_emit_added (GCR_COLLECTION (self), G_OBJECT (pkey));
+ g_ptr_array_add (self->keys, pkey);
+ g_list_model_items_changed (G_LIST_MODEL (self), self->keys->len - 1, 0, 1);
return pkey;
}
@@ -243,7 +244,7 @@ remove_key (SeahorseGpgmeKeyring *self,
{
SeahorseGpgmeKey *key;
- key = g_hash_table_lookup (self->keys, keyid);
+ key = seahorse_gpgme_keyring_lookup (self, keyid);
if (key != NULL)
seahorse_gpgme_keyring_remove_key (self, key);
}
@@ -255,7 +256,6 @@ on_idle_list_batch_of_keys (void *data)
GTask *task = G_TASK (data);
keyring_list_closure *closure = g_task_get_task_data (task);
SeahorseGpgmeKey *pkey;
- GHashTableIter iter;
gpgme_key_t key;
unsigned int batch;
g_autofree char *detail = NULL;
@@ -266,6 +266,7 @@ on_idle_list_batch_of_keys (void *data)
while (batch-- > 0) {
if (!GPG_IS_OK (gpgme_op_keylist_next (closure->gctx, &key))) {
+ GHashTableIter iter;
gpgme_op_keylist_end (closure->gctx);
@@ -328,7 +329,6 @@ seahorse_gpgme_keyring_list_async (SeahorseGpgmeKeyring *self,
keyring_list_closure *closure;
SeahorseObject *object;
gpgme_error_t gerr = 0;
- GHashTableIter iter;
g_autoptr(GError) error = NULL;
task = g_task_new (self, cancellable, callback, user_data);
@@ -358,16 +358,19 @@ seahorse_gpgme_keyring_list_async (SeahorseGpgmeKeyring *self,
/* Loading all the keys? */
if (patterns == NULL) {
- char *keyid;
-
closure->checks = g_hash_table_new_full (seahorse_pgp_keyid_hash,
seahorse_pgp_keyid_equal,
g_free, NULL);
- g_hash_table_iter_init (&iter, self->keys);
- while (g_hash_table_iter_next (&iter, (void **) &keyid, (void **) &object)) {
- if ((secret && seahorse_object_get_usage (object) == SEAHORSE_USAGE_PRIVATE_KEY) ||
- (!secret && seahorse_object_get_usage (object) == SEAHORSE_USAGE_PUBLIC_KEY)) {
- keyid = g_strdup (keyid);
+ for (unsigned int i = 0; i < self->keys->len; i++) {
+ SeahorsePgpKey *key = g_ptr_array_index (self->keys, i);
+ SeahorseUsage usage;
+
+ usage = seahorse_object_get_usage (SEAHORSE_OBJECT (key));
+ if ((secret && usage == SEAHORSE_USAGE_PRIVATE_KEY) ||
+ (!secret && usage == SEAHORSE_USAGE_PUBLIC_KEY)) {
+ char *keyid;
+
+ keyid = (char*) seahorse_pgp_key_get_keyid (key);
g_hash_table_insert (closure->checks, keyid, keyid);
}
}
@@ -511,7 +514,15 @@ seahorse_gpgme_keyring_lookup (SeahorseGpgmeKeyring *self,
g_return_val_if_fail (SEAHORSE_IS_GPGME_KEYRING (self), NULL);
g_return_val_if_fail (keyid != NULL, NULL);
- return g_hash_table_lookup (self->keys, keyid);
+ for (unsigned int i = 0; i < self->keys->len; i++) {
+ SeahorseGpgmeKey *pkey = g_ptr_array_index (self->keys, i);
+ const char *pkeyid;
+
+ pkeyid = seahorse_pgp_key_get_keyid (SEAHORSE_PGP_KEY (pkey));
+ if (seahorse_pgp_keyid_equal (keyid, pkeyid))
+ return pkey;
+ }
+ return NULL;
}
void
@@ -519,16 +530,19 @@ seahorse_gpgme_keyring_remove_key (SeahorseGpgmeKeyring *self,
SeahorseGpgmeKey *key)
{
const char *keyid;
+ gboolean found;
+ unsigned int pos;
g_return_if_fail (SEAHORSE_IS_GPGME_KEYRING (self));
g_return_if_fail (SEAHORSE_GPGME_IS_KEY (key));
keyid = seahorse_pgp_key_get_keyid (SEAHORSE_PGP_KEY (key));
- g_return_if_fail (g_hash_table_lookup (self->keys, keyid) == key);
+ found = g_ptr_array_find (self->keys, key, &pos);
+ g_return_if_fail (found);
g_object_ref (key);
- g_hash_table_remove (self->keys, keyid);
- gcr_collection_emit_removed (GCR_COLLECTION (self), G_OBJECT (key));
+ g_ptr_array_remove_index (self->keys, pos);
+ g_list_model_items_changed (G_LIST_MODEL (self), pos, 1, 0);
g_object_unref (key);
}
@@ -583,16 +597,16 @@ on_keyring_import_loaded (GObject *source,
g_autoptr(GList) keys = NULL;
for (unsigned int i = 0; closure->patterns[i] != NULL; i++) {
- SeahorseObject *object;
+ SeahorseGpgmeKey *key;
- object = g_hash_table_lookup (closure->keyring->keys, closure->patterns[i]);
- if (object == NULL) {
+ key = seahorse_gpgme_keyring_lookup (closure->keyring, closure->patterns[i]);
+ if (key == NULL) {
g_warning ("imported key but then couldn't find it in keyring: %s",
closure->patterns[i]);
continue;
}
- keys = g_list_prepend (keys, object);
+ keys = g_list_prepend (keys, key);
}
seahorse_progress_end (g_task_get_cancellable (task), task);
@@ -747,9 +761,7 @@ seahorse_gpgme_keyring_init (SeahorseGpgmeKeyring *self)
g_autoptr(GFile) file = NULL;
g_autoptr(GError) err = NULL;
- self->keys = g_hash_table_new_full (seahorse_pgp_keyid_hash,
- seahorse_pgp_keyid_equal,
- g_free, g_object_unref);
+ self->keys = g_ptr_array_new_with_free_func (g_object_unref);
self->scheduled_refresh = 0;
self->monitor_handle = NULL;
@@ -796,12 +808,6 @@ seahorse_gpgme_keyring_get_description (SeahorsePlace *place)
return g_strdup (_("GnuPG: default keyring directory"));
}
-static GIcon *
-seahorse_gpgme_keyring_get_icon (SeahorsePlace *place)
-{
- return g_themed_icon_new (GCR_ICON_GNUPG);
-}
-
static SeahorsePlaceCategory
seahorse_gpgme_keyring_get_category (SeahorsePlace *place)
{
@@ -835,12 +841,6 @@ seahorse_gpgme_keyring_get_uri (SeahorsePlace *place)
return g_strdup ("gnupg://");
}
-static gboolean
-seahorse_gpgme_keyring_get_show_if_empty (SeahorsePlace *place)
-{
- return TRUE;
-}
-
static void
seahorse_gpgme_keyring_get_property (GObject *obj,
unsigned int prop_id,
@@ -856,9 +856,6 @@ seahorse_gpgme_keyring_get_property (GObject *obj,
case PROP_DESCRIPTION:
g_value_take_string (value, seahorse_gpgme_keyring_get_description (place));
break;
- case PROP_ICON:
- g_value_take_object (value, seahorse_gpgme_keyring_get_icon (place));
- break;
case PROP_CATEGORY:
g_value_set_enum (value, seahorse_gpgme_keyring_get_category (place));
break;
@@ -874,9 +871,6 @@ seahorse_gpgme_keyring_get_property (GObject *obj,
case PROP_MENU_MODEL:
g_value_take_object (value, seahorse_gpgme_keyring_get_menu_model (place));
break;
- case PROP_SHOW_IF_EMPTY:
- g_value_set_boolean (value, TRUE);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -906,8 +900,6 @@ seahorse_gpgme_keyring_dispose (GObject *object)
{
SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (object);
- g_hash_table_remove_all (self->keys);
-
cancel_scheduled_refresh (self);
g_clear_object (&self->monitor_handle);
@@ -924,7 +916,7 @@ seahorse_gpgme_keyring_finalize (GObject *object)
SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (object);
g_clear_object (&self->actions);
- g_hash_table_destroy (self->keys);
+ g_ptr_array_unref (self->keys);
/* All monitoring and scheduling should be done */
g_assert (self->scheduled_refresh == 0);
@@ -953,12 +945,10 @@ seahorse_gpgme_keyring_class_init (SeahorseGpgmeKeyringClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
g_object_class_override_property (gobject_class, PROP_URI, "uri");
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_override_property (gobject_class, PROP_CATEGORY, "category");
g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
g_object_class_override_property (gobject_class, PROP_ACTION_PREFIX, "action-prefix");
g_object_class_override_property (gobject_class, PROP_MENU_MODEL, "menu-model");
- g_object_class_override_property (gobject_class, PROP_SHOW_IF_EMPTY, "show-if-empty");
}
static void
@@ -970,48 +960,42 @@ seahorse_gpgme_keyring_place_iface (SeahorsePlaceIface *iface)
iface->get_action_prefix = seahorse_gpgme_keyring_get_action_prefix;
iface->get_menu_model = seahorse_gpgme_keyring_get_menu_model;
iface->get_description = seahorse_gpgme_keyring_get_description;
- iface->get_icon = seahorse_gpgme_keyring_get_icon;
iface->get_category = seahorse_gpgme_keyring_get_category;
iface->get_label = seahorse_gpgme_keyring_get_label;
iface->set_label = seahorse_gpgme_keyring_set_label;
iface->get_uri = seahorse_gpgme_keyring_get_uri;
- iface->get_show_if_empty = seahorse_gpgme_keyring_get_show_if_empty;
}
-static unsigned int
-seahorse_gpgme_keyring_get_length (GcrCollection *collection)
+static GType
+seahorse_gpgme_keyring_get_item_type (GListModel *list)
{
- SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (collection);
- return g_hash_table_size (self->keys);
+ return SEAHORSE_GPGME_TYPE_KEY;
}
-static GList *
-seahorse_gpgme_keyring_get_objects (GcrCollection *collection)
+static unsigned int
+seahorse_gpgme_keyring_get_n_items (GListModel *list)
{
- SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (collection);
- return g_hash_table_get_values (self->keys);
+ SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (list);
+ return self->keys->len;
}
-static gboolean
-seahorse_gpgme_keyring_contains (GcrCollection *collection,
- GObject *object)
+static void *
+seahorse_gpgme_keyring_get_item (GListModel *list,
+ unsigned int index)
{
- SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (collection);
- const char *keyid;
-
- if (!SEAHORSE_GPGME_IS_KEY (object))
- return FALSE;
+ SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (list);
- keyid = seahorse_pgp_key_get_keyid (SEAHORSE_PGP_KEY (object));
- return g_hash_table_lookup (self->keys, keyid) == object;
+ if (index >= self->keys->len)
+ return NULL;
+ return g_object_ref (g_ptr_array_index (self->keys, index));
}
static void
-seahorse_gpgme_keyring_collection_iface (GcrCollectionIface *iface)
+seahorse_gpgme_keyring_list_model_iface (GListModelInterface *iface)
{
- iface->get_objects = seahorse_gpgme_keyring_get_objects;
- iface->get_length = seahorse_gpgme_keyring_get_length;
- iface->contains = seahorse_gpgme_keyring_contains;
+ iface->get_item_type = seahorse_gpgme_keyring_get_item_type;
+ iface->get_n_items = seahorse_gpgme_keyring_get_n_items;
+ iface->get_item = seahorse_gpgme_keyring_get_item;
}
/**
diff --git a/pgp/seahorse-gpgme-photos.c b/pgp/seahorse-gpgme-photos.c
index 24bb517a..eb316b85 100644
--- a/pgp/seahorse-gpgme-photos.c
+++ b/pgp/seahorse-gpgme-photos.c
@@ -38,6 +38,8 @@
#define LARGE_WIDTH 240
#define LARGE_HEIGHT 288
+// XXX
+#if 0
static gboolean
calc_scale (int *width, int *height)
{
@@ -238,98 +240,69 @@ add_image_files (GtkWidget *dialog)
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
}
-
+#endif
gboolean
seahorse_gpgme_photo_add (SeahorseGpgmeKey *pkey,
GtkWindow *parent,
- const gchar *path)
-{
- gchar *filename = NULL;
- gchar *tempfile = NULL;
- GError *error = NULL;
- gpgme_error_t gerr;
- GtkWidget *chooser;
- gboolean res = TRUE;
-
- g_return_val_if_fail (SEAHORSE_GPGME_IS_KEY (pkey), FALSE);
-
- if (NULL == path) {
- chooser = gtk_file_chooser_dialog_new (_("Choose Photo to Add to Key"), parent,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_Open"), GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
- add_image_files (chooser);
-
- if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
-
- gtk_widget_destroy (chooser);
-
- if (!filename)
- return FALSE;
- } else {
- filename = g_strdup (path);
- }
-
- if (!prepare_photo_id (parent, filename, &tempfile, &error)) {
- seahorse_util_handle_error (&error, NULL, _("Couldn’t prepare photo"));
- return FALSE;
- }
-
- gerr = seahorse_gpgme_key_op_photo_add (pkey, tempfile ? tempfile : filename);
- if (!GPG_IS_OK (gerr)) {
-
- /* A special error value set by seahorse_key_op_photoid_add to
- denote an invalid format file */
- if (gerr == GPG_E (GPG_ERR_USER_1))
- seahorse_util_show_error (NULL, _("Couldn’t add photo"),
- _("The file could not be loaded. It may be in an invalid
format."));
- else
- seahorse_gpgme_handle_error (gerr, _("Couldn’t add photo"));
- res = FALSE;
- }
-
- g_free (filename);
- if (tempfile) {
- unlink (tempfile);
- g_free (tempfile);
- }
-
- return res;
-}
-
-gboolean
-seahorse_gpgme_photo_delete (SeahorseGpgmePhoto *photo, GtkWindow *parent)
+ const char *path)
{
+#if 0
+ g_autofree char *filename = NULL;
+ char *tempfile = NULL;
+ GError *error = NULL;
gpgme_error_t gerr;
- GtkWidget *dlg;
- int response;
+ GtkWidget *chooser;
+ gboolean res = TRUE;
- g_return_val_if_fail (SEAHORSE_IS_GPGME_PHOTO (photo), FALSE);
+ g_return_val_if_fail (SEAHORSE_GPGME_IS_KEY (pkey), FALSE);
- dlg = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
- _("Are you sure you want to remove the current photo from your key?"));
+ if (NULL == path) {
+ chooser = gtk_file_chooser_dialog_new (_("Choose Photo to Add to Key"), parent,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Open"), GTK_RESPONSE_ACCEPT,
+ NULL);
- gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Delete"), GTK_RESPONSE_ACCEPT);
- gtk_dialog_add_button (GTK_DIALOG (dlg), _("_Cancel"), GTK_RESPONSE_REJECT);
+ gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
+ add_image_files (chooser);
- response = gtk_dialog_run (GTK_DIALOG (dlg));
- gtk_widget_destroy (dlg);
+ if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
- if (response != GTK_RESPONSE_ACCEPT)
+ gtk_widget_destroy (chooser);
+
+ if (!filename)
+ return FALSE;
+ } else {
+ filename = g_strdup (path);
+ }
+
+ if (!prepare_photo_id (parent, filename, &tempfile, &error)) {
+ seahorse_util_handle_error (&error, NULL, _("Couldn’t prepare photo"));
return FALSE;
+ }
- gerr = seahorse_gpgme_key_op_photo_delete (photo);
+ gerr = seahorse_gpgme_key_op_photo_add (pkey, tempfile ? tempfile : filename);
if (!GPG_IS_OK (gerr)) {
- seahorse_gpgme_handle_error (gerr, _("Couldn’t delete photo"));
- return FALSE;
+
+ /* A special error value set by seahorse_key_op_photoid_add to
+ denote an invalid format file */
+ if (gerr == GPG_E (GPG_ERR_USER_1))
+ seahorse_util_show_error (NULL, _("Couldn’t add photo"),
+ _("The file could not be loaded. It may be in an invalid format."));
+ else
+ seahorse_gpgme_handle_error (gerr, _("Couldn’t add photo"));
+ res = FALSE;
}
- return TRUE;
+ if (tempfile) {
+ unlink (tempfile);
+ g_free (tempfile);
+ }
+
+ return res;
+#endif
+ return FALSE;
}
diff --git a/pgp/seahorse-gpgme-revoke-dialog.c b/pgp/seahorse-gpgme-revoke-dialog.c
index aa98c832..8f9599f2 100644
--- a/pgp/seahorse-gpgme-revoke-dialog.c
+++ b/pgp/seahorse-gpgme-revoke-dialog.c
@@ -74,7 +74,7 @@ on_gpgme_revoke_ok_clicked (GtkButton *button,
reason = g_value_get_int (&value);
g_value_unset (&value);
- description = gtk_entry_get_text (GTK_ENTRY (self->description_entry));
+ description = gtk_editable_get_text (GTK_EDITABLE (self->description_entry));
err = seahorse_gpgme_key_op_revoke_subkey (self->subkey, reason, description);
if (!GPG_IS_OK (err))
diff --git a/pgp/seahorse-gpgme-sign-dialog.c b/pgp/seahorse-gpgme-sign-dialog.c
index 1059f29e..7e504d68 100644
--- a/pgp/seahorse-gpgme-sign-dialog.c
+++ b/pgp/seahorse-gpgme-sign-dialog.c
@@ -20,7 +20,6 @@
#include "config.h"
-#include "seahorse-combo-keys.h"
#include "seahorse-gpgme-sign-dialog.h"
#include "seahorse-gpgme-key-op.h"
#include "seahorse-pgp-keysets.h"
@@ -49,7 +48,7 @@ struct _SeahorseGpgmeSignDialog {
GtkWidget *sign_option_local;
GtkWidget *sign_option_revocable;
- GtkWidget *signer_select;
+ GtkWidget *signer_row;
GtkWidget *signer_frame;
};
@@ -64,14 +63,16 @@ G_DEFINE_TYPE (SeahorseGpgmeSignDialog, seahorse_gpgme_sign_dialog, GTK_TYPE_DIA
static void
-on_collection_changed (GcrCollection *collection,
- GObject *object,
+on_collection_changed (GListModel *model,
+ unsigned int position,
+ unsigned int removed,
+ unsigned int added,
gpointer user_data)
{
SeahorseGpgmeSignDialog *self = SEAHORSE_GPGME_SIGN_DIALOG (user_data);
gtk_widget_set_visible (self->signer_frame,
- gcr_collection_get_length (collection) > 1);
+ g_list_model_get_n_items (model) > 1);
}
static void
@@ -125,7 +126,7 @@ seahorse_gpgme_sign_dialog_response (GtkDialog *dialog, int response)
options |= SIGN_NO_REVOKE;
/* Signer */
- signer = seahorse_combo_keys_get_active (GTK_COMBO_BOX (self->signer_select));
+ signer = adw_combo_row_get_selected_item (ADW_COMBO_ROW (self->signer_row));
g_assert (!signer || (SEAHORSE_GPGME_IS_KEY (signer) &&
seahorse_object_get_usage (SEAHORSE_OBJECT (signer)) ==
SEAHORSE_USAGE_PRIVATE_KEY));
@@ -145,8 +146,8 @@ seahorse_gpgme_sign_dialog_response (GtkDialog *dialog, int response)
w = gtk_message_dialog_new (GTK_WINDOW (self), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
_("This key was already signed by\n“%s”"),
seahorse_object_get_label (SEAHORSE_OBJECT (signer)));
- gtk_dialog_run (GTK_DIALOG (w));
- gtk_widget_destroy (w);
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
} else
seahorse_gpgme_handle_error (err, _("Couldn’t sign key"));
}
@@ -258,7 +259,7 @@ seahorse_gpgme_sign_dialog_class_init (SeahorseGpgmeSignDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeSignDialog, sign_option_local);
gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeSignDialog, sign_option_revocable);
gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeSignDialog, signer_frame);
- gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeSignDialog, signer_select);
+ gtk_widget_class_bind_template_child (widget_class, SeahorseGpgmeSignDialog, signer_row);
gtk_widget_class_bind_template_callback (widget_class, on_gpgme_sign_choice_toggled);
dialog_class->response = seahorse_gpgme_sign_dialog_response;
@@ -268,14 +269,14 @@ SeahorseGpgmeSignDialog *
seahorse_gpgme_sign_dialog_new (SeahorseObject *to_sign)
{
g_autoptr(SeahorseGpgmeSignDialog) self = NULL;
- GcrCollection *collection;
+ g_autoptr(GListModel) model = NULL;
g_return_val_if_fail (SEAHORSE_GPGME_IS_KEY (to_sign) ||
SEAHORSE_GPGME_IS_UID (to_sign), NULL);
/* If no signing keys then we can't sign */
- collection = seahorse_keyset_pgp_signers_new ();
- if (gcr_collection_get_length (collection) == 0) {
+ model = seahorse_keyset_pgp_signers_new ();
+ if (g_list_model_get_n_items (model) == 0) {
/* TODO: We should be giving an error message that allows them to
generate or import a key */
seahorse_util_show_error (NULL, _("No keys usable for signing"),
@@ -289,17 +290,13 @@ seahorse_gpgme_sign_dialog_new (SeahorseObject *to_sign)
NULL);
/* Signature area */
- g_signal_connect_object (collection, "added",
+ g_signal_connect_object (model, "model",
G_CALLBACK (on_collection_changed), self, 0);
- g_signal_connect_object (collection, "removed",
- G_CALLBACK (on_collection_changed), self, 0);
- on_collection_changed (collection, NULL, self);
+ on_collection_changed (model, 0, 0, 0, self);
/* Signer box */
- seahorse_combo_keys_attach (GTK_COMBO_BOX (self->signer_select),
- collection, NULL);
-
- g_object_unref (collection);
+ /* XXX I think we still need to set a factory here? */
+ adw_combo_row_set_model (ADW_COMBO_ROW (self->signer_row), model);
return g_steal_pointer (&self);
}
diff --git a/pgp/seahorse-gpgme-sign-dialog.ui b/pgp/seahorse-gpgme-sign-dialog.ui
index cf03894d..884dfef2 100644
--- a/pgp/seahorse-gpgme-sign-dialog.ui
+++ b/pgp/seahorse-gpgme-sign-dialog.ui
@@ -1,25 +1,19 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseGpgmeSignDialog" parent="GtkDialog">
- <property name="visible">True</property>
<property name="title" translatable="yes">Sign Key</property>
<property name="resizable">False</property>
<property name="use_header_bar">1</property>
<child internal-child="vbox">
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="border_width">12</property>
<property name="spacing">18</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">By signing you indicate your trust that this key
belongs to:</property>
@@ -27,7 +21,6 @@
</child>
<child>
<object class="GtkLabel" id="to_sign_name_label">
- <property name="visible">True</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Key Name</property>
<property name="use_markup">True</property>
@@ -41,12 +34,10 @@
</child>
<child>
<object class="GtkBox" id="vbox6">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label8">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">How carefully have you checked this key?</property>
@@ -57,26 +48,21 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="margin-start">12</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkRadioButton" id="sign_choice_not">
<property name="label" translatable="yes">_Not at all</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
@@ -86,8 +72,6 @@
<child>
<object class="GtkRadioButton" id="sign_choice_casual">
<property name="label" translatable="yes">_Casually</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
@@ -98,8 +82,6 @@
<child>
<object class="GtkRadioButton" id="sign_choice_careful">
<property name="label" translatable="yes">_Very Carefully</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
@@ -111,17 +93,14 @@
</child>
<child>
<object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
<property name="xalign">1</property>
<property name="yalign">1</property>
<property name="left_padding">18</property>
<child>
<object class="GtkBox" id="vbox12">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="sign_display_not">
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes"><i>Not at all:</i>
means you believe the key is owned by the person who claims to own it, but you could not or did not verify
this to be a fact.</property>
@@ -134,7 +113,6 @@
</child>
<child>
<object class="GtkLabel" id="sign_display_casual">
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes"><i>Casually:</i> means
you have done a casual verification that the key is owned by the person who claims to own it. For example,
you could read the key fingerprint to the owner over the phone.</property>
@@ -151,11 +129,8 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkEventBox" id="eventbox1">
- <property name="visible">True</property>
<child>
<object class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes"><i>Very
Carefully:</i> Select this only if you are absolutely sure that this key is genuine.</property>
@@ -170,8 +145,6 @@
</child>
<child>
<object class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">You could use a hard to forge
photo identification (such as a passport) to personally check that the name on the key is correct. You should
have also used email to check that the email address belongs to the owner.</property>
@@ -196,12 +169,10 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label9">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">How others will see this signature:</property>
<attributes>
@@ -211,13 +182,11 @@
</child>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<property name="margin-start">12</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Others may not see this signature</property>
<property name="tooltip_text">If signature is local to the key ring and won't be
exported with the key</property>
@@ -231,8 +200,6 @@
</child>
<child>
<object class="GtkSwitch" id="sign_option_local">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text">If signature is local to the key ring and won't be
exported with the key</property>
</object>
@@ -243,7 +210,6 @@
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">I can _revoke this signature at a later
date.</property>
<property name="tooltip_text">If signature can be revoked</property>
@@ -257,7 +223,6 @@
</child>
<child>
<object class="GtkSwitch" id="sign_option_revocable">
- <property name="visible">True</property>
<property name="tooltip_text">If signature can be revoked</property>
<property name="active">True</property>
</object>
@@ -271,44 +236,10 @@
</object>
</child>
<child>
- <object class="GtkBox" id="signer_frame">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Sign key as:</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
+ <object class="GtkListBox" id="signer_frame">
<child>
- <object class="GtkAlignment" id="alignment7">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkBox" id="hbox2">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Signer:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">signer_select</property>
- </object>
- </child>
- <child>
- <object class="GtkComboBox" id="signer_select">
- <property name="visible">True</property>
- </object>
- </child>
- </object>
- </child>
+ <object class="AdwComboRow" id="signer_row">
+ <property name="label" translatable="yes">_Sign key as</property>
</object>
</child>
</object>
@@ -318,8 +249,6 @@
<child type="action">
<object class="GtkButton" id="cancel_button">
<property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
@@ -327,8 +256,6 @@
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">False</property>
diff --git a/pgp/seahorse-hkp-source.c b/pgp/seahorse-hkp-source.c
index 1e906f90..6cedd023 100644
--- a/pgp/seahorse-hkp-source.c
+++ b/pgp/seahorse-hkp-source.c
@@ -480,7 +480,7 @@ typedef struct {
SoupMessage *message;
GString *response;
int requests;
- GcrSimpleCollection *results;
+ GListStore *results;
} SearchClosure;
static void
@@ -522,7 +522,7 @@ on_search_message_complete (GObject *object,
keys = seahorse_hkp_parse_lookup_response (closure->response->str);
for (GList *l = keys; l; l = g_list_next (l)) {
g_object_set (l->data, "place", closure->source, NULL);
- gcr_simple_collection_add (closure->results, l->data);
+ g_list_store_append (closure->results, l->data);
}
g_task_return_boolean (task, TRUE);
}
@@ -547,7 +547,7 @@ is_hex_keyid (const char *match)
static void
seahorse_hkp_source_search_async (SeahorseServerSource *source,
const char *match,
- GcrSimpleCollection *results,
+ GListStore *results,
GCancellable *cancellable,
GAsyncReadyCallback callback,
void *user_data)
@@ -761,7 +761,6 @@ seahorse_hkp_source_import_finish (SeahorseServerSource *source,
typedef struct {
SeahorseHKPSource *source;
GString *data;
- gsize data_len;
SoupSession *session;
SoupMessage *message;
int requests;
@@ -817,10 +816,10 @@ on_export_message_complete (GObject *object,
closure->requests--;
if (closure->requests == 0) {
- closure->data_len = closure->data->len;
- g_task_return_pointer (task,
- g_string_free (g_steal_pointer (&closure->data), FALSE),
- g_free);
+ g_autoptr(GBytes) result = NULL;
+
+ result = g_string_free_to_bytes (g_steal_pointer (&closure->data));
+ g_task_return_pointer (task, g_steal_pointer (&result), g_bytes_unref);
}
}
@@ -891,19 +890,13 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source,
closure->session, NULL);
}
-static void *
+static GBytes *
seahorse_hkp_source_export_finish (SeahorseServerSource *source,
GAsyncResult *result,
- gsize *size,
GError **error)
{
- ExportClosure *closure;
-
- g_return_val_if_fail (size != NULL, NULL);
g_return_val_if_fail (g_task_is_valid (result, source), NULL);
- closure = g_task_get_task_data (G_TASK (result));
- *size = closure->data_len;
return g_task_propagate_pointer (G_TASK (result), error);
}
diff --git a/pgp/seahorse-keyserver-results.c b/pgp/seahorse-keyserver-results.c
index 2c03b087..baa6ed8d 100644
--- a/pgp/seahorse-keyserver-results.c
+++ b/pgp/seahorse-keyserver-results.c
@@ -35,16 +35,18 @@
#include <string.h>
#define SEAHORSE_TYPE_KEYSERVER_RESULTS_ROW (seahorse_keyserver_results_row_get_type ())
-G_DECLARE_FINAL_TYPE (SeahorseKeyserverResultsRow, seahorse_keyserver_results_row, SEAHORSE,
KEYSERVER_RESULTS_ROW, GtkListBoxRow)
+G_DECLARE_FINAL_TYPE (SeahorseKeyserverResultsRow, seahorse_keyserver_results_row,
+ SEAHORSE, KEYSERVER_RESULTS_ROW,
+ AdwActionRow)
struct _SeahorseKeyserverResultsRow {
- GtkListBoxRow parent;
+ AdwActionRow parent;
GObject *key;
GtkButton *import_button;
};
-G_DEFINE_TYPE (SeahorseKeyserverResultsRow, seahorse_keyserver_results_row, GTK_TYPE_LIST_BOX_ROW);
+G_DEFINE_TYPE (SeahorseKeyserverResultsRow, seahorse_keyserver_results_row, ADW_TYPE_ACTION_ROW);
static void
on_import_complete (GObject *source, GAsyncResult *result, gpointer user_data)
@@ -52,9 +54,8 @@ on_import_complete (GObject *source, GAsyncResult *result, gpointer user_data)
SeahorsePgpBackend *backend = SEAHORSE_PGP_BACKEND (source);
g_autoptr(SeahorseKeyserverResultsRow) row =
SEAHORSE_KEYSERVER_RESULTS_ROW (user_data);
- const gchar *result_icon_name;
- g_autoptr(GtkWidget) result_icon = NULL;
- g_autofree gchar *result_tooltip = NULL;
+ const char *result_icon_name;
+ g_autofree char *result_tooltip = NULL;
g_autoptr(GError) err = NULL;
if (!seahorse_pgp_backend_transfer_finish (backend, result, &err)) {
@@ -66,9 +67,7 @@ on_import_complete (GObject *source, GAsyncResult *result, gpointer user_data)
result_tooltip = g_strdup (_("Key import succeeded"));
}
- result_icon = gtk_image_new_from_icon_name (result_icon_name,
- GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (row->import_button, g_steal_pointer (&result_icon));
+ gtk_button_set_icon_name (row->import_button, result_icon_name);
gtk_widget_set_tooltip_text (GTK_WIDGET (row->import_button),
result_tooltip);
}
@@ -87,7 +86,7 @@ on_import_button_clicked (GtkButton *import_button, gpointer user_data)
gtk_widget_set_sensitive (GTK_WIDGET (import_button), FALSE);
spinner = gtk_spinner_new ();
gtk_spinner_start (GTK_SPINNER (spinner));
- gtk_button_set_image (import_button, g_steal_pointer (&spinner));
+ gtk_button_set_child (import_button, g_steal_pointer (&spinner));
/* Now import the key */
keys = g_list_append (keys, row->key);
@@ -110,53 +109,39 @@ seahorse_keyserver_results_row_init (SeahorseKeyserverResultsRow *row)
{
}
-static SeahorseKeyserverResultsRow*
+static SeahorseKeyserverResultsRow *
seahorse_keyserver_results_row_new (GObject *item)
{
g_autoptr(SeahorseKeyserverResultsRow) row = NULL;
- g_autoptr(GtkWidget) grid = NULL;
- g_autoptr(GtkWidget) label = NULL;
- g_autoptr(GtkWidget) import_button = NULL;
- gchar *item_label;
+ GtkWidget *import_button = NULL;
+ g_autofree char *item_label = NULL;
gboolean item_exportable;
- g_object_get (item, "markup", &item_label, "exportable", &item_exportable,
+ g_object_get (item,
+ "markup", &item_label,
+ "exportable", &item_exportable,
NULL);
row = g_object_new (SEAHORSE_TYPE_KEYSERVER_RESULTS_ROW, NULL);
gtk_list_box_row_set_selectable (GTK_LIST_BOX_ROW (row), FALSE);
gtk_widget_set_sensitive (GTK_WIDGET (row), item_exportable);
- gtk_widget_show (GTK_WIDGET (row));
row->key = item;
- grid = gtk_grid_new ();
- g_object_set (grid, "margin", 6, NULL);
- gtk_widget_show (grid);
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), item_label);
- label = gtk_label_new (item_label);
- gtk_widget_set_hexpand (label, TRUE);
- gtk_label_set_xalign (GTK_LABEL (label), 0);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_widget_show (label);
- gtk_grid_attach (GTK_GRID (grid), g_steal_pointer (&label), 0, 0, 1, 1);
-
- import_button = gtk_button_new_from_icon_name ("document-save-symbolic",
- GTK_ICON_SIZE_BUTTON);
+ import_button = gtk_button_new_from_icon_name ("document-save-symbolic");
row->import_button = GTK_BUTTON (import_button);
g_signal_connect_object (import_button, "clicked",
G_CALLBACK (on_import_button_clicked), row, 0);
- gtk_widget_set_visible (import_button, TRUE);
- gtk_widget_set_valign (import_button, GTK_ALIGN_START);
- gtk_widget_set_halign (import_button, GTK_ALIGN_END);
- gtk_style_context_add_class (gtk_widget_get_style_context (import_button),
- "flat");
- if (item_exportable)
+ gtk_widget_set_valign (import_button, GTK_ALIGN_CENTER);
+ gtk_widget_add_css_class (import_button, "flat");
+ if (item_exportable) {
gtk_widget_set_tooltip_text (import_button, _("Import"));
- else
+ } else {
gtk_widget_set_tooltip_text (import_button, _("Can’t import key"));
- gtk_grid_attach (GTK_GRID (grid), g_steal_pointer (&import_button), 1, 0, 1, 1);
-
- gtk_container_add (GTK_CONTAINER (row), g_steal_pointer (&grid));
+ gtk_widget_set_sensitive (import_button, FALSE);
+ }
+ adw_action_row_add_suffix (ADW_ACTION_ROW (row), import_button);
return g_steal_pointer (&row);
}
@@ -173,7 +158,7 @@ struct _SeahorseKeyserverResults {
GtkBuilder *builder;
char *search_string;
- GcrSimpleCollection *collection;
+ GListStore *collection;
GtkListBox *key_list;
};
@@ -190,27 +175,10 @@ on_row_activated (GtkListBox *key_list, GtkListBoxRow *row, gpointer user_data)
seahorse_viewable_view (_row->key, GTK_WINDOW (self));
}
-static void
-on_item_added (GcrCollection *collection, GObject *item, gpointer user_data)
-{
- SeahorseKeyserverResults *self = SEAHORSE_KEYSERVER_RESULTS (user_data);
- g_autoptr(SeahorseKeyserverResultsRow) row = NULL;
-
- g_return_if_fail (G_IS_OBJECT (item));
-
- row = seahorse_keyserver_results_row_new (item);
- gtk_list_box_insert (self->key_list,
- GTK_WIDGET (g_steal_pointer (&row)),
- -1);
-}
-
-static gboolean
-on_delete_event (GtkWidget* widget, GdkEvent* event, gpointer user_data)
+static GtkWidget *
+create_row_for_key (void *item, gpointer user_data)
{
- SeahorseKeyserverResults *self = SEAHORSE_KEYSERVER_RESULTS (user_data);
-
- gtk_widget_destroy (GTK_WIDGET (self));
- return TRUE;
+ return seahorse_keyserver_results_row_new ((GObject *) item);
}
static void
@@ -232,22 +200,15 @@ seahorse_keyserver_results_constructed (GObject *obj)
gtk_window_set_title (window, title);
gtk_widget_set_visible (GTK_WIDGET (window), TRUE);
- g_signal_connect (window, "delete-event",
- G_CALLBACK (on_delete_event), self);
-
self->builder = gtk_builder_new_from_resource ("/org/gnome/Seahorse/seahorse-keyserver-results.ui");
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (self))),
- GTK_WIDGET (gtk_builder_get_object (self->builder, "keyserver-results")));
+ gtk_window_set_child (GTK_WINDOW (self),
+ GTK_WIDGET (gtk_builder_get_object (self->builder, "keyserver-results")));
/* init key list */
self->key_list = GTK_LIST_BOX (gtk_builder_get_object (self->builder, "key_list"));
g_signal_connect_object (self->key_list, "row-activated",
G_CALLBACK (on_row_activated), self, 0);
- gtk_widget_show (GTK_WIDGET (self->key_list));
-
- /* Make sure the listbox gets updated with the collection */
- g_signal_connect_object (self->collection, "added",
- G_CALLBACK (on_item_added), self, 0);
+ gtk_list_box_bind_model (self->key_list, G_LIST_MODEL (self->collection), create_row_for_key, self,
NULL);
/* Set focus to the current key list */
gtk_widget_grab_focus (GTK_WIDGET (self->key_list));
@@ -256,7 +217,7 @@ seahorse_keyserver_results_constructed (GObject *obj)
static void
seahorse_keyserver_results_init (SeahorseKeyserverResults *self)
{
- self->collection = GCR_SIMPLE_COLLECTION (gcr_simple_collection_new ());
+ self->collection = g_list_store_new (SEAHORSE_PGP_TYPE_KEY);
}
static void
diff --git a/pgp/seahorse-keyserver-results.ui b/pgp/seahorse-keyserver-results.ui
index 4e8cea41..bf218328 100644
--- a/pgp/seahorse-keyserver-results.ui
+++ b/pgp/seahorse-keyserver-results.ui
@@ -1,33 +1,23 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkBox" id="keyserver-results">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="wrap">True</property>
<property name="max-width-chars">40</property>
- <property name="margin">24</property>
- <property name="margin-bottom">0</property>
<property name="label" translatable="yes">Double click on a key to inspect it, or click the
import button to import it into your local keyring.</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
- <property name="margin">24</property>
<property name="margin-top">0</property>
<property name="margin-bottom">0</property>
<child>
<object class="GtkListBox" id="key_list">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="activate_on_single_click">False</property>
<style>
@@ -39,18 +29,15 @@
</child>
<child>
<object class="GtkBox" id="hbox1">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkProgressBar" id="progress-bar">
- <property name="visible">True</property>
<property name="hexpand">True</property>
<property name="pulse_step">0.10000000149</property>
</object>
</child>
<child>
<object class="GtkStatusbar" id="status">
- <property name="visible">True</property>
</object>
</child>
</object>
diff --git a/pgp/seahorse-keyserver-search.c b/pgp/seahorse-keyserver-search.c
index 077b0f34..93fd73dd 100644
--- a/pgp/seahorse-keyserver-search.c
+++ b/pgp/seahorse-keyserver-search.c
@@ -72,7 +72,7 @@ seahorse_keyserver_search_get_search_text (SeahorseKeyserverSearch *self)
{
g_return_val_if_fail (SEAHORSE_IS_KEYSERVER_SEARCH (self), NULL);
- return g_strdup (gtk_entry_get_text (GTK_ENTRY (self->search_entry)));
+ return g_strdup (gtk_editable_get_text (GTK_EDITABLE (self->search_entry)));
}
/* Extracts data, stores it in settings and starts a search using the entered
@@ -148,33 +148,22 @@ create_row_for_server_source (gpointer item,
SeahorseServerSource *ssrc = SEAHORSE_SERVER_SOURCE (item);
g_autofree char *uri = NULL;
GtkWidget *row;
- GtkWidget *grid;
- GtkWidget *label;
GtkWidget *check;
gboolean is_selected;
- row = gtk_list_box_row_new ();
+ row = adw_action_row_new ();
gtk_list_box_row_set_selectable (GTK_LIST_BOX_ROW (row), FALSE);
g_object_set_data (G_OBJECT (row), "keyserver-uri", ssrc);
- grid = gtk_grid_new ();
- g_object_set (grid, "margin", 6, NULL);
- gtk_container_add (GTK_CONTAINER (row), grid);
-
uri = seahorse_place_get_uri (SEAHORSE_PLACE (ssrc));
- label = gtk_label_new (uri);
- gtk_widget_set_hexpand (label, TRUE);
- gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), uri);
- check = gtk_image_new_from_icon_name ("emblem-ok-symbolic",
- GTK_ICON_SIZE_BUTTON);
+ check = gtk_image_new_from_icon_name ("emblem-ok-symbolic");
is_selected = g_ptr_array_find (self->selected_servers, ssrc, NULL);
gtk_widget_set_visible (check, is_selected);
- gtk_grid_attach (GTK_GRID (grid), check, 1, 0, 1, 1);
+ adw_action_row_add_suffix (ADW_ACTION_ROW (row), check);
g_object_set_data (G_OBJECT (row), "check", check);
- gtk_widget_show_all (row);
-
return row;
}
@@ -223,7 +212,7 @@ seahorse_keyserver_search_init (SeahorseKeyserverSearch *self)
search_text = seahorse_app_settings_get_last_search_text (app_settings);
if (search_text != NULL) {
- gtk_entry_set_text (GTK_ENTRY (self->search_entry), search_text);
+ gtk_editable_set_text (GTK_EDITABLE (self->search_entry), search_text);
gtk_editable_select_region (GTK_EDITABLE (self->search_entry), 0, -1);
}
diff --git a/pgp/seahorse-keyserver-search.ui b/pgp/seahorse-keyserver-search.ui
index 557ade9c..c3fd6988 100644
--- a/pgp/seahorse-keyserver-search.ui
+++ b/pgp/seahorse-keyserver-search.ui
@@ -1,32 +1,27 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseKeyserverSearch" parent="GtkDialog">
- <property name="visible">True</property>
- <property name="border_width">18</property>
<property name="use_header_bar">1</property>
<property name="title" translatable="yes">Find Remote Keys</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="border_width">6</property>
<property name="spacing">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">find-location-symbolic</property>
- <property name="icon-size">5</property>
</object>
</child>
<child>
<object class="GtkLabel" id="publish-message">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">This will find keys for others on the Internet.
These keys can then be imported into your local key ring.</property>
<property name="max_width_chars">60</property>
@@ -37,24 +32,18 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Search for keys containing: </property>
+ <property name="label" translatable="yes">_Search for keys containing:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">search_entry</property>
</object>
</child>
<child>
<object class="GtkEntry" id="search_entry">
- <property name="visible">True</property>
<property name="hexpand">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <accelerator key="Return" signal="activate"/>
<signal name="changed" handler="on_keyserver_search_control_changed"/>
<signal name="activate" handler="on_keyserver_search_ok_clicked"/>
</object>
@@ -63,7 +52,6 @@
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Where to search:</property>
<property name="use_markup">True</property>
@@ -75,19 +63,16 @@
</child>
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<property name="propagate-natural-height">True</property>
<property name="max-content-height">250</property>
<child>
<object class="GtkListBox" id="key_server_list">
- <property name="visible">True</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<style>
- <class name="content"/>
+ <class name="boxed-list"/>
</style>
</object>
</child>
@@ -95,22 +80,15 @@
</child>
</object>
</child>
+
<child type="action">
<object class="GtkButton" id="cancelbutton">
- <property name="label" translatable="yes">Cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="use_underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="searchbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">False</property>
<property name="label" translatable="yes">_Search</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_keyserver_search_ok_clicked"/>
diff --git a/pgp/seahorse-keyserver-sync.c b/pgp/seahorse-keyserver-sync.c
index facb49df..210c04b3 100644
--- a/pgp/seahorse-keyserver-sync.c
+++ b/pgp/seahorse-keyserver-sync.c
@@ -35,7 +35,7 @@
struct _SeahorseKeyserverSync {
GtkDialog parent_instance;
- GList *keys;
+ GListModel *keys;
GtkWidget *detail_message;
GtkWidget *publish_message;
@@ -118,10 +118,8 @@ static void
on_sync_ok_clicked (GtkButton *button, gpointer user_data)
{
SeahorseKeyserverSync *self = SEAHORSE_KEYSERVER_SYNC (user_data);
- g_autoptr(GList) keys = NULL;
- keys = g_list_copy (self->keys);
- seahorse_keyserver_sync_do_sync (keys);
+ seahorse_keyserver_sync_do_sync (self->keys);
}
static void
@@ -144,7 +142,7 @@ seahorse_keyserver_sync_get_property (GObject *object,
switch (prop_id) {
case PROP_KEYS:
- g_value_set_pointer (value, self->keys);
+ g_value_set_object (value, self->keys);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -162,8 +160,7 @@ seahorse_keyserver_sync_set_property (GObject *object,
switch (prop_id) {
case PROP_KEYS:
- g_list_free (self->keys);
- self->keys = g_list_copy (g_value_get_pointer (value));
+ g_set_object (&self->keys, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -176,7 +173,7 @@ seahorse_keyserver_sync_finalize (GObject *obj)
{
SeahorseKeyserverSync *self = SEAHORSE_KEYSERVER_SYNC (obj);
- g_clear_pointer (&self->keys, g_list_free);
+ g_clear_object (&self->keys);
G_OBJECT_CLASS (seahorse_keyserver_sync_parent_class)->finalize (obj);
}
@@ -192,7 +189,7 @@ seahorse_keyserver_sync_constructed (GObject *obj)
G_OBJECT_CLASS (seahorse_keyserver_sync_parent_class)->constructed (obj);
/* The details message */
- n_keys = g_list_length (self->keys);
+ n_keys = g_list_model_get_n_items (self->keys);
t = g_strdup_printf (ngettext ("<b>%d key is selected for synchronizing</b>",
"<b>%d keys are selected for synchronizing</b>",
n_keys),
@@ -225,9 +222,8 @@ seahorse_keyserver_sync_class_init (SeahorseKeyserverSyncClass *klass)
gobject_class->finalize = seahorse_keyserver_sync_finalize;
g_object_class_install_property (gobject_class, PROP_KEYS,
- g_param_spec_pointer ("keys", "Keys",
- "A GList of keys which should be synced",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_param_spec_object ("keys", NULL, NULL, G_TYPE_LIST_MODEL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Seahorse/seahorse-keyserver-sync.ui");
@@ -247,7 +243,7 @@ seahorse_keyserver_sync_class_init (SeahorseKeyserverSyncClass *klass)
* Non-interactively synchronizes the given @keys with the chosen keyserver.
*/
void
-seahorse_keyserver_sync_do_sync (GList *keys)
+seahorse_keyserver_sync_do_sync (GListModel *keys)
{
SeahorseServerSource *source;
SeahorseGpgmeKeyring *keyring;
@@ -258,16 +254,17 @@ seahorse_keyserver_sync_do_sync (GList *keys)
g_auto(GStrv) keyservers = NULL;
g_autoptr(GPtrArray) keyids = NULL;
- if (!keys)
- return;
+ g_return_if_fail (G_IS_LIST_MODEL (keys));
keyring = seahorse_pgp_backend_get_default_keyring (NULL);
pgp_settings = seahorse_pgp_settings_instance ();
cancellable = g_cancellable_new ();
keyids = g_ptr_array_new ();
- for (GList *l = keys; l != NULL; l = g_list_next (l))
- g_ptr_array_add (keyids, (char *) seahorse_pgp_key_get_keyid (l->data));
+ for (unsigned int i = 0; i < g_list_model_get_n_items (keys); i++) {
+ g_autoptr(SeahorsePgpKey) key = g_list_model_get_item (keys, i);
+ g_ptr_array_add (keyids, (char *) seahorse_pgp_key_get_keyid (key));
+ }
g_ptr_array_add (keyids, NULL);
/* And now synchronizing keys from the servers */
@@ -305,11 +302,11 @@ seahorse_keyserver_sync_do_sync (GList *keys)
}
SeahorseKeyserverSync *
-seahorse_keyserver_sync_new (GList *keys,
- GtkWindow *parent)
+seahorse_keyserver_sync_new (GListModel *keys,
+ GtkWindow *parent)
{
- g_return_val_if_fail (keys, NULL);
- g_return_val_if_fail (keys->data, NULL);
+ g_return_val_if_fail (G_IS_LIST_MODEL (keys), NULL);
+ g_return_val_if_fail (g_list_model_get_n_items (keys) > 0, NULL);
g_return_val_if_fail (!parent || GTK_IS_WINDOW (parent), NULL);
return g_object_new (SEAHORSE_TYPE_KEYSERVER_SYNC,
diff --git a/pgp/seahorse-keyserver-sync.h b/pgp/seahorse-keyserver-sync.h
index 6b6679d7..983dd664 100644
--- a/pgp/seahorse-keyserver-sync.h
+++ b/pgp/seahorse-keyserver-sync.h
@@ -27,7 +27,7 @@ G_DECLARE_FINAL_TYPE (SeahorseKeyserverSync, seahorse_keyserver_sync,
SEAHORSE, KEYSERVER_SYNC,
GtkDialog)
-SeahorseKeyserverSync * seahorse_keyserver_sync_new (GList *keys,
- GtkWindow *parent);
+SeahorseKeyserverSync * seahorse_keyserver_sync_new (GListModel *keys,
+ GtkWindow *parent);
-void seahorse_keyserver_sync_do_sync (GList *keys);
+void seahorse_keyserver_sync_do_sync (GListModel *keys);
diff --git a/pgp/seahorse-ldap-source.c b/pgp/seahorse-ldap-source.c
index fc17fe40..df4e8377 100644
--- a/pgp/seahorse-ldap-source.c
+++ b/pgp/seahorse-ldap-source.c
@@ -689,7 +689,7 @@ seahorse_ldap_source_init (SeahorseLDAPSource *self)
typedef struct {
char *filter;
LDAP *ldap;
- GcrSimpleCollection *results;
+ GListStore *results;
} SearchClosure;
static void
@@ -718,9 +718,9 @@ static const char *PGP_ATTRIBUTES[] = {
/* Add a key to the key source from an LDAP entry */
static void
search_parse_key_from_ldap_entry (SeahorseLDAPSource *self,
- GcrSimpleCollection *results,
- LDAP *ldap,
- LDAPMessage *res)
+ GListStore *results,
+ LDAP *ldap,
+ LDAPMessage *res)
{
const char *algo;
long int timestamp;
@@ -791,7 +791,7 @@ search_parse_key_from_ldap_entry (SeahorseLDAPSource *self,
NULL);
seahorse_pgp_key_realize (key);
- gcr_simple_collection_add (results, G_OBJECT (key));
+ g_list_store_append (results, key);
}
}
@@ -893,11 +893,11 @@ on_search_connect_completed (GObject *source,
static void
seahorse_ldap_source_search_async (SeahorseServerSource *source,
- const char *match,
- GcrSimpleCollection *results,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ const char *match,
+ GListStore *results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ void *user_data)
{
SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (source);
SearchClosure *closure;
@@ -1270,11 +1270,11 @@ on_export_connect_completed (GObject *source,
}
static void
-seahorse_ldap_source_export_async (SeahorseServerSource *source,
- const char **keyids,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+seahorse_ldap_source_export_async (SeahorseServerSource *source,
+ const char **keyids,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ void *user_data)
{
SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (source);
ExportClosure *closure;
@@ -1300,26 +1300,20 @@ seahorse_ldap_source_export_async (SeahorseServerSource *source,
g_steal_pointer (&task));
}
-static gpointer
+static GBytes *
seahorse_ldap_source_export_finish (SeahorseServerSource *source,
- GAsyncResult *result,
- gsize *size,
- GError **error)
+ GAsyncResult *result,
+ GError **error)
{
ExportClosure *closure;
- gpointer output;
- g_return_val_if_fail (size != NULL, NULL);
g_return_val_if_fail (g_task_is_valid (result, source), NULL);
if (!g_task_propagate_boolean (G_TASK (result), error))
return NULL;
closure = g_task_get_task_data (G_TASK (result));
- *size = closure->data->len;
- output = g_string_free (closure->data, FALSE);
- closure->data = NULL;
- return output;
+ return g_string_free_to_bytes (g_steal_pointer (&closure->data));
}
/* Initialize the basic class stuff */
diff --git a/pgp/seahorse-pgp-actions.c b/pgp/seahorse-pgp-actions.c
index 22c3ad55..2cc8ab4c 100644
--- a/pgp/seahorse-pgp-actions.c
+++ b/pgp/seahorse-pgp-actions.c
@@ -59,39 +59,48 @@ G_DEFINE_TYPE (SeahorsePgpBackendActions, seahorse_pgp_backend_actions, SEAHORSE
#ifdef WITH_KEYSERVER
+static void
+on_keyserver_search_response (GtkDialog *dialog, int response, void *user_data)
+{
+ SeahorseKeyserverSearch *sdialog = SEAHORSE_KEYSERVER_SEARCH (dialog);
+ SeahorseCatalog *catalog = user_data;
+ g_autofree char *search_text = NULL;
+
+ /* If the user pressed "Search", make it happen */
+ if (response == GTK_RESPONSE_ACCEPT) {
+ search_text = seahorse_keyserver_search_get_search_text (sdialog);
+ /* Get search text and save it for next time */
+ g_return_if_fail (search_text && *search_text);
+
+ seahorse_app_settings_set_last_search_text (seahorse_app_settings_instance (),
+ search_text);
+ seahorse_keyserver_results_show (search_text, GTK_WINDOW (catalog));
+ }
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+ g_clear_object (&catalog);
+}
+
static void
on_remote_find (GSimpleAction *action,
GVariant *param,
gpointer user_data)
{
- SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
- SeahorseCatalog *catalog = NULL;
- g_autoptr(SeahorseKeyserverSearch) search_dialog = NULL;
- int response;
- g_autofree gchar *search_text = NULL;
-
- /* Make a new "Find remote keys" dialog */
- catalog = seahorse_action_group_get_catalog (actions);
- search_dialog = seahorse_keyserver_search_new (GTK_WINDOW (catalog));
-
- /* Run it and get the search text */
- response = gtk_dialog_run (GTK_DIALOG (search_dialog));
- search_text = seahorse_keyserver_search_get_search_text (search_dialog);
-
- /* We can safely destroy it */
- gtk_widget_destroy (GTK_WIDGET (g_steal_pointer (&search_dialog)));
-
- /* If the user pressed "Search", make it happen */
- if (response == GTK_RESPONSE_ACCEPT) {
- /* Get search text and save it for next time */
- g_return_if_fail (search_text && *search_text);
-
- seahorse_app_settings_set_last_search_text (seahorse_app_settings_instance (),
- search_text);
- seahorse_keyserver_results_show (search_text, GTK_WINDOW (catalog));
- }
-
- g_clear_object (&catalog);
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
+ SeahorseCatalog *catalog = NULL;
+ SeahorseKeyserverSearch *search_dialog = NULL;
+
+ /* Make a new "Find remote keys" dialog */
+ catalog = seahorse_action_group_get_catalog (actions);
+ search_dialog = seahorse_keyserver_search_new (GTK_WINDOW (catalog));
+
+ /* Run it and get the search text */
+ g_signal_connect (search_dialog, "response",
+ G_CALLBACK (on_keyserver_search_response),
+ g_steal_pointer (&catalog));
+ gtk_window_present (GTK_WINDOW (search_dialog));
+
+ g_clear_object (&catalog);
}
static void
@@ -101,30 +110,32 @@ on_remote_sync (GSimpleAction *action,
{
SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
g_autoptr(SeahorseCatalog) catalog = NULL;
- g_autoptr(GList) keys = NULL;
+ g_autoptr(GListModel) keys = NULL;
SeahorseKeyserverSync *dialog = NULL;
catalog = seahorse_action_group_get_catalog (actions);
if (catalog != NULL) {
g_autoptr(GList) objects = NULL;
+ keys = g_list_store_new (SEAHORSE_PGP_TYPE_KEY);
objects = seahorse_catalog_get_selected_objects (catalog);
for (GList *l = objects; l != NULL; l = g_list_next (l)) {
if (SEAHORSE_PGP_IS_KEY (l->data))
- keys = g_list_prepend (keys, l->data);
+ g_list_store_append (keys, l->data);
}
}
- if (keys == NULL) {
+ if (keys == NULL || g_list_model_get_n_items (keys) == 0) {
SeahorseGpgmeKeyring *keyring;
+ g_clear_object (&keys);
keyring = seahorse_pgp_backend_get_default_keyring (NULL);
- keys = gcr_collection_get_objects (GCR_COLLECTION (keyring));
+ keys = g_object_ref (G_LIST_MODEL (keyring));
}
dialog = seahorse_keyserver_sync_new (keys, GTK_WINDOW (catalog));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
#endif /* WITH_KEYSERVER */
@@ -134,21 +145,21 @@ on_pgp_generate_key (GSimpleAction *action,
GVariant *param,
gpointer user_data)
{
- SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
- SeahorseGpgmeKeyring* keyring;
- SeahorseCatalog *catalog;
- GtkDialog *dialog;
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
+ SeahorseGpgmeKeyring* keyring;
+ SeahorseCatalog *catalog;
+ GtkDialog *dialog;
- keyring = seahorse_pgp_backend_get_default_keyring (NULL);
- g_return_if_fail (keyring != NULL);
+ keyring = seahorse_pgp_backend_get_default_keyring (NULL);
+ g_return_if_fail (keyring != NULL);
- catalog = seahorse_action_group_get_catalog (actions);
+ catalog = seahorse_action_group_get_catalog (actions);
- dialog = seahorse_gpgme_generate_dialog_new (keyring, GTK_WINDOW (catalog));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ dialog = seahorse_gpgme_generate_dialog_new (keyring, GTK_WINDOW (catalog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
- g_clear_object (&catalog);
+ g_clear_object (&catalog);
}
static const GActionEntry ACTION_ENTRIES[] = {
diff --git a/pgp/seahorse-pgp-backend.c b/pgp/seahorse-pgp-backend.c
index 1ffd889a..f93427a8 100644
--- a/pgp/seahorse-pgp-backend.c
+++ b/pgp/seahorse-pgp-backend.c
@@ -68,10 +68,10 @@ static GParamSpec *obj_props[N_PROPS] = { NULL, };
static void seahorse_pgp_backend_iface (SeahorseBackendIface *iface);
-static void seahorse_pgp_backend_collection_init (GcrCollectionIface *iface);
+static void seahorse_pgp_backend_list_model_init (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorsePgpBackend, seahorse_pgp_backend, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_pgp_backend_collection_init);
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, seahorse_pgp_backend_list_model_init);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_BACKEND, seahorse_pgp_backend_iface);
);
@@ -326,33 +326,32 @@ seahorse_pgp_backend_class_init (SeahorsePgpBackendClass *klass)
g_object_class_override_property (gobject_class, PROP_LOADED, "loaded");
}
-static guint
-seahorse_pgp_backend_get_length (GcrCollection *collection)
+static GType
+seahorse_pgp_backend_get_item_type (GListModel *model)
{
- return 1;
+ return SEAHORSE_TYPE_GPGME_KEYRING;
}
-static GList *
-seahorse_pgp_backend_get_objects (GcrCollection *collection)
+static unsigned int
+seahorse_pgp_backend_get_n_items (GListModel *model)
{
- SeahorsePgpBackend *self = SEAHORSE_PGP_BACKEND (collection);
- return g_list_append (NULL, self->keyring);
+ return 1;
}
-static gboolean
-seahorse_pgp_backend_contains (GcrCollection *collection,
- GObject *object)
+static void *
+seahorse_pgp_backend_get_item (GListModel *model,
+ unsigned int position)
{
- SeahorsePgpBackend *self = SEAHORSE_PGP_BACKEND (collection);
- return G_OBJECT (self->keyring) == object;
+ SeahorsePgpBackend *self = SEAHORSE_PGP_BACKEND (model);
+ return (position == 0)? g_object_ref (self->keyring) : NULL;
}
static void
-seahorse_pgp_backend_collection_init (GcrCollectionIface *iface)
+seahorse_pgp_backend_list_model_init (GListModelInterface *iface)
{
- iface->contains = seahorse_pgp_backend_contains;
- iface->get_length = seahorse_pgp_backend_get_length;
- iface->get_objects = seahorse_pgp_backend_get_objects;
+ iface->get_item_type = seahorse_pgp_backend_get_item_type;
+ iface->get_n_items = seahorse_pgp_backend_get_n_items;
+ iface->get_item = seahorse_pgp_backend_get_item;
}
static SeahorsePlace *
@@ -574,8 +573,8 @@ on_source_search_ready (GObject *source,
void
seahorse_pgp_backend_search_remote_async (SeahorsePgpBackend *self,
- const gchar *search,
- GcrSimpleCollection *results,
+ const char *search,
+ GListStore *results,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -585,8 +584,9 @@ seahorse_pgp_backend_search_remote_async (SeahorsePgpBackend *self,
g_autoptr(GHashTable) servers = NULL;
g_auto(GStrv) names = NULL;
- self = self ? self : seahorse_pgp_backend_get ();
g_return_if_fail (SEAHORSE_PGP_IS_BACKEND (self));
+ g_return_if_fail (search);
+ g_return_if_fail (G_IS_LIST_STORE (results));
/* Get a list of all selected key servers */
names = seahorse_app_settings_get_last_search_servers (seahorse_app_settings_instance ());
@@ -670,7 +670,7 @@ on_source_transfer_ready (GObject *source,
void
seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
- GList *keys,
+ GListModel *keys,
SeahorsePlace *to,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -681,7 +681,6 @@ seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
g_autoptr(GTask) task = NULL;
SeahorsePlace *from;
- self = self ? self : seahorse_pgp_backend_get ();
g_return_if_fail (SEAHORSE_PGP_IS_BACKEND (self));
g_return_if_fail (SEAHORSE_IS_PLACE (to));
@@ -689,6 +688,8 @@ seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
closure = g_new0 (transfer_closure, 1);
g_task_set_task_data (task, closure, transfer_closure_free);
+ // XXX
+#if 0
keys = g_list_copy (keys);
/* Sort by key place */
keys = seahorse_util_objects_sort_by_place (keys);
@@ -717,6 +718,7 @@ seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
g_list_free (keys);
keys = next;
}
+#endif
if (closure->num_transfers == 0)
g_task_return_boolean (task, TRUE);
diff --git a/pgp/seahorse-pgp-backend.h b/pgp/seahorse-pgp-backend.h
index 5f6a369a..fd570a1d 100644
--- a/pgp/seahorse-pgp-backend.h
+++ b/pgp/seahorse-pgp-backend.h
@@ -68,8 +68,8 @@ void seahorse_pgp_backend_remove_remote (SeahorsePgpBac
const char *uri);
void seahorse_pgp_backend_search_remote_async (SeahorsePgpBackend *self,
- const gchar *search,
- GcrSimpleCollection *results,
+ const char *search,
+ GListStore *results,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -78,12 +78,12 @@ gboolean seahorse_pgp_backend_search_remote_finish (SeahorsePgpBac
GAsyncResult *result,
GError **error);
-void seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
- GList *keys,
- SeahorsePlace *to,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
+ GListModel *keys,
+ SeahorsePlace *to,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ void *user_data);
gboolean seahorse_pgp_backend_transfer_finish (SeahorsePgpBackend *self,
GAsyncResult *result,
diff --git a/pgp/seahorse-pgp-key-properties.c b/pgp/seahorse-pgp-key-properties.c
index 4c308195..eeabe985 100644
--- a/pgp/seahorse-pgp-key-properties.c
+++ b/pgp/seahorse-pgp-key-properties.c
@@ -73,7 +73,6 @@ struct _SeahorsePgpKeyProperties {
GtkWidget *expired_message;
GtkImage *photoid;
- GtkEventBox *photo_event_box;
GtkWidget *name_label;
GtkWidget *email_label;
@@ -125,59 +124,6 @@ on_uids_add (GSimpleAction *action, GVariant *param, void *user_data)
GTK_WINDOW (self));
}
-/* drag-n-drop uri data */
-enum {
- TARGET_URI,
-};
-
-static GtkTargetEntry target_list[] = {
- { "text/uri-list", 0, TARGET_URI } };
-
-static void
-on_pgp_owner_photo_drag_received (GtkWidget *widget,
- GdkDragContext *context,
- int x,
- int y,
- GtkSelectionData *sel_data,
- unsigned int target_type,
- unsigned int time,
- void *user_data)
-{
- SeahorsePgpKeyProperties *self = SEAHORSE_PGP_KEY_PROPERTIES (user_data);
- gboolean dnd_success = FALSE;
- int len = 0;
-
- g_return_if_fail (SEAHORSE_GPGME_IS_KEY (self->key));
-
- /*
- * This needs to be improved, support should be added for remote images
- * and there has to be a better way to get rid of the trailing \r\n appended
- * to the end of the path after the call to g_filename_from_uri
- */
- if ((sel_data != NULL) && (gtk_selection_data_get_length (sel_data) >= 0)) {
- g_auto(GStrv) uri_list = NULL;
-
- g_return_if_fail (target_type == TARGET_URI);
-
- uri_list = gtk_selection_data_get_uris (sel_data);
- while (uri_list && uri_list[len]) {
- g_autofree char *uri = NULL;
-
- uri = g_filename_from_uri (uri_list[len], NULL, NULL);
- if (!uri)
- continue;
-
- dnd_success = seahorse_gpgme_photo_add (SEAHORSE_GPGME_KEY (self->key),
- GTK_WINDOW (self), uri);
- if (!dnd_success)
- break;
- len++;
- }
- }
-
- gtk_drag_finish (context, dnd_success, FALSE, time);
-}
-
static void
on_photos_add (GSimpleAction *action, GVariant *param, void *user_data)
{
@@ -343,32 +289,6 @@ on_photos_previous (GSimpleAction *action, GVariant *param, void *user_data)
set_photoid_state (self);
}
-static void
-on_pgp_owner_photoid_button (GtkWidget *widget,
- GdkEvent *event,
- void *user_data)
-{
- SeahorsePgpKeyProperties *self = SEAHORSE_PGP_KEY_PROPERTIES (user_data);
- const char *action_str;
-
- if (event->type != GDK_SCROLL)
- return;
-
- switch (((GdkEventScroll *) event)->direction) {
- case GDK_SCROLL_UP:
- action_str = "photos.previous";
- break;
- case GDK_SCROLL_DOWN:
- action_str = "photos.next";
- break;
- default:
- return;
- }
-
- g_action_group_activate_action (G_ACTION_GROUP (self->action_group),
- action_str, NULL);
-}
-
static void
on_gpgme_key_change_pass_done (GObject *source,
GAsyncResult *res,
@@ -408,19 +328,17 @@ setup_titlebar (SeahorsePgpKeyProperties *self)
{
const char *name;
GtkWidget *headerbar;
- GtkWidget *menu_icon;
GtkWidget *menu_button;
g_autofree char *title = NULL;
+ GtkWidget *title_widget;
name = seahorse_pgp_key_get_primary_name (self->key);
headerbar = gtk_header_bar_new ();
- gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headerbar), TRUE);
- gtk_widget_show (headerbar);
+ gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
menu_button = gtk_menu_button_new ();
- menu_icon = gtk_image_new_from_icon_name ("open-menu-symbolic", GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (menu_button), menu_icon);
+ gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (menu_button), "open-menu-symbolic");
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menu_button), self->actions_menu);
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), menu_button);
@@ -434,7 +352,8 @@ setup_titlebar (SeahorsePgpKeyProperties *self)
title = g_strdup_printf (_("%s — Public key"), name);
gtk_widget_hide (menu_button);
}
- gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), title);
+ title_widget = adw_window_title_new (title, "");
+ gtk_header_bar_set_title_widget (GTK_HEADER_BAR (headerbar), title_widget);
gtk_window_set_titlebar (GTK_WINDOW (self), headerbar);
}
@@ -551,34 +470,41 @@ on_add_subkey_completed (GObject *object, GAsyncResult *res, void *user_data)
}
static void
-on_subkeys_add (GSimpleAction *action, GVariant *param, void *user_data)
+on_add_subkey_response (GtkDialog *dialog, int response, void *user_data)
{
SeahorsePgpKeyProperties *self = SEAHORSE_PGP_KEY_PROPERTIES (user_data);
- SeahorseGpgmeAddSubkey *dialog;
- int response;
+ SeahorseGpgmeAddSubkey *add_dialog = SEAHORSE_GPGME_ADD_SUBKEY (dialog);
SeahorseKeyEncType type;
unsigned int length;
GDateTime *expires;
- g_return_if_fail (SEAHORSE_GPGME_IS_KEY (self->key));
-
- dialog = seahorse_gpgme_add_subkey_new (SEAHORSE_GPGME_KEY (self->key),
- GTK_WINDOW (self));
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ gtk_window_destroy (GTK_WINDOW (add_dialog));
return;
}
- length = seahorse_gpgme_add_subkey_get_keysize (dialog);
- type = seahorse_gpgme_add_subkey_get_active_type (dialog);
- expires = seahorse_gpgme_add_subkey_get_expires (dialog);
+ length = seahorse_gpgme_add_subkey_get_keysize (add_dialog);
+ type = seahorse_gpgme_add_subkey_get_active_type (add_dialog);
+ expires = seahorse_gpgme_add_subkey_get_expires (add_dialog);
seahorse_gpgme_key_op_add_subkey_async (SEAHORSE_GPGME_KEY (self->key),
type, length, expires, NULL,
on_add_subkey_completed, self);
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ gtk_window_destroy (GTK_WINDOW (add_dialog));
+}
+
+static void
+on_subkeys_add (GSimpleAction *action, GVariant *param, void *user_data)
+{
+ SeahorsePgpKeyProperties *self = SEAHORSE_PGP_KEY_PROPERTIES (user_data);
+ SeahorseGpgmeAddSubkey *dialog;
+
+ g_return_if_fail (SEAHORSE_GPGME_IS_KEY (self->key));
+
+ dialog = seahorse_gpgme_add_subkey_new (SEAHORSE_GPGME_KEY (self->key),
+ GTK_WINDOW (self));
+ g_signal_connect (dialog, "response", G_CALLBACK (on_add_subkey_response), self);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
@@ -671,8 +597,8 @@ on_change_expires (GSimpleAction *action, GVariant *param, void *user_data)
g_return_if_fail (subkey);
dialog = seahorse_gpgme_expires_dialog_new (subkey, GTK_WINDOW (self));
- gtk_dialog_run (dialog);
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
@@ -792,9 +718,8 @@ on_sign_key (GSimpleAction *action, GVariant *param, void *user_data)
g_return_if_fail (SEAHORSE_GPGME_IS_KEY (self->key));
dialog = seahorse_gpgme_sign_dialog_new (SEAHORSE_OBJECT (self->key));
-
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static gboolean
@@ -931,44 +856,36 @@ get_common_widgets (SeahorsePgpKeyProperties *self, GtkBuilder *builder)
self->expired_area = GTK_WIDGET (gtk_builder_get_object (builder, "expired_area"));
self->expired_message = GTK_WIDGET (gtk_builder_get_object (builder, "expired_message"));
self->photoid = GTK_IMAGE (gtk_builder_get_object (builder, "photoid"));
- self->photo_event_box = GTK_EVENT_BOX (gtk_builder_get_object (builder, "photo-event-box"));
self->ownertrust_combobox = GTK_WIDGET (gtk_builder_get_object (builder, "ownertrust_combobox"));
self->uids_container = GTK_WIDGET (gtk_builder_get_object (builder, "uids_container"));
self->subkeys_container = GTK_WIDGET (gtk_builder_get_object (builder, "subkeys_container"));
- g_signal_connect_object (self->photo_event_box, "scroll-event",
- G_CALLBACK (on_pgp_owner_photoid_button),
- self, 0);
g_signal_connect_object (self->ownertrust_combobox, "changed",
G_CALLBACK (on_pgp_details_trust_changed),
self, 0);
uids_listbox = seahorse_pgp_uid_list_box_new (self->key);
- gtk_widget_show (uids_listbox);
- gtk_container_add (GTK_CONTAINER (self->uids_container),
- uids_listbox);
+ gtk_box_append (GTK_BOX (self->uids_container), uids_listbox);
subkeys_listbox = seahorse_pgp_subkey_list_box_new (self->key);
- gtk_widget_show (subkeys_listbox);
- gtk_container_add (GTK_CONTAINER (self->subkeys_container),
- subkeys_listbox);
+ gtk_box_append (GTK_BOX (self->subkeys_container), subkeys_listbox);
}
static void
create_public_key_dialog (SeahorsePgpKeyProperties *self)
{
g_autoptr(GtkBuilder) builder = NULL;
- GtkWidget *content_area, *content;
+ GtkWidget *content;
const char *user;
g_autofree char *sign_text = NULL;
g_autofree char *revoke_text = NULL;
builder = gtk_builder_new_from_resource (PUBLIC_KEY_PROPERTIES_UI);
- gtk_builder_connect_signals (builder, self);
+ // XXX
+ //gtk_builder_connect_signals (builder, self);
- content_area = gtk_dialog_get_content_area (GTK_DIALOG (self));
content = GTK_WIDGET (gtk_builder_get_object (builder, "window_content"));
- gtk_container_add (GTK_CONTAINER (content_area), content);
+ gtk_window_set_child (GTK_WINDOW (self), content);
g_action_map_add_action_entries (G_ACTION_MAP (self->action_group),
PUBLIC_KEY_ACTIONS,
@@ -995,28 +912,27 @@ create_public_key_dialog (SeahorsePgpKeyProperties *self)
user = seahorse_object_get_label (SEAHORSE_OBJECT (self->key));
sign_text = g_strdup_printf(_("I believe “%s” is the owner of this key"),
- user);
- hdy_action_row_set_subtitle (HDY_ACTION_ROW (self->trust_sign_row), sign_text);
- hdy_action_row_set_subtitle_lines (HDY_ACTION_ROW (self->trust_sign_row), 0);
+ user);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (self->trust_sign_row), sign_text);
+ adw_action_row_set_subtitle_lines (ADW_ACTION_ROW (self->trust_sign_row), 0);
revoke_text = g_strdup_printf(_("I no longer trust that “%s” owns this key"),
user);
- hdy_action_row_set_subtitle (HDY_ACTION_ROW (self->trust_revoke_row), revoke_text);
- hdy_action_row_set_subtitle_lines (HDY_ACTION_ROW (self->trust_revoke_row), 0);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (self->trust_revoke_row), revoke_text);
+ adw_action_row_set_subtitle_lines (ADW_ACTION_ROW (self->trust_revoke_row), 0);
}
static void
create_private_key_dialog (SeahorsePgpKeyProperties *self)
{
g_autoptr(GtkBuilder) builder = NULL;
- GtkWidget *content_area, *content;
+ GtkWidget *content;
builder = gtk_builder_new_from_resource (PRIVATE_KEY_PROPERTIES_UI);
- content_area = gtk_dialog_get_content_area (GTK_DIALOG (self));
content = GTK_WIDGET (gtk_builder_get_object (builder, "window_content"));
self->actions_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "actions_menu"));
- gtk_container_add (GTK_CONTAINER (content_area), content);
+ gtk_window_set_child (GTK_WINDOW (self), content);
g_action_map_add_action_entries (G_ACTION_MAP (self->action_group),
PRIVATE_KEY_ACTIONS,
@@ -1036,15 +952,6 @@ create_private_key_dialog (SeahorsePgpKeyProperties *self)
setup_trust_combobox (self);
do_owner (self);
do_details (self);
-
- /* Allow DnD on the photo frame */
- g_signal_connect_object (self->owner_photo_frame, "drag-data-received",
- G_CALLBACK (on_pgp_owner_photo_drag_received),
- self, 0);
- gtk_drag_dest_set (self->owner_photo_frame,
- GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
- target_list, G_N_ELEMENTS (target_list),
- GDK_ACTION_COPY);
}
static void
@@ -1119,7 +1026,6 @@ seahorse_pgp_key_properties_init (SeahorsePgpKeyProperties *self)
self->action_group = g_simple_action_group_new ();
gtk_window_set_default_size (GTK_WINDOW (self), 300, 600);
- gtk_container_set_border_width (GTK_CONTAINER (self), 0);
}
static void
diff --git a/pgp/seahorse-pgp-key.c b/pgp/seahorse-pgp-key.c
index e1871f97..5154d4f9 100644
--- a/pgp/seahorse-pgp-key.c
+++ b/pgp/seahorse-pgp-key.c
@@ -253,13 +253,15 @@ seahorse_pgp_key_realize (SeahorsePgpKey *self)
g_object_get (self, "usage", &usage, NULL);
/* The type */
- if (usage == SEAHORSE_USAGE_PRIVATE_KEY) {
- icon_name = GCR_ICON_KEY_PAIR;
- } else {
- icon_name = GCR_ICON_KEY;
- if (usage == SEAHORSE_USAGE_NONE)
- g_object_set (self, "usage", SEAHORSE_USAGE_PUBLIC_KEY, NULL);
- }
+ // XXX
+ icon_name = "missing-icon";
+ /* if (usage == SEAHORSE_USAGE_PRIVATE_KEY) { */
+ /* icon_name = GCR_ICON_KEY_PAIR; */
+ /* } else { */
+ /* icon_name = GCR_ICON_KEY; */
+ /* if (usage == SEAHORSE_USAGE_NONE) */
+ /* g_object_set (self, "usage", SEAHORSE_USAGE_PUBLIC_KEY, NULL); */
+ /* } */
icon = g_themed_icon_new (icon_name);
g_object_set (self,
diff --git a/pgp/seahorse-pgp-keysets.c b/pgp/seahorse-pgp-keysets.c
index b2703ea8..35007586 100644
--- a/pgp/seahorse-pgp-keysets.c
+++ b/pgp/seahorse-pgp-keysets.c
@@ -35,53 +35,55 @@
static void
on_settings_default_key_changed (GSettings *settings, const gchar *key, gpointer user_data)
{
- /* Default key changed, refresh */
- gcr_filter_collection_refilter (GCR_FILTER_COLLECTION (user_data));
+ GtkFilter *filter = GTK_FILTER (user_data);
+
+ /* Default key changed, refresh */
+ gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static gboolean
pgp_signers_match (GObject *obj,
gpointer data)
{
- SeahorsePgpKey *defkey;
- SeahorseUsage usage;
- SeahorseFlags flags;
-
- if (!SEAHORSE_GPGME_IS_KEY (obj))
- return FALSE;
-
- g_object_get (obj, "usage", &usage, "object-flags", &flags, NULL);
- if (usage != SEAHORSE_USAGE_PRIVATE_KEY)
- return FALSE;
- if (!(flags & SEAHORSE_FLAG_CAN_SIGN))
- return FALSE;
- if (flags & (SEAHORSE_FLAG_EXPIRED | SEAHORSE_FLAG_REVOKED | SEAHORSE_FLAG_DISABLED))
- return FALSE;
-
- defkey = seahorse_pgp_backend_get_default_key (NULL);
-
- /* Default key overrides all, and becomes the only signer available*/
- if (defkey != NULL &&
- g_strcmp0 (seahorse_pgp_key_get_keyid (defkey),
- seahorse_pgp_key_get_keyid (SEAHORSE_PGP_KEY (obj))) != 0)
- return FALSE;
-
- return TRUE;
+ SeahorsePgpKey *defkey;
+ SeahorseUsage usage;
+ SeahorseFlags flags;
+
+ if (!SEAHORSE_GPGME_IS_KEY (obj))
+ return FALSE;
+
+ g_object_get (obj, "usage", &usage, "object-flags", &flags, NULL);
+ if (usage != SEAHORSE_USAGE_PRIVATE_KEY)
+ return FALSE;
+ if (!(flags & SEAHORSE_FLAG_CAN_SIGN))
+ return FALSE;
+ if (flags & (SEAHORSE_FLAG_EXPIRED | SEAHORSE_FLAG_REVOKED | SEAHORSE_FLAG_DISABLED))
+ return FALSE;
+
+ defkey = seahorse_pgp_backend_get_default_key (NULL);
+
+ /* Default key overrides all, and becomes the only signer available*/
+ if (defkey != NULL &&
+ g_strcmp0 (seahorse_pgp_key_get_keyid (defkey),
+ seahorse_pgp_key_get_keyid (SEAHORSE_PGP_KEY (obj))) != 0)
+ return FALSE;
+
+ return TRUE;
}
-GcrCollection *
+GListModel *
seahorse_keyset_pgp_signers_new (void)
{
- GcrCollection *collection;
- SeahorseGpgmeKeyring *keyring;
+ SeahorseGpgmeKeyring *keyring;
+ g_autoptr(GtkCustomFilter) filter = NULL;
+ GtkFilterListModel *model;
- keyring = seahorse_pgp_backend_get_default_keyring (NULL);
- collection = gcr_filter_collection_new_with_callback (GCR_COLLECTION (keyring),
- pgp_signers_match,
- NULL, NULL);
+ keyring = seahorse_pgp_backend_get_default_keyring (NULL);
+ filter = gtk_custom_filter_new (pgp_signers_match, NULL, NULL);
+ model = gtk_filter_list_model_new (G_LIST_MODEL (keyring), g_steal_pointer (&filter));
- g_signal_connect_object (seahorse_pgp_settings_instance (), "changed::default-key",
- G_CALLBACK (on_settings_default_key_changed), collection, 0);
+ g_signal_connect_object (seahorse_pgp_settings_instance (), "changed::default-key",
+ G_CALLBACK (on_settings_default_key_changed), filter, 0);
- return collection;
+ return G_LIST_MODEL (model);
}
diff --git a/pgp/seahorse-pgp-keysets.h b/pgp/seahorse-pgp-keysets.h
index 65bfe522..dc31149f 100644
--- a/pgp/seahorse-pgp-keysets.h
+++ b/pgp/seahorse-pgp-keysets.h
@@ -2,6 +2,7 @@
* Seahorse
*
* Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2022 Niels De Graef
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@@ -18,15 +19,8 @@
* <http://www.gnu.org/licenses/>.
*/
-#ifndef SEAPGPKEYSETS_H_
-#define SEAPGPKEYSETS_H_
+#pragma once
-#include <gcr/gcr.h>
+#include <gio/gio.h>
-/* -----------------------------------------------------------------------------
- * SOME COMMON KEYSETS
- */
-
-GcrCollection * seahorse_keyset_pgp_signers_new (void);
-
-#endif /*SEAPGPKEYSETS_H_*/
+GListModel * seahorse_keyset_pgp_signers_new (void);
diff --git a/pgp/seahorse-pgp-private-key-properties.ui b/pgp/seahorse-pgp-private-key-properties.ui
index 857012c9..90ed423e 100644
--- a/pgp/seahorse-pgp-private-key-properties.ui
+++ b/pgp/seahorse-pgp-private-key-properties.ui
@@ -1,6 +1,5 @@
<?xml version="1.0"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<object class="GtkListStore" id="model1">
<columns>
<!-- column-name gchararray -->
@@ -43,104 +42,69 @@
</section>
</menu>
<object class="GtkBox" id="window_content">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="revoked_area">
- <property name="visible">True</property>
<property name="message-type">error</property>
- <property name="spacing">6</property>
- <child internal-child="content_area">
- <object class="GtkContainer">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">The owner of the key revoked the key. It
should no longer be used.</property>
- <property name="margin-start">12</property>
- </object>
- </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The owner of the key revoked the key. It should no
longer be used.</property>
+ <property name="margin-start">12</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkInfoBar" id="expired_area">
- <property name="spacing">12</property>
<property name="message-type">error</property>
- <property name="orientation">horizontal</property>
- <child internal-child="content_area">
- <object class="GtkContainer">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="expired_message">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="margin-start">12</property>
- <property name="label">This key expired on (placeholder)</property>
- </object>
- </child>
+ <child>
+ <object class="GtkLabel" id="expired_message">
+ <property name="xalign">0</property>
+ <property name="margin-start">12</property>
+ <property name="label">This key expired on (placeholder)</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="propagate-natural-height">True</property>
<property name="vscrollbar-policy">automatic</property>
<property name="hscrollbar-policy">never</property>
<child>
- <object class="HdyClamp">
- <property name="visible">True</property>
+ <object class="AdwClamp">
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">18</property>
- <property name="margin">18</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<child>
<object class="GtkBox" id="owner-photo-frame">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
- <property name="margin">6</property>
<property name="margin-top">0</property>
<child>
- <object class="GtkEventBox" id="photo-event-box">
- <property name="visible">True</property>
- <child>
- <object class="GtkImage" id="photoid">
- <property name="width_request">150</property>
- <property name="height_request">160</property>
- <property name="visible">True</property>
- <property name="icon-name">avatar-default-symbolic</property>
- <property name="icon-size">6</property>
- </object>
- </child>
+ <object class="GtkImage" id="photoid">
+ <property name="width_request">150</property>
+ <property name="height_request">160</property>
+ <property name="icon-name">avatar-default-symbolic</property>
</object>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="owner-photo-add-button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.photos.add</property>
<property name="tooltip-text" translatable="yes">Add a photo to this
key</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
@@ -148,14 +112,11 @@
</child>
<child>
<object class="GtkButton" id="owner-photo-delete-button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.photos.delete</property>
<property name="tooltip-text" translatable="yes">Remove this photo from
this key</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">list-remove-symbolic</property>
</object>
</child>
@@ -163,14 +124,11 @@
</child>
<child>
<object class="GtkButton" id="owner-photo-primary-button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.photos.make-primary</property>
<property name="tooltip-text" translatable="yes">Make this photo the
primary photo</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">emblem-default-symbolic</property>
</object>
</child>
@@ -178,20 +136,16 @@
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="photo_previous_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<property name="action-name">props.photos.previous</property>
<property name="tooltip-text" translatable="yes">Go to previous
photo</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">go-previous-symbolic</property>
</object>
</child>
@@ -199,14 +153,11 @@
</child>
<child>
<object class="GtkButton" id="photo_next_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.photos.next</property>
<property name="tooltip-text" translatable="yes">Go to next
photo</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
@@ -218,20 +169,15 @@
</child>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
- <property name="border_width">3</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="margin-bottom">12</property>
<child>
<object class="GtkLabel" id="name_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<attributes>
@@ -241,19 +187,17 @@
</child>
<child>
<object class="GtkLabel" id="email_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="use-markup">True</property>
</object>
</child>
+ <layout>
+ <property name="row">0</property>
+ <property name="column">0</property>
+ <property name="column-span">2</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- <property name="width">2</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
@@ -263,70 +207,62 @@
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="comment_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">1</property>
+ </layout>
</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="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Key ID</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="keyid_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">1</property>
+ </layout>
</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="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Fingerprint</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="fingerprint_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="wrap">True</property>
@@ -334,46 +270,39 @@
<property name="max-width-chars">24</property>
<property name="width-chars">24</property>
<property name="lines">2</property>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Expires</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">4</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="expires_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkButton" id="details_expires_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.change-expires</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon_name">x-office-calendar-symbolic</property>
</object>
</child>
@@ -382,11 +311,11 @@
</style>
</object>
</child>
+ <layout>
+ <property name="row">4</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">1</property>
- </packing>
</child>
</object>
</child>
@@ -394,16 +323,13 @@
</child>
<child>
<object class="GtkBox" id="uids_container">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">User IDs</property>
<attributes>
@@ -413,16 +339,11 @@
</child>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.uids.add</property>
<property name="use-underline">True</property>
<property name="label" translatable="yes">Add user ID</property>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
@@ -430,16 +351,13 @@
</child>
<child>
<object class="GtkBox" id="subkeys_container">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Subkeys</property>
@@ -450,8 +368,6 @@
</child>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.subkeys.add</property>
<property name="use-underline">True</property>
@@ -464,13 +380,10 @@
</child>
<child>
<object class="GtkBox" id="trust_section">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Trust</property>
@@ -482,20 +395,16 @@
</child>
<child>
<object class="GtkListBox">
- <property name="visible">True</property>
<property name="selection-mode">none</property>
<style>
<class name="content"/>
</style>
<child>
- <object class="HdyActionRow" id="indicate_trust_row">
- <property name="visible">True</property>
+ <object class="AdwActionRow" id="indicate_trust_row">
<property name="title" translatable="yes">Override owner trust</property>
<child>
<object class="GtkComboBox" id="ownertrust_combobox">
- <property name="visible">True</property>
<property name="valign">center</property>
- <property name="can_focus">False</property>
<property name="model">model1</property>
<child>
<object class="GtkCellRendererText"/>
diff --git a/pgp/seahorse-pgp-public-key-properties.ui b/pgp/seahorse-pgp-public-key-properties.ui
index 18eec594..51f90e74 100644
--- a/pgp/seahorse-pgp-public-key-properties.ui
+++ b/pgp/seahorse-pgp-public-key-properties.ui
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<object class="GtkListStore" id="model1">
<columns>
<!-- column-name gchararray -->
@@ -25,107 +24,70 @@
</data>
</object>
<object class="GtkBox" id="window_content">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="revoked_area">
- <property name="visible">True</property>
<property name="message-type">error</property>
- <property name="spacing">6</property>
- <child internal-child="content_area">
- <object class="GtkContainer">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">The owner of the key revoked the key. It
should no longer be used.</property>
- <property name="margin-start">12</property>
- </object>
- </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The owner of the key revoked the key. It should no
longer be used.</property>
+ <property name="margin-start">12</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkInfoBar" id="expired_area">
- <property name="spacing">12</property>
<property name="message-type">error</property>
- <property name="orientation">horizontal</property>
- <child internal-child="content_area">
- <object class="GtkContainer">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="expired_message">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="margin-start">12</property>
- <property name="label">This key expired on (placeholder)</property>
- </object>
- </child>
+ <child>
+ <object class="GtkLabel" id="expired_message">
+ <property name="xalign">0</property>
+ <property name="margin-start">12</property>
+ <property name="label">This key expired on (placeholder)</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="propagate-natural-height">True</property>
<property name="vscrollbar-policy">automatic</property>
<property name="hscrollbar-policy">never</property>
<child>
- <object class="HdyClamp">
- <property name="visible">True</property>
+ <object class="AdwClamp">
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="can_focus">False</property>
<property name="spacing">18</property>
- <property name="margin">18</property>
<child>
<object class="GtkBox" id="summary_container">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
- <object class="GtkEventBox" id="photo-event-box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkImage" id="photoid">
- <property name="width_request">150</property>
- <property name="height_request">160</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon-name">avatar-default-symbolic</property>
- <property name="icon-size">6</property>
- </object>
- </child>
+ <object class="GtkImage" id="photoid">
+ <property name="width_request">150</property>
+ <property name="height_request">160</property>
+ <property name="icon-name">avatar-default-symbolic</property>
</object>
</child>
<child>
<object class="GtkBox" id="key-controls">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="halign">center</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="photo_previous_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<property name="action-name">props.photos.previous</property>
<property name="tooltip-text" translatable="yes">Go to previous
photo</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">go-previous-symbolic</property>
</object>
</child>
@@ -133,20 +95,15 @@
</child>
<child>
<object class="GtkButton" id="photo_next_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.photos.next</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
- <property name="can_focus">False</property>
<property name="spacing">2</property>
<property name="tooltip-text" translatable="yes">Go to next
photo</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">go-next-symbolic</property>
</object>
</child>
@@ -160,26 +117,19 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin">3</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="margin-bottom">12</property>
<child>
<object class="GtkLabel" id="name_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="halign">start</property>
<property name="selectable">True</property>
<attributes>
@@ -189,94 +139,81 @@
</child>
<child>
<object class="GtkLabel" id="email_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="halign">start</property>
<property name="selectable">True</property>
</object>
</child>
+ <layout>
+ <property name="row">0</property>
+ <property name="column">0</property>
+ <property name="column-span">2</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- <property name="width">2</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible" bind-source="comment_label"
bind-property="visible" bind-flags="sync-create" />
- <property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Comment</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="comment_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">1</property>
+ </layout>
</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="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Key ID</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="keyid_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">1</property>
+ </layout>
</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="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Fingerprint</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="fingerprint_label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="selectable">True</property>
<property name="wrap">True</property>
@@ -284,37 +221,34 @@
<property name="width-chars">24</property>
<property name="max-width-chars">24</property>
<property name="lines">2</property>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Expires</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">4</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="expires_label">
- <property name="visible">True</property>
<property name="xalign">0</property>
+ <layout>
+ <property name="row">4</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">1</property>
- </packing>
</child>
</object>
</child>
@@ -324,12 +258,10 @@
</child>
<child>
<object class="GtkBox" id="uids_container">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">User IDs</property>
<attributes>
@@ -341,16 +273,13 @@
</child>
<child>
<object class="GtkBox" id="subkeys_container">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Subkeys</property>
@@ -365,20 +294,14 @@
</child>
<child>
<object class="GtkBox" id="trust-page">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="can_focus">False</property>
<property name="spacing">24</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Trust</property>
@@ -390,22 +313,18 @@
</child>
<child>
<object class="GtkListBox">
- <property name="visible">True</property>
<property name="selection-mode">none</property>
<style>
<class name="content"/>
</style>
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
+ <object class="AdwActionRow">
<property name="title" translatable="yes">Signature trust</property>
<property name="subtitle" translatable="yes">I trust signatures from
this key on other keys</property>
<child>
<object class="GtkSwitch" id="trust-marginal-switch">
- <property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="action-name">props.trust-marginal</property>
</object>
@@ -413,15 +332,12 @@
</object>
</child>
<child>
- <object class="HdyActionRow" id="trust_sign_row">
- <property name="visible">True</property>
+ <object class="AdwActionRow" id="trust_sign_row">
<property name="title" translatable="yes">Sign key</property>
<child>
<object class="GtkButton" id="sign-button">
- <property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
- <property name="can_focus">True</property>
<property name="label" translatable="yes">_Sign key</property>
<property name="use_underline">True</property>
<property name="receives_default">False</property>
@@ -431,15 +347,12 @@
</object>
</child>
<child>
- <object class="HdyActionRow" id="trust_revoke_row">
- <property name="visible">True</property>
+ <object class="AdwActionRow" id="trust_revoke_row">
<property name="title" translatable="yes">Revoke key signature</property>
<child>
<object class="GtkButton" id="revoke-button">
- <property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
- <property name="can_focus">True</property>
<property name="label" translatable="yes">_Revoke</property>
<property name="use_underline">True</property>
<property name="receives_default">False</property>
@@ -449,15 +362,12 @@
</object>
</child>
<child>
- <object class="HdyActionRow" id="indicate_trust_row">
- <property name="visible">True</property>
+ <object class="AdwActionRow" id="indicate_trust_row">
<property name="title" translatable="yes">Owner trust</property>
<property name="subtitle" translatable="yes">Give a trust level to the
owner of this key</property>
<child>
<object class="GtkComboBox" id="ownertrust_combobox">
- <property name="visible">True</property>
<property name="valign">center</property>
- <property name="can_focus">False</property>
<property name="model">model1</property>
<child>
<object class="GtkCellRendererText"/>
diff --git a/pgp/seahorse-pgp-subkey-list-box-row.ui b/pgp/seahorse-pgp-subkey-list-box-row.ui
index 1caa65a6..47980611 100644
--- a/pgp/seahorse-pgp-subkey-list-box-row.ui
+++ b/pgp/seahorse-pgp-subkey-list-box-row.ui
@@ -17,159 +17,137 @@
</item>
</section>
</menu>
- <template class="SeahorsePgpSubkeyListBoxRow" parent="HdyExpanderRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <template class="SeahorsePgpSubkeyListBoxRow" parent="AdwExpanderRow">
<child type="action">
<object class="GtkImage" id="status_box">
- <property name="visible">True</property>
<property name="icon-name">dialog-warning-symbolic</property>
<style>
<class name="pgp-subkey-status-box"/>
</style>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">2</property>
- </packing>
</child>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
- <property name="margin">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Usages</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">0</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkBox" id="usages_box">
- <property name="visible">True</property>
<property name="spacing">3</property>
<property name="orientation">horizontal</property>
+ <layout>
+ <property name="row">0</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Fingerprint</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="fingerprint_label">
- <property name="visible">True</property>
<property name="selectable">True</property>
<property name="xalign">0</property>
+ <layout>
+ <property name="row">1</property>
+ <property name="column">1</property>
+ </layout>
</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="xalign">1</property>
<property name="label" translatable="yes">Type</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="algo_label">
- <property name="visible">True</property>
<property name="xalign">0</property>
+ <layout>
+ <property name="row">2</property>
+ <property name="column">1</property>
+ </layout>
</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="xalign">1</property>
<property name="label" translatable="yes">Created</property>
<style>
<class name="dim-label"/>
</style>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">0</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
</child>
<child>
<object class="GtkLabel" id="created_label">
- <property name="visible">True</property>
<property name="xalign">0</property>
+ <layout>
+ <property name="row">3</property>
+ <property name="column">1</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
</child>
<child>
<object class="GtkBox" id="action_box">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
- <property name="margin">6</property>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
<property name="label" translatable="yes">Change expiry date</property>
<property name="action-name">subkey.change-expires</property>
</object>
</child>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
<property name="label" translatable="yes">Revoke</property>
<property name="action-name">subkey.revoke</property>
</object>
</child>
<child>
<object class="GtkButton">
- <property name="visible">True</property>
<property name="label" translatable="yes">Delete</property>
<property name="action-name">subkey.delete</property>
</object>
</child>
+ <layout>
+ <property name="row">4</property>
+ <property name="column">0</property>
+ <property name="column-span">2</property>
+ </layout>
</object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">0</property>
- <property name="width">2</property>
- </packing>
</child>
</object>
</child>
diff --git a/pgp/seahorse-pgp-subkey-list-box.c b/pgp/seahorse-pgp-subkey-list-box.c
index 4ee2dc45..b6ec834e 100644
--- a/pgp/seahorse-pgp-subkey-list-box.c
+++ b/pgp/seahorse-pgp-subkey-list-box.c
@@ -29,9 +29,11 @@
#include <glib/gi18n.h>
struct _SeahorsePgpSubkeyListBox {
- GtkListBox parent_instance;
+ AdwBin parent_instance;
SeahorsePgpKey *key;
+
+ GtkWidget *listbox;
};
enum {
@@ -41,7 +43,7 @@ enum {
};
static GParamSpec *obj_props[N_PROPS] = { NULL, };
-G_DEFINE_TYPE (SeahorsePgpSubkeyListBox, seahorse_pgp_subkey_list_box, GTK_TYPE_LIST_BOX)
+G_DEFINE_TYPE (SeahorsePgpSubkeyListBox, seahorse_pgp_subkey_list_box, ADW_TYPE_BIN)
static void
seahorse_pgp_subkey_list_box_set_property (GObject *object,
@@ -53,7 +55,7 @@ seahorse_pgp_subkey_list_box_set_property (GObject *object,
switch (prop_id) {
case PROP_KEY:
- g_set_object (&self->key, g_value_dup_object (value));
+ g_set_object (&self->key, g_value_get_object (value));
break;
}
}
@@ -91,7 +93,7 @@ seahorse_pgp_subkey_list_box_constructed (GObject *obj)
G_OBJECT_CLASS (seahorse_pgp_subkey_list_box_parent_class)->constructed (obj);
- gtk_list_box_bind_model (GTK_LIST_BOX (self),
+ gtk_list_box_bind_model (GTK_LIST_BOX (self->listbox),
seahorse_pgp_key_get_subkeys (self->key),
create_subkey_row,
self,
@@ -101,10 +103,11 @@ seahorse_pgp_subkey_list_box_constructed (GObject *obj)
static void
seahorse_pgp_subkey_list_box_init (SeahorsePgpSubkeyListBox *self)
{
- GtkStyleContext *style_context;
-
- style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
- gtk_style_context_add_class (style_context, "content");
+ self->listbox = gtk_list_box_new ();
+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (self->listbox),
+ GTK_SELECTION_NONE);
+ adw_bin_set_child (ADW_BIN (self), self->listbox);
+ gtk_widget_add_css_class (GTK_WIDGET (self->listbox), "boxed-list");
}
static void
@@ -139,7 +142,6 @@ GtkWidget *
seahorse_pgp_subkey_list_box_new (SeahorsePgpKey *key)
{
return g_object_new (SEAHORSE_PGP_TYPE_SUBKEY_LIST_BOX,
- "selection-mode", GTK_SELECTION_NONE,
"key", key,
NULL);
}
@@ -154,7 +156,7 @@ seahorse_pgp_subkey_list_box_get_key (SeahorsePgpSubkeyListBox *self)
/* SeahorsePhpSubkeyListBoxRow */
struct _SeahorsePgpSubkeyListBoxRow {
- HdyExpanderRow parent_instance;
+ AdwExpanderRow parent_instance;
SeahorsePgpSubkey *subkey;
@@ -175,14 +177,14 @@ enum {
};
static GParamSpec *row_props[ROW_N_PROPS] = { NULL, };
-G_DEFINE_TYPE (SeahorsePgpSubkeyListBoxRow, seahorse_pgp_subkey_list_box_row, HDY_TYPE_EXPANDER_ROW)
+G_DEFINE_TYPE (SeahorsePgpSubkeyListBoxRow, seahorse_pgp_subkey_list_box_row, ADW_TYPE_EXPANDER_ROW)
static GtkWindow *
-get_toplevel_window (SeahorsePgpSubkeyListBoxRow *row)
+get_root (SeahorsePgpSubkeyListBoxRow *row)
{
GtkWidget *toplevel = NULL;
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (row));
+ toplevel = gtk_widget_get_root (GTK_WIDGET (row));
if (GTK_IS_WINDOW (toplevel))
return GTK_WINDOW (toplevel);
@@ -202,12 +204,15 @@ on_subkey_delete (GSimpleAction *action, GVariant *param, void *user_data)
fingerprint = seahorse_pgp_subkey_get_fingerprint (row->subkey);
message = g_strdup_printf (_("Are you sure you want to permanently delete subkey %s?"), fingerprint);
- if (!seahorse_delete_dialog_prompt (get_toplevel_window (row), message))
+ // XXX
+#if 0
+ if (!seahorse_delete_dialog_prompt (get_root (row), message))
return;
err = seahorse_gpgme_key_op_del_subkey (SEAHORSE_GPGME_SUBKEY (row->subkey));
if (!GPG_IS_OK (err))
seahorse_gpgme_handle_error (err, _("Couldn’t delete subkey"));
+#endif
}
static void
@@ -219,9 +224,9 @@ on_subkey_revoke (GSimpleAction *action, GVariant *param, void *user_data)
g_return_if_fail (SEAHORSE_GPGME_IS_SUBKEY (row->subkey));
dialog = seahorse_gpgme_revoke_dialog_new (SEAHORSE_GPGME_SUBKEY (row->subkey),
- get_toplevel_window (row));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ get_root (row));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static void
@@ -233,9 +238,9 @@ on_subkey_change_expires (GSimpleAction *action, GVariant *param, void *user_dat
g_return_if_fail (SEAHORSE_GPGME_IS_SUBKEY (row->subkey));
dialog = seahorse_gpgme_expires_dialog_new (SEAHORSE_GPGME_SUBKEY (row->subkey),
- get_toplevel_window (row));
- gtk_dialog_run (dialog);
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ get_root (row));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static const GActionEntry SUBKEY_ACTIONS[] = {
@@ -276,12 +281,12 @@ update_row (SeahorsePgpSubkeyListBoxRow *row)
}
/* Set the key id */
- hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (row),
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row),
seahorse_pgp_subkey_get_keyid (row->subkey));
expires = seahorse_pgp_subkey_get_expires (row->subkey);
expires_str = expires? g_date_time_format (expires, "Expires on %x")
: g_strdup (_("Never expires"));
- hdy_expander_row_set_subtitle (HDY_EXPANDER_ROW (row), expires_str);
+ adw_expander_row_set_subtitle (ADW_EXPANDER_ROW (row), expires_str);
/* Add the usage tags */
usages = seahorse_pgp_subkey_get_usages (row->subkey, &descriptions);
@@ -291,8 +296,7 @@ update_row (SeahorsePgpSubkeyListBoxRow *row)
label = gtk_label_new (usages[i]);
gtk_widget_set_tooltip_text (label, descriptions[i]);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (row->usages_box), label, FALSE, FALSE, 0);
+ gtk_box_append (GTK_BOX (row->usages_box), label);
gtk_style_context_add_class (gtk_widget_get_style_context (label),
"pgp-subkey-usage-label");
}
diff --git a/pgp/seahorse-pgp-subkey-list-box.h b/pgp/seahorse-pgp-subkey-list-box.h
index 589ac98e..64b03d5e 100644
--- a/pgp/seahorse-pgp-subkey-list-box.h
+++ b/pgp/seahorse-pgp-subkey-list-box.h
@@ -28,7 +28,7 @@
#define SEAHORSE_PGP_TYPE_SUBKEY_LIST_BOX (seahorse_pgp_subkey_list_box_get_type ())
G_DECLARE_FINAL_TYPE (SeahorsePgpSubkeyListBox, seahorse_pgp_subkey_list_box,
SEAHORSE_PGP, SUBKEY_LIST_BOX,
- GtkListBox)
+ AdwBin)
GtkWidget * seahorse_pgp_subkey_list_box_new (SeahorsePgpKey *key);
@@ -37,6 +37,6 @@ SeahorsePgpKey * seahorse_pgp_subkey_list_box_get_key (SeahorsePg
#define SEAHORSE_PGP_TYPE_SUBKEY_LIST_BOX_ROW (seahorse_pgp_subkey_list_box_row_get_type ())
G_DECLARE_FINAL_TYPE (SeahorsePgpSubkeyListBoxRow, seahorse_pgp_subkey_list_box_row,
SEAHORSE_PGP, SUBKEY_LIST_BOX_ROW,
- HdyExpanderRow)
+ AdwExpanderRow)
SeahorsePgpSubkey * seahorse_pgp_subkey_list_box_row_get_subkey (SeahorsePgpSubkeyListBoxRow *self);
diff --git a/pgp/seahorse-pgp-uid-list-box-row.ui b/pgp/seahorse-pgp-uid-list-box-row.ui
index 3b9c313e..3e8c8e40 100644
--- a/pgp/seahorse-pgp-uid-list-box-row.ui
+++ b/pgp/seahorse-pgp-uid-list-box-row.ui
@@ -17,19 +17,16 @@
</item>
</section>
</menu>
- <template class="SeahorsePgpUidListBoxRow" parent="HdyExpanderRow">
- <property name="visible">True</property>
+ <template class="SeahorsePgpUidListBoxRow" parent="AdwExpanderRow">
<property name="focus-on-click">False</property>
<child type="action">
<object class="GtkMenuButton" id="actions_button">
- <property name="visible">True</property>
<property name="valign">center</property>
<property name="halign">end</property>
<property name="margin-start">6</property>
<property name="menu-model">actions_menu</property>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
@@ -40,25 +37,19 @@
</child>
<child type="prefix">
<object class="GtkImage" id="avatar">
- <property name="visible">True</property>
<property name="icon-name">avatar-default-symbolic</property>
- <property name="icon-size">5</property>
</object>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="spacing">12</property>
- <property name="margin">18</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="spacing">6</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="signed_by_label">
- <property name="visible">True</property>
<property name="xalign">0</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Signatures</property>
@@ -72,31 +63,22 @@
</child>
<child>
<object class="GtkSwitch" id="trusted_switch">
- <property name="visible">True</property>
<property name="action-name">uid.only-trusted</property>
<property name="tooltip-text" translatable="yes">Only display the signatures of people I
trust</property>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Only trusted</property>
<property name="tooltip-text" translatable="yes">Only display the signatures of people I
trust</property>
<property name="mnemonic-widget">trusted_switch</property>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
<child>
<object class="GtkListBox" id="signatures_list">
- <property name="visible">True</property>
<property name="selection-mode">none</property>
</object>
</child>
diff --git a/pgp/seahorse-pgp-uid-list-box.c b/pgp/seahorse-pgp-uid-list-box.c
index de5fab10..db183aec 100644
--- a/pgp/seahorse-pgp-uid-list-box.c
+++ b/pgp/seahorse-pgp-uid-list-box.c
@@ -33,9 +33,11 @@
/* ListBox object */
struct _SeahorsePgpUidListBox {
- GtkListBox parent_instance;
+ AdwBin parent_instance;
SeahorsePgpKey *key;
+
+ GtkWidget *listbox;
};
enum {
@@ -45,7 +47,7 @@ enum {
};
static GParamSpec *obj_props[N_PROPS] = { NULL, };
-G_DEFINE_TYPE (SeahorsePgpUidListBox, seahorse_pgp_uid_list_box, GTK_TYPE_LIST_BOX);
+G_DEFINE_TYPE (SeahorsePgpUidListBox, seahorse_pgp_uid_list_box, ADW_TYPE_BIN);
static GtkWidget *
create_row_for_uid (void *item, void *user_data)
@@ -64,7 +66,7 @@ seahorse_pgp_uid_list_box_constructed (GObject *object)
G_OBJECT_CLASS (seahorse_pgp_uid_list_box_parent_class)->constructed (object);
- gtk_list_box_bind_model (GTK_LIST_BOX (self),
+ gtk_list_box_bind_model (GTK_LIST_BOX (self->listbox),
seahorse_pgp_key_get_uids (self->key),
create_row_for_uid,
self,
@@ -74,10 +76,11 @@ seahorse_pgp_uid_list_box_constructed (GObject *object)
static void
seahorse_pgp_uid_list_box_init (SeahorsePgpUidListBox *self)
{
- GtkStyleContext *style_context;
-
- style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
- gtk_style_context_add_class (style_context, "content");
+ self->listbox = gtk_list_box_new ();
+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (self->listbox),
+ GTK_SELECTION_NONE);
+ adw_bin_set_child (ADW_BIN (self), self->listbox);
+ gtk_widget_add_css_class (GTK_WIDGET (self->listbox), "boxed-list");
}
static void
@@ -147,14 +150,13 @@ seahorse_pgp_uid_list_box_new (SeahorsePgpKey *key)
/* XXX We should store the key and connect to ::notify */
return g_object_new (SEAHORSE_PGP_TYPE_UID_LIST_BOX,
"key", key,
- "selection-mode", GTK_SELECTION_NONE,
NULL);
}
/* Row object */
struct _SeahorsePgpUidListBoxRow {
- HdyExpanderRow parent_instance;
+ AdwExpanderRow parent_instance;
SeahorsePgpUid *uid;
@@ -172,7 +174,7 @@ enum {
ROW_N_PROPS
};
-G_DEFINE_TYPE (SeahorsePgpUidListBoxRow, seahorse_pgp_uid_list_box_row, HDY_TYPE_EXPANDER_ROW);
+G_DEFINE_TYPE (SeahorsePgpUidListBoxRow, seahorse_pgp_uid_list_box_row, ADW_TYPE_EXPANDER_ROW);
static void
update_actions (SeahorsePgpUidListBoxRow *row)
@@ -256,16 +258,19 @@ on_uid_delete (GSimpleAction *action, GVariant *param, void *user_data)
g_return_if_fail (SEAHORSE_GPGME_IS_UID (row->uid));
- window = gtk_widget_get_toplevel (GTK_WIDGET (row));
+ window = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (row)));
message = g_strdup_printf (_("Are you sure you want to permanently delete the “%s” user ID?"),
seahorse_object_get_label (SEAHORSE_OBJECT (row->uid)));
+ // XXX
+#if 0
if (!seahorse_delete_dialog_prompt (GTK_WINDOW (window), message))
return;
gerr = seahorse_gpgme_key_op_del_uid (SEAHORSE_GPGME_UID (row->uid));
if (!GPG_IS_OK (gerr))
seahorse_gpgme_handle_error (gerr, _("Couldn’t delete user ID"));
+#endif
}
static void
@@ -292,7 +297,7 @@ on_uid_make_primary (GSimpleAction *action, GVariant *param, void *user_data)
/* Don't pass the row itself as user_data, as that might be destroyed as
* part of the GListModel shuffle */
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (row));
+ toplevel = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (row)));
seahorse_gpgme_key_op_make_primary_async (SEAHORSE_GPGME_UID (row->uid),
NULL,
@@ -309,8 +314,8 @@ on_uid_sign (GSimpleAction *action, GVariant *param, void *user_data)
g_return_if_fail (SEAHORSE_GPGME_IS_UID (row->uid));
dialog = seahorse_gpgme_sign_dialog_new (SEAHORSE_OBJECT (row->uid));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
}
static const GActionEntry UID_ACTION_ENTRIES[] = {
@@ -335,13 +340,11 @@ create_row_for_signature (void *item, void *user_data)
sig_row = gtk_list_box_row_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_widget_show (box);
- gtk_container_add (GTK_CONTAINER (sig_row), box);
+ gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (sig_row), box);
sig_keyid = seahorse_pgp_signature_get_keyid (signature);
keyid_label = gtk_label_new (sig_keyid);
- gtk_widget_show (keyid_label);
- gtk_box_pack_start (GTK_BOX (box), keyid_label, FALSE, FALSE, 0);
+ gtk_box_append (GTK_BOX (box), keyid_label);
for (GList *l = row->discovered_keys; l; l = g_list_next (l)) {
if (SEAHORSE_PGP_IS_KEY (l->data)) {
@@ -373,8 +376,7 @@ create_row_for_signature (void *item, void *user_data)
}
signer_label = gtk_label_new (signer_name);
- gtk_widget_show (signer_label);
- gtk_box_pack_start (GTK_BOX (box), signer_label, FALSE, FALSE, 0);
+ gtk_box_append (GTK_BOX (box), signer_label);
return sig_row;
}
@@ -394,7 +396,7 @@ on_row_expanded (GObject *object,
/* Lazily discover keys by only loading when user actually expands the row
* (showing the signatures) and not reloading if already done earlier */
- expanded = hdy_expander_row_get_expanded (HDY_EXPANDER_ROW (row));
+ expanded = adw_expander_row_get_expanded (ADW_EXPANDER_ROW (row));
if (!expanded || row->discovered_keys)
return;
@@ -445,12 +447,12 @@ update_row (SeahorsePgpUidListBoxRow *row)
comment = seahorse_pgp_uid_get_comment (row->uid);
if (comment && *comment)
g_string_append_printf (title, " (%s)", comment);
- hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (row), title->str);
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), title->str);
/* Make a linkified version the email as subtitle */
email = seahorse_pgp_uid_get_email (row->uid);
if (email && *email)
- hdy_expander_row_set_subtitle (HDY_EXPANDER_ROW (row), email);
+ adw_expander_row_set_subtitle (ADW_EXPANDER_ROW (row), email);
/* Actions */
gtk_widget_set_visible (row->actions_button, is_editable);
diff --git a/pgp/seahorse-pgp-uid-list-box.h b/pgp/seahorse-pgp-uid-list-box.h
index 9079ad4b..641ffa64 100644
--- a/pgp/seahorse-pgp-uid-list-box.h
+++ b/pgp/seahorse-pgp-uid-list-box.h
@@ -26,11 +26,11 @@
#define SEAHORSE_PGP_TYPE_UID_LIST_BOX (seahorse_pgp_uid_list_box_get_type ())
G_DECLARE_FINAL_TYPE (SeahorsePgpUidListBox, seahorse_pgp_uid_list_box,
SEAHORSE_PGP, UID_LIST_BOX,
- GtkListBox)
+ AdwBin)
#define SEAHORSE_PGP_TYPE_UID_LIST_BOX_ROW (seahorse_pgp_uid_list_box_row_get_type ())
G_DECLARE_FINAL_TYPE (SeahorsePgpUidListBoxRow, seahorse_pgp_uid_list_box_row,
SEAHORSE_PGP, UID_LIST_BOX_ROW,
- HdyExpanderRow)
+ AdwExpanderRow)
GtkWidget * seahorse_pgp_uid_list_box_new (SeahorsePgpKey *key);
diff --git a/pgp/seahorse-server-source.c b/pgp/seahorse-server-source.c
index e3170f26..e2ddbc72 100644
--- a/pgp/seahorse-server-source.c
+++ b/pgp/seahorse-server-source.c
@@ -46,13 +46,11 @@ enum {
PROP_0,
PROP_LABEL,
PROP_DESCRIPTION,
- PROP_ICON,
PROP_CATEGORY,
PROP_URI,
PROP_ACTIONS,
PROP_ACTION_PREFIX,
PROP_MENU_MODEL,
- PROP_SHOW_IF_EMPTY,
N_PROPS
};
@@ -65,13 +63,13 @@ typedef struct _SeahorseServerSourcePrivate {
gchar *uri;
} SeahorseServerSourcePrivate;
-static void seahorse_server_source_collection_init (GcrCollectionIface *iface);
+static void seahorse_server_source_list_model_init (GListModelInterface *iface);
static void seahorse_server_source_place_iface (SeahorsePlaceIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (SeahorseServerSource, seahorse_server_source, G_TYPE_OBJECT,
G_ADD_PRIVATE (SeahorseServerSource)
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_server_source_collection_init);
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, seahorse_server_source_list_model_init);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_server_source_place_iface);
);
@@ -91,14 +89,12 @@ seahorse_server_source_class_init (SeahorseServerSourceClass *klass)
gobject_class->set_property = seahorse_server_set_property;
gobject_class->get_property = seahorse_server_get_property;
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
- g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
+ g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+ g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
g_object_class_override_property (gobject_class, PROP_CATEGORY, "category");
- g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
- g_object_class_override_property (gobject_class, PROP_ACTION_PREFIX, "action-prefix");
- g_object_class_override_property (gobject_class, PROP_MENU_MODEL, "menu-model");
- g_object_class_override_property (gobject_class, PROP_SHOW_IF_EMPTY, "show-if-empty");
+ g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
+ g_object_class_override_property (gobject_class, PROP_ACTION_PREFIX, "action-prefix");
+ g_object_class_override_property (gobject_class, PROP_MENU_MODEL, "menu-model");
g_object_class_install_property (gobject_class, PROP_URI,
g_param_spec_string ("uri", "Key Server URI",
@@ -130,7 +126,7 @@ seahorse_server_source_load (SeahorsePlace *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_return_if_reached ();
+ g_return_if_reached ();
}
static gboolean
@@ -138,7 +134,7 @@ seahorse_server_source_load_finish (SeahorsePlace *self,
GAsyncResult *res,
GError **error)
{
- g_return_val_if_reached (FALSE);
+ g_return_val_if_reached (FALSE);
}
static gchar *
@@ -148,7 +144,7 @@ seahorse_server_source_get_label (SeahorsePlace* self)
SeahorseServerSourcePrivate *priv =
seahorse_server_source_get_instance_private (ssrc);
- return g_strdup (priv->server);
+ return g_strdup (priv->server);
}
static void
@@ -163,7 +159,7 @@ seahorse_server_source_get_description (SeahorsePlace* self)
SeahorseServerSourcePrivate *priv =
seahorse_server_source_get_instance_private (ssrc);
- return g_strdup (priv->uri);
+ return g_strdup (priv->uri);
}
static gchar *
@@ -173,13 +169,7 @@ seahorse_server_source_get_uri (SeahorsePlace* self)
SeahorseServerSourcePrivate *priv =
seahorse_server_source_get_instance_private (ssrc);
- return g_strdup (priv->uri);
-}
-
-static GIcon *
-seahorse_server_source_get_icon (SeahorsePlace* self)
-{
- return g_themed_icon_new (NULL);
+ return g_strdup (priv->uri);
}
static SeahorsePlaceCategory
@@ -206,12 +196,6 @@ seahorse_server_source_get_menu_model (SeahorsePlace* self)
return NULL;
}
-static gboolean
-seahorse_server_source_get_show_if_empty (SeahorsePlace *place)
-{
- return TRUE;
-}
-
static void
seahorse_server_source_place_iface (SeahorsePlaceIface *iface)
{
@@ -221,12 +205,10 @@ seahorse_server_source_place_iface (SeahorsePlaceIface *iface)
iface->get_action_prefix = seahorse_server_source_get_action_prefix;
iface->get_menu_model = seahorse_server_source_get_menu_model;
iface->get_description = seahorse_server_source_get_description;
- iface->get_icon = seahorse_server_source_get_icon;
iface->get_category = seahorse_server_source_get_category;
iface->get_label = seahorse_server_source_get_label;
iface->set_label = seahorse_server_source_set_label;
iface->get_uri = seahorse_server_source_get_uri;
- iface->get_show_if_empty = seahorse_server_source_get_show_if_empty;
}
static void
@@ -258,21 +240,18 @@ seahorse_server_get_property (GObject *obj,
GValue *value,
GParamSpec *pspec)
{
- SeahorseServerSource *self = SEAHORSE_SERVER_SOURCE (obj);
- SeahorsePlace *place = SEAHORSE_PLACE (self);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, seahorse_server_source_get_label (place));
- break;
- case PROP_DESCRIPTION:
- g_value_take_string (value, seahorse_server_source_get_description (place));
- break;
- case PROP_URI:
- g_value_take_string (value, seahorse_server_source_get_uri (place));
- break;
- case PROP_ICON:
- g_value_take_object (value, seahorse_server_source_get_icon (place));
+ SeahorseServerSource *self = SEAHORSE_SERVER_SOURCE (obj);
+ SeahorsePlace *place = SEAHORSE_PLACE (self);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_take_string (value, seahorse_server_source_get_label (place));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_take_string (value, seahorse_server_source_get_description (place));
+ break;
+ case PROP_URI:
+ g_value_take_string (value, seahorse_server_source_get_uri (place));
break;
case PROP_CATEGORY:
g_value_set_enum (value, seahorse_server_source_get_category (place));
@@ -286,57 +265,56 @@ seahorse_server_get_property (GObject *obj,
case PROP_MENU_MODEL:
g_value_set_object (value, seahorse_server_source_get_menu_model (place));
break;
- case PROP_SHOW_IF_EMPTY:
- g_value_set_boolean (value, TRUE);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
}
}
-static guint
-seahorse_server_source_get_length (GcrCollection *collection)
+static unsigned int
+seahorse_server_source_get_n_items (GListModel *list)
{
- return 0;
+ return 0;
}
-static GList *
-seahorse_server_source_get_objects (GcrCollection *collection)
+static void *
+seahorse_server_source_get_item (GListModel *list,
+ unsigned int pos)
{
- return NULL;
+ return NULL;
}
-static gboolean
-seahorse_server_source_contains (GcrCollection *collection,
- GObject *object)
+static GType
+seahorse_server_source_get_item_type (GListModel *list)
{
- return FALSE;
+ return G_TYPE_OBJECT;
}
static void
-seahorse_server_source_collection_init (GcrCollectionIface *iface)
+seahorse_server_source_list_model_init (GListModelInterface *iface)
{
- /* This is implemented because SeahorseSource requires it */
- iface->get_length = seahorse_server_source_get_length;
- iface->get_objects = seahorse_server_source_get_objects;
- iface->contains = seahorse_server_source_contains;
+ /* This is implemented because SeahorseSource requires it */
+ iface->get_n_items = seahorse_server_source_get_n_items;
+ iface->get_item = seahorse_server_source_get_item;
+ iface->get_item_type = seahorse_server_source_get_item_type;
}
void
seahorse_server_source_search_async (SeahorseServerSource *self,
- const gchar *match,
- GcrSimpleCollection *results,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ const char *match,
+ GListStore *results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (self));
- g_return_if_fail (match != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_async);
- SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_async (self, match, results,
- cancellable, callback, user_data);
+ g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (self));
+ g_return_if_fail (match != NULL);
+ g_return_if_fail (G_IS_LIST_STORE (results));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_async);
+
+ SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_async (self, match, results,
+ cancellable, callback, user_data);
}
gboolean
@@ -344,47 +322,45 @@ seahorse_server_source_search_finish (SeahorseServerSource *self,
GAsyncResult *result,
GError **error)
{
- g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (self), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- g_return_val_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_finish, FALSE);
- return SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_finish (self, result, error);
+ g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (self), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_finish, FALSE);
+
+ return SEAHORSE_SERVER_SOURCE_GET_CLASS (self)->search_finish (self, result, error);
}
void
seahorse_server_source_export_async (SeahorseServerSource *self,
- const gchar **keyids,
+ const char **keyids,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- SeahorseServerSourceClass *klass;
+ SeahorseServerSourceClass *klass;
- g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (self));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (self));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- klass = SEAHORSE_SERVER_SOURCE_GET_CLASS (self);
- g_return_if_fail (klass->export_async);
- (klass->export_async) (self, keyids, cancellable, callback, user_data);
+ klass = SEAHORSE_SERVER_SOURCE_GET_CLASS (self);
+ g_return_if_fail (klass->export_async);
+ (klass->export_async) (self, keyids, cancellable, callback, user_data);
}
-gpointer
+GBytes *
seahorse_server_source_export_finish (SeahorseServerSource *self,
GAsyncResult *result,
- gsize *size,
GError **error)
{
- SeahorseServerSourceClass *klass;
+ SeahorseServerSourceClass *klass;
- g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (self), NULL);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
- g_return_val_if_fail (size != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- klass = SEAHORSE_SERVER_SOURCE_GET_CLASS (self);
- g_return_val_if_fail (klass->export_async != NULL, NULL);
- g_return_val_if_fail (klass->export_finish != NULL, NULL);
- return (klass->export_finish) (self, result, size, error);
+ klass = SEAHORSE_SERVER_SOURCE_GET_CLASS (self);
+ g_return_val_if_fail (klass->export_finish != NULL, NULL);
+ return (klass->export_finish) (self, result, error);
}
void
@@ -394,12 +370,12 @@ seahorse_server_source_import_async (SeahorseServerSource *source,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (source));
- g_return_if_fail (G_IS_INPUT_STREAM (input));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_async);
- SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_async (source, input, cancellable,
- callback, user_data);
+ g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (source));
+ g_return_if_fail (G_IS_INPUT_STREAM (input));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_async);
+ SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_async (source, input, cancellable,
+ callback, user_data);
}
GList *
@@ -407,9 +383,9 @@ seahorse_server_source_import_finish (SeahorseServerSource *source,
GAsyncResult *result,
GError **error)
{
- g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (source), NULL);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- g_return_val_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_finish, NULL);
- return SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_finish (source, result, error);
+ g_return_val_if_fail (SEAHORSE_IS_SERVER_SOURCE (source), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_finish, NULL);
+ return SEAHORSE_SERVER_SOURCE_GET_CLASS (source)->import_finish (source, result, error);
}
diff --git a/pgp/seahorse-server-source.h b/pgp/seahorse-server-source.h
index 9d009b41..fada5a45 100644
--- a/pgp/seahorse-server-source.h
+++ b/pgp/seahorse-server-source.h
@@ -46,46 +46,45 @@ G_DECLARE_DERIVABLE_TYPE (SeahorseServerSource, seahorse_server_source,
GObject)
struct _SeahorseServerSourceClass {
- GObjectClass parent_class;
-
- void (* import_async) (SeahorseServerSource *source,
- GInputStream *input,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- GList * (* import_finish) (SeahorseServerSource *source,
- GAsyncResult *result,
- GError **error);
-
- void (*export_async) (SeahorseServerSource *source,
- const gchar **keyids,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- gpointer (*export_finish) (SeahorseServerSource *source,
- GAsyncResult *result,
- gsize *size,
- GError **error);
-
- void (*search_async) (SeahorseServerSource *source,
- const gchar *match,
- GcrSimpleCollection *results,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- gboolean (*search_finish) (SeahorseServerSource *source,
- GAsyncResult *result,
- GError **error);
+ GObjectClass parent_class;
+
+ void (*import_async) (SeahorseServerSource *source,
+ GInputStream *input,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GList * (*import_finish) (SeahorseServerSource *source,
+ GAsyncResult *result,
+ GError **error);
+
+ void (*export_async) (SeahorseServerSource *source,
+ const gchar **keyids,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GBytes * (*export_finish) (SeahorseServerSource *source,
+ GAsyncResult *result,
+ GError **error);
+
+ void (*search_async) (SeahorseServerSource *source,
+ const char *match,
+ GListStore *results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ gboolean (*search_finish) (SeahorseServerSource *source,
+ GAsyncResult *result,
+ GError **error);
};
SeahorseServerSource* seahorse_server_source_new (const char *uri);
void seahorse_server_source_search_async (SeahorseServerSource *self,
- const gchar *match,
- GcrSimpleCollection *results,
+ const char *match,
+ GListStore *results,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -110,7 +109,6 @@ void seahorse_server_source_export_async (SeahorseServerSo
GAsyncReadyCallback callback,
gpointer user_data);
-gpointer seahorse_server_source_export_finish (SeahorseServerSource *self,
+GBytes * seahorse_server_source_export_finish (SeahorseServerSource *self,
GAsyncResult *result,
- gsize *size,
GError **error);
diff --git a/pgp/seahorse-transfer.c b/pgp/seahorse-transfer.c
index c7e91851..00f0f60c 100644
--- a/pgp/seahorse-transfer.c
+++ b/pgp/seahorse-transfer.c
@@ -104,8 +104,11 @@ on_source_export_ready (GObject *object,
seahorse_progress_end (cancellable, &closure->from);
if (SEAHORSE_IS_SERVER_SOURCE (closure->from)) {
- stream_data = seahorse_server_source_export_finish (SEAHORSE_SERVER_SOURCE (object),
- result, &stream_size, &error);
+ GBytes *stream_bytes;
+
+ stream_bytes = seahorse_server_source_export_finish (SEAHORSE_SERVER_SOURCE (object),
+ result, &error);
+ stream_data = g_bytes_unref_to_data (stream_bytes, &stream_size);
} else if (SEAHORSE_IS_GPGME_KEYRING (closure->from)) {
stream_data = seahorse_exporter_export_finish (SEAHORSE_EXPORTER (object), result,
diff --git a/pgp/seahorse-unknown-source.c b/pgp/seahorse-unknown-source.c
index a4f4a308..c22bbddd 100644
--- a/pgp/seahorse-unknown-source.c
+++ b/pgp/seahorse-unknown-source.c
@@ -23,9 +23,8 @@
#include "seahorse-unknown-source.h"
#include "seahorse-pgp-key.h"
-#include "seahorse-unknown.h"
-#include <gcr/gcr-base.h>
+#include <gcr/gcr.h>
#include <glib/gi18n.h>
@@ -33,40 +32,49 @@ enum {
PROP_0,
PROP_LABEL,
PROP_DESCRIPTION,
- PROP_ICON,
PROP_CATEGORY,
PROP_URI,
PROP_ACTIONS,
PROP_ACTION_PREFIX,
PROP_MENU_MODEL,
- PROP_SHOW_IF_EMPTY,
N_PROPS
};
struct _SeahorseUnknownSource {
- GObject parent;
- GHashTable *keys;
-};
+ GObject parent;
-struct _SeahorseUnknownSourceClass {
- GObjectClass parent_class;
+ GPtrArray *keys;
};
-static void seahorse_unknown_source_collection_iface (GcrCollectionIface *iface);
+static void seahorse_unknown_source_list_model_iface (GListModelInterface *iface);
static void seahorse_unknown_source_place_iface (SeahorsePlaceIface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorseUnknownSource, seahorse_unknown_source, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION,
seahorse_unknown_source_collection_iface);
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, seahorse_unknown_source_list_model_iface);
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_unknown_source_place_iface);
);
static void
seahorse_unknown_source_init (SeahorseUnknownSource *self)
{
- self->keys = g_hash_table_new_full (seahorse_pgp_keyid_hash,
- seahorse_pgp_keyid_equal,
- g_free, g_object_unref);
+ self->keys = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+static SeahorseUnknown *
+seahorse_unknown_lookup_by_keyid (SeahorseUnknownSource *self,
+ const char *keyid)
+{
+ for (unsigned int i = 0; i < self->keys->len; i++) {
+ SeahorseUnknown *unknown = g_ptr_array_index (self->keys, i);
+ const char *unknown_keyid;
+
+ unknown_keyid = seahorse_unknown_get_keyid (unknown);
+ if (seahorse_pgp_keyid_equal (keyid, unknown_keyid))
+ return unknown;
+ }
+
+ return NULL;
}
static void
@@ -75,7 +83,7 @@ seahorse_unknown_source_load (SeahorsePlace *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_return_if_reached ();
+ g_return_if_reached ();
}
static gboolean
@@ -83,13 +91,13 @@ seahorse_unknown_source_load_finish (SeahorsePlace *self,
GAsyncResult *res,
GError **error)
{
- g_return_val_if_reached (FALSE);
+ g_return_val_if_reached (FALSE);
}
static gchar *
seahorse_unknown_source_get_label (SeahorsePlace* self)
{
- return g_strdup ("");
+ return g_strdup ("");
}
static void
@@ -100,19 +108,13 @@ seahorse_unknown_source_set_label (SeahorsePlace *self, const char *label)
static gchar *
seahorse_unknown_source_get_description (SeahorsePlace* self)
{
- return NULL;
+ return NULL;
}
static gchar *
seahorse_unknown_source_get_uri (SeahorsePlace* self)
{
- return NULL;
-}
-
-static GIcon *
-seahorse_unknown_source_get_icon (SeahorsePlace* self)
-{
- return NULL;
+ return NULL;
}
static SeahorsePlaceCategory
@@ -124,7 +126,7 @@ seahorse_unknown_source_get_category (SeahorsePlace *place)
static GActionGroup *
seahorse_unknown_source_get_actions (SeahorsePlace* self)
{
- return NULL;
+ return NULL;
}
static const gchar *
@@ -136,13 +138,7 @@ seahorse_unknown_source_get_action_prefix (SeahorsePlace* self)
static GMenuModel *
seahorse_unknown_source_get_menu_model (SeahorsePlace* self)
{
- return NULL;
-}
-
-static gboolean
-seahorse_unknown_source_get_show_if_empty (SeahorsePlace *place)
-{
- return TRUE;
+ return NULL;
}
static void
@@ -151,20 +147,17 @@ seahorse_unknown_source_get_property (GObject *obj,
GValue *value,
GParamSpec *pspec)
{
- SeahorsePlace *place = SEAHORSE_PLACE (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, seahorse_unknown_source_get_label (place));
- break;
- case PROP_DESCRIPTION:
- g_value_take_string (value, seahorse_unknown_source_get_description (place));
- break;
- case PROP_URI:
- g_value_take_string (value, seahorse_unknown_source_get_uri (place));
- break;
- case PROP_ICON:
- g_value_take_object (value, seahorse_unknown_source_get_icon (place));
+ SeahorsePlace *place = SEAHORSE_PLACE (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ g_value_take_string (value, seahorse_unknown_source_get_label (place));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_take_string (value, seahorse_unknown_source_get_description (place));
+ break;
+ case PROP_URI:
+ g_value_take_string (value, seahorse_unknown_source_get_uri (place));
break;
case PROP_CATEGORY:
g_value_set_enum (value, seahorse_unknown_source_get_category (place));
@@ -178,9 +171,6 @@ seahorse_unknown_source_get_property (GObject *obj,
case PROP_MENU_MODEL:
g_value_take_object (value, seahorse_unknown_source_get_menu_model (place));
break;
- case PROP_SHOW_IF_EMPTY:
- g_value_set_boolean (value, TRUE);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -193,77 +183,78 @@ seahorse_unknown_source_set_property (GObject *obj,
const GValue *value,
GParamSpec *pspec)
{
- SeahorsePlace *place = SEAHORSE_PLACE (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- seahorse_unknown_source_set_label (place, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
+ SeahorsePlace *place = SEAHORSE_PLACE (obj);
+
+ switch (prop_id) {
+ case PROP_LABEL:
+ seahorse_unknown_source_set_label (place, g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
}
static void
seahorse_unknown_source_finalize (GObject *obj)
{
- SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (obj);
+ SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (obj);
- g_hash_table_destroy (self->keys);
+ g_ptr_array_unref (self->keys);
- G_OBJECT_CLASS (seahorse_unknown_source_parent_class)->finalize (obj);
+ G_OBJECT_CLASS (seahorse_unknown_source_parent_class)->finalize (obj);
}
static void
seahorse_unknown_source_class_init (SeahorseUnknownSourceClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->get_property = seahorse_unknown_source_get_property;
- gobject_class->set_property = seahorse_unknown_source_set_property;
- gobject_class->finalize = seahorse_unknown_source_finalize;
+ gobject_class->get_property = seahorse_unknown_source_get_property;
+ gobject_class->set_property = seahorse_unknown_source_set_property;
+ gobject_class->finalize = seahorse_unknown_source_finalize;
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_override_property (gobject_class, PROP_CATEGORY, "category");
g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
g_object_class_override_property (gobject_class, PROP_ACTION_PREFIX, "action-prefix");
g_object_class_override_property (gobject_class, PROP_MENU_MODEL, "menu-model");
g_object_class_override_property (gobject_class, PROP_URI, "uri");
- g_object_class_override_property (gobject_class, PROP_SHOW_IF_EMPTY, "show-if-empty");
}
-static guint
-seahorse_unknown_source_get_length (GcrCollection *collection)
+static unsigned int
+seahorse_unknown_source_get_n_items (GListModel *list)
{
- SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
- return g_hash_table_size (self->keys);
+ SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (list);
+
+ return self->keys->len;
}
-static GList *
-seahorse_unknown_source_get_objects (GcrCollection *collection)
+static void *
+seahorse_unknown_source_get_item (GListModel *list,
+ unsigned int pos)
{
- SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
- return g_hash_table_get_values (self->keys);
+ SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (list);
+
+ if (pos >= self->keys->len)
+ return NULL;
+
+ return g_object_ref (g_ptr_array_index (self->keys, pos));
}
-static gboolean
-seahorse_unknown_source_contains (GcrCollection *collection,
- GObject *object)
+static GType
+seahorse_unknown_source_get_item_type (GListModel *list)
{
- SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
- const gchar *identifier = seahorse_object_get_identifier (SEAHORSE_OBJECT (object));
- return g_hash_table_lookup (self->keys, identifier) == object;
+ return SEAHORSE_TYPE_UNKNOWN;
}
static void
-seahorse_unknown_source_collection_iface (GcrCollectionIface *iface)
+seahorse_unknown_source_list_model_iface (GListModelInterface *iface)
{
- iface->contains = seahorse_unknown_source_contains;
- iface->get_length = seahorse_unknown_source_get_length;
- iface->get_objects = seahorse_unknown_source_get_objects;
+ iface->get_n_items = seahorse_unknown_source_get_n_items;
+ iface->get_item = seahorse_unknown_source_get_item;
+ iface->get_item_type = seahorse_unknown_source_get_item_type;
}
static void
@@ -274,45 +265,44 @@ seahorse_unknown_source_place_iface (SeahorsePlaceIface *iface)
iface->get_actions = seahorse_unknown_source_get_actions;
iface->get_menu_model = seahorse_unknown_source_get_menu_model;
iface->get_description = seahorse_unknown_source_get_description;
- iface->get_icon = seahorse_unknown_source_get_icon;
iface->get_category = seahorse_unknown_source_get_category;
iface->get_label = seahorse_unknown_source_get_label;
iface->set_label = seahorse_unknown_source_set_label;
iface->get_uri = seahorse_unknown_source_get_uri;
- iface->get_show_if_empty = seahorse_unknown_source_get_show_if_empty;
}
SeahorseUnknownSource*
seahorse_unknown_source_new (void)
{
- return g_object_new (SEAHORSE_TYPE_UNKNOWN_SOURCE, NULL);
+ return g_object_new (SEAHORSE_TYPE_UNKNOWN_SOURCE, NULL);
}
static void
on_cancellable_gone (gpointer user_data,
GObject *where_the_object_was)
{
- /* TODO: Change the icon */
+ /* TODO: Change the icon */
}
-SeahorseObject *
+SeahorseUnknown *
seahorse_unknown_source_add_object (SeahorseUnknownSource *self,
- const gchar *keyid,
+ const char *keyid,
GCancellable *cancellable)
{
- SeahorseObject *object;
+ SeahorseUnknown *unknown;
- g_return_val_if_fail (keyid != NULL, NULL);
- g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (SEAHORSE_IS_UNKNOWN_SOURCE (self), NULL);
+ g_return_val_if_fail (keyid != NULL, NULL);
+ g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
- object = g_hash_table_lookup (self->keys, keyid);
- if (object == NULL) {
- object = SEAHORSE_OBJECT (seahorse_unknown_new (self, keyid, NULL));
- g_hash_table_insert (self->keys, g_strdup (keyid), object);
- }
+ unknown = seahorse_unknown_lookup_by_keyid (self, keyid);
+ if (unknown == NULL) {
+ unknown = seahorse_unknown_new (self, keyid, NULL);
+ g_ptr_array_add (self->keys, unknown);
+ }
- if (cancellable)
- g_object_weak_ref (G_OBJECT (cancellable), on_cancellable_gone, object);
+ if (cancellable)
+ g_object_weak_ref (G_OBJECT (cancellable), on_cancellable_gone, unknown);
- return object;
+ return unknown;
}
diff --git a/pgp/seahorse-unknown-source.h b/pgp/seahorse-unknown-source.h
index a9f6a1b2..b242adc5 100644
--- a/pgp/seahorse-unknown-source.h
+++ b/pgp/seahorse-unknown-source.h
@@ -21,22 +21,15 @@
#pragma once
#include "seahorse-common.h"
+#include "seahorse-unknown.h"
-#define SEAHORSE_TYPE_UNKNOWN_SOURCE (seahorse_unknown_source_get_type ())
-#define SEAHORSE_UNKNOWN_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
SEAHORSE_TYPE_UNKNOWN_SOURCE, SeahorseUnknownSource))
-#define SEAHORSE_UNKNOWN_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
SEAHORSE_TYPE_UNKNOWN_SOURCE, SeahorseUnknownSourceClass))
-#define SEAHORSE_IS_UNKNOWN_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
SEAHORSE_TYPE_UNKNOWN_SOURCE))
-#define SEAHORSE_IS_UNKNOWN_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
SEAHORSE_TYPE_UNKNOWN_SOURCE))
-#define SEAHORSE_UNKNOWN_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
SEAHORSE_TYPE_UNKNOWN_SOURCE, SeahorseUnknownSourceClass))
+#define SEAHORSE_TYPE_UNKNOWN_SOURCE (seahorse_unknown_source_get_type ())
+G_DECLARE_FINAL_TYPE (SeahorseUnknownSource, seahorse_unknown_source,
+ SEAHORSE, UNKNOWN_SOURCE,
+ GObject)
-typedef struct _SeahorseUnknownSource SeahorseUnknownSource;
-typedef struct _SeahorseUnknownSourceClass SeahorseUnknownSourceClass;
-typedef struct _SeahorseUnknownSourcePrivate SeahorseUnknownSourcePrivate;
+SeahorseUnknownSource * seahorse_unknown_source_new (void);
-GType seahorse_unknown_source_get_type (void);
-
-SeahorseUnknownSource* seahorse_unknown_source_new (void);
-
-SeahorseObject* seahorse_unknown_source_add_object (SeahorseUnknownSource *self,
- const gchar *keyid,
- GCancellable *cancellable);
+SeahorseUnknown * seahorse_unknown_source_add_object (SeahorseUnknownSource *self,
+ const char *keyid,
+ GCancellable *cancellable);
diff --git a/pgp/seahorse-unknown.c b/pgp/seahorse-unknown.c
index 319620e4..9f99de1b 100644
--- a/pgp/seahorse-unknown.c
+++ b/pgp/seahorse-unknown.c
@@ -25,43 +25,104 @@
#include <glib/gi18n.h>
+struct _SeahorseUnknown {
+ SeahorseObject parent;
+
+ char *keyid;
+};
+
+enum {
+ PROP_0,
+ PROP_KEYID,
+ N_PROPS
+};
+static GParamSpec *properties[N_PROPS] = { NULL, };
+
G_DEFINE_TYPE (SeahorseUnknown, seahorse_unknown, SEAHORSE_TYPE_OBJECT);
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
+static void
+seahorse_unknown_get_property (GObject *object,
+ unsigned int prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SeahorseUnknown *self = SEAHORSE_UNKNOWN (object);
+ switch (prop_id) {
+ case PROP_KEYID:
+ g_value_set_string (value, seahorse_unknown_get_keyid (self));
+ break;
+ }
+}
static void
-seahorse_unknown_init (SeahorseUnknown *self)
+seahorse_unknown_set_property (GObject *object, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
{
+ SeahorseUnknown *self = SEAHORSE_UNKNOWN (object);
+ switch (prop_id) {
+ case PROP_KEYID:
+ g_clear_pointer (&self->keyid, g_free);
+ self->keyid = g_value_dup_string (value);
+ break;
+ }
}
static void
-seahorse_unknown_class_init (SeahorseUnknownClass *klass)
+seahorse_unknown_object_finalize (GObject *obj)
{
+ SeahorseUnknown *self = SEAHORSE_UNKNOWN (obj);
+ g_clear_pointer (&self->keyid, g_free);
+
+ G_OBJECT_CLASS (seahorse_unknown_parent_class)->finalize (G_OBJECT (self));
}
-/* -----------------------------------------------------------------------------
- * PUBLIC METHODS
- */
+static void
+seahorse_unknown_init (SeahorseUnknown *self)
+{
+}
+
+static void
+seahorse_unknown_class_init (SeahorseUnknownClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = seahorse_unknown_object_finalize;
+ gobject_class->set_property = seahorse_unknown_set_property;
+ gobject_class->get_property = seahorse_unknown_get_property;
+
+ properties[PROP_KEYID] =
+ g_param_spec_string ("keyid", NULL, NULL, NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-SeahorseUnknown*
+ g_object_class_install_properties (gobject_class, N_PROPS, properties);
+}
+
+SeahorseUnknown *
seahorse_unknown_new (SeahorseUnknownSource *source,
- const gchar *keyid,
- const gchar *display)
+ const char *keyid,
+ const char *display)
{
- const char *identifier;
+ const char *identifier;
+
+ if (!display)
+ display = _("Unavailable");
+ identifier = seahorse_pgp_key_calc_identifier (keyid);
- if (!display)
- display = _("Unavailable");
- identifier = seahorse_pgp_key_calc_identifier (keyid);
+ return g_object_new (SEAHORSE_TYPE_UNKNOWN,
+ "place", source,
+ "label", display,
+ "identifier", identifier,
+ "keyid", keyid,
+ NULL);
+}
+
+const char *
+seahorse_unknown_get_keyid (SeahorseUnknown *self)
+{
+ g_return_val_if_fail (SEAHORSE_IS_UNKNOWN (self), NULL);
- return g_object_new (SEAHORSE_TYPE_UNKNOWN,
- "place", source,
- "label", display,
- "identifier", identifier,
- NULL);
+ return self->keyid;
}
diff --git a/pgp/seahorse-unknown.h b/pgp/seahorse-unknown.h
index 304b2398..92609f4a 100644
--- a/pgp/seahorse-unknown.h
+++ b/pgp/seahorse-unknown.h
@@ -22,31 +22,16 @@
#include <gtk/gtk.h>
#include "seahorse-common.h"
-#include "seahorse-unknown-source.h"
-#define SEAHORSE_TYPE_UNKNOWN (seahorse_unknown_get_type ())
-#define SEAHORSE_UNKNOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_UNKNOWN,
SeahorseUnknown))
-#define SEAHORSE_UNKNOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_UNKNOWN,
SeahorseUnknownClass))
-#define SEAHORSE_IS_UNKNOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_UNKNOWN))
-#define SEAHORSE_IS_UNKNOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_UNKNOWN))
-#define SEAHORSE_UNKNOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_UNKNOWN,
SeahorseUnknownClass))
+/* Solve a circular include */
+typedef struct _SeahorseUnknownSource SeahorseUnknownSource;
-typedef struct _SeahorseUnknown SeahorseUnknown;
-typedef struct _SeahorseUnknownClass SeahorseUnknownClass;
-struct _SeahorseUnknown {
- SeahorseObject parent;
+#define SEAHORSE_TYPE_UNKNOWN (seahorse_unknown_get_type ())
+G_DECLARE_FINAL_TYPE (SeahorseUnknown, seahorse_unknown, SEAHORSE, UNKNOWN, SeahorseObject)
- /*< public >*/
- gchar *display;
-};
+SeahorseUnknown * seahorse_unknown_new (SeahorseUnknownSource *usrc,
+ const char *keyid,
+ const char *display);
-struct _SeahorseUnknownClass {
- SeahorseObjectClass parent_class;
-};
-
-GType seahorse_unknown_get_type (void);
-
-SeahorseUnknown* seahorse_unknown_new (SeahorseUnknownSource *usrc,
- const gchar *keyid,
- const gchar *display);
+const char * seahorse_unknown_get_keyid (SeahorseUnknown *self);
diff --git a/pgp/test-gpgme-backend.c b/pgp/test-gpgme-backend.c
index 64b6ce1a..5a24cf35 100644
--- a/pgp/test-gpgme-backend.c
+++ b/pgp/test-gpgme-backend.c
@@ -41,9 +41,9 @@ test_pgp_check_empty_keyring (PgpTestFixture *fixture,
g_assert_nonnull (keyring);
g_assert_true (SEAHORSE_IS_GPGME_KEYRING (keyring));
- n_keys = gcr_collection_get_length (GCR_COLLECTION (keyring));
+ n_keys = g_list_model_get_n_items (G_LIST_MODEL (keyring));
g_assert_cmpint (n_keys, ==, 0);
- g_assert_null (gcr_collection_get_objects (GCR_COLLECTION (keyring)));
+ g_assert_null (g_list_model_get_item (G_LIST_MODEL (keyring), 0));
}
static void
diff --git a/pkcs11/certificate-der-exporter.vala b/pkcs11/certificate-der-exporter.vala
index 57e6ec25..9aaf1c41 100644
--- a/pkcs11/certificate-der-exporter.vala
+++ b/pkcs11/certificate-der-exporter.vala
@@ -54,7 +54,7 @@ public class CertificateDerExporter : GLib.Object, Exporter {
public Gtk.FileFilter file_filter {
owned get {
var filter = new Gtk.FileFilter();
- filter.set_name(_("Certificates (DER encoded)"));
+ filter.name = _("Certificates (DER encoded)");
filter.add_mime_type ("application/pkix-cert");
filter.add_mime_type ("application/x-x509-ca-cert");
filter.add_mime_type ("application/x-x509-user-cert");
diff --git a/pkcs11/meson.build b/pkcs11/meson.build
index 342bc1c9..cac1bdba 100644
--- a/pkcs11/meson.build
+++ b/pkcs11/meson.build
@@ -9,6 +9,7 @@ pkcs11_sources = files(
'pkcs11-properties.vala',
'pkcs11-request.vala',
'pkcs11-token.vala',
+ 'pkcs11-token-filter.vala',
'cryptoki.vapi',
'seahorse-pkcs11-backend.c',
@@ -16,7 +17,6 @@ pkcs11_sources = files(
pkcs11_deps = [
glib_deps,
- gcr_ui,
pkcs11_dep,
common_dep,
]
diff --git a/pkcs11/pkcs11-certificate.vala b/pkcs11/pkcs11-certificate.vala
index 03e626cf..ca7095e7 100644
--- a/pkcs11/pkcs11-certificate.vala
+++ b/pkcs11/pkcs11-certificate.vala
@@ -21,224 +21,210 @@
* 02111-1307, USA.
*/
-namespace Seahorse {
-namespace Pkcs11 {
-
-public class Certificate : Gck.Object, Gcr.Comparable, Gcr.Certificate,
- Gck.ObjectCache, Deletable, Exportable, Viewable {
- public Token? place {
- owned get { return (Token?)this._token.get(); }
- set { this._token.set(value); }
- }
-
- public Flags object_flags {
- get { ensure_flags(); return this._flags; }
- }
-
- public Gtk.ActionGroup? actions {
- get { return null; }
- }
-
- public PrivateKey? partner {
- owned get { return (PrivateKey?)this._private_key.get(); }
- set {
- this._private_key.set(value);
- this._icon = null;
- this.notify_property("partner");
- this.notify_property("icon");
- this.notify_property("description");
- }
- }
-
- public Gck.Attributes attributes {
- owned get { return this._attributes; }
- set {
- this._attributes = value;
- this.notify_property("attributes");
- }
- }
-
- public bool deletable {
- get {
- var token = this.place;
- if (token == null)
- return false;
- return token.is_deletable(this);
- }
- }
-
- public bool exportable {
- get { return this._der != null; }
- }
-
- public GLib.Icon icon {
- owned get {
- if (this._icon != null)
- return this._icon;
- var icon = new GLib.ThemedIcon(Gcr.ICON_CERTIFICATE);
- if (this._private_key.get() != null) {
- var eicon = new GLib.ThemedIcon (Gcr.ICON_KEY);
- var emblem = new GLib.Emblem (eicon);
- this._icon = new GLib.EmblemedIcon (icon, emblem);
- } else {
- this._icon = icon;
- }
- return this._icon;
- }
- }
-
- public string description {
- owned get {
- ensure_flags ();
- if (this._private_key.get() != null)
- return _("Personal certificate and key");
- if ((this._flags & Flags.PERSONAL) == Flags.PERSONAL)
- return _("Personal certificate");
- else
- return _("Certificate");
- }
- }
-
- public string? label {
- owned get { return get_subject_name(); }
- }
-
- public string? subject {
- owned get { return get_subject_name(); }
- }
-
- public string? markup {
- owned get { return get_markup_text(); }
- }
-
- public string? issuer {
- owned get { return get_issuer_name(); }
- }
-
- public GLib.Date expiry {
- owned get { return get_expiry_date(); }
- }
-
- private GLib.WeakRef _token;
- private Gck.Attributes? _attributes;
- private unowned Gck.Attribute? _der;
- private GLib.WeakRef _private_key;
- private GLib.Icon? _icon;
- private Flags _flags;
-
- private static uint8[] EMPTY = { };
-
- construct {
- this._flags = (Flags)uint.MAX;
- this._der = null;
- this._private_key = GLib.WeakRef(null);
- this._token = GLib.WeakRef(null);
-
- this.notify.connect((pspec) => {
- if (pspec.name != "attributes")
- return;
- if (this._attributes != null)
- this._der = this._attributes.find(CKA.VALUE);
- notify_property ("label");
- notify_property ("markup");
- notify_property ("subject");
- notify_property ("issuer");
- notify_property ("expiry");
- });
-
- if (this._attributes != null)
- this._der = this._attributes.find(CKA.VALUE);
- }
-
- public override void dispose() {
- this.partner = null;
- base.dispose();
- }
-
- public Gtk.Window? create_viewer(Gtk.Window? parent) {
- var viewer = new Pkcs11.Properties(this, parent);
- viewer.show();
- return viewer;
- }
-
- public Seahorse.Deleter create_deleter() {
- Seahorse.Deleter deleter;
-
- PrivateKey? key = this.partner;
- if (key == null) {
- deleter = new Pkcs11.Deleter(this);
- } else {
- deleter = key.create_deleter();
- if (!deleter.add_object(this))
- GLib.return_val_if_reached(null);
- }
-
- return deleter;
- }
-
- public GLib.List<Exporter> create_exporters(ExporterType type) {
- var exporters = new GLib.List<Exporter>();
-
- if (this.exportable) {
- var exporter = new CertificateDerExporter(this);
- exporters.append(exporter);
- }
-
- return exporters;
- }
-
- public void fill(Gck.Attributes attributes) {
- Gck.Builder builder = new Gck.Builder(Gck.BuilderFlags.NONE);
-
- if (this._attributes != null)
- builder.add_all(this._attributes);
- builder.set_all(attributes);
- this._attributes = builder.steal();
- this.notify_property("attributes");
- }
-
- [CCode (array_length_type = "gsize")]
- public unowned uint8[] get_der_data() {
- if (this._der == null)
- return EMPTY;
- return this._der.get_data();
- }
-
- public int compare (Gcr.Comparable? other) {
- if (other == null)
- return -1;
- unowned uint8[] data1 = this.get_der_data();
- unowned uint8[] data2 = ((Gcr.Certificate)other).get_der_data();
- return Gcr.Comparable.memcmp(data1, data2);
- }
-
- private Flags calc_is_personal_and_trusted() {
- ulong category = 0;
- bool is_ca;
-
- /* If a matching private key, then this is personal*/
- if (this._private_key.get() != null)
- return Flags.PERSONAL | Flags.TRUSTED;
-
- if (this._attributes != null &&
- this._attributes.find_ulong (CKA.CERTIFICATE_CATEGORY, out category)) {
- if (category == 2)
- return 0;
- else if (category == 1)
- return Flags.PERSONAL;
- }
-
- if (get_basic_constraints (out is_ca, null))
- return is_ca ? 0 : Flags.PERSONAL;
-
- return Flags.PERSONAL;
- }
-
- private void ensure_flags() {
- if (this._flags == uint.MAX)
- this._flags = Flags.EXPORTABLE | calc_is_personal_and_trusted ();
- }
-}
-
-}
+public class Seahorse.Pkcs11.Certificate : Gck.Object, Gcr.Comparable, Gcr.Certificate,
+ Gck.ObjectCache, Deletable, Exportable, Viewable {
+ public Token? place {
+ owned get { return (Token?)this._token.get(); }
+ set { this._token.set(value); }
+ }
+
+ public Flags object_flags {
+ get { ensure_flags(); return this._flags; }
+ }
+
+ public PrivateKey? partner {
+ owned get { return (PrivateKey?)this._private_key.get(); }
+ set {
+ this._private_key.set(value);
+ this._icon = null;
+ this.notify_property("partner");
+ this.notify_property("icon");
+ this.notify_property("description");
+ }
+ }
+
+ public Gck.Attributes attributes {
+ owned get { return this._attributes; }
+ set {
+ this._attributes = value;
+ this.notify_property("attributes");
+ }
+ }
+
+ public bool deletable {
+ get {
+ var token = this.place;
+ if (token == null)
+ return false;
+ return token.is_deletable(this);
+ }
+ }
+
+ public bool exportable {
+ get { return this._der != null; }
+ }
+
+ public GLib.Icon icon {
+ owned get {
+ if (this._icon != null)
+ return this._icon;
+ //XXX
+ // var icon = new GLib.ThemedIcon(Gcr.ICON_CERTIFICATE);
+ // if (this._private_key.get() != null) {
+ // var eicon = new GLib.ThemedIcon (Gcr.ICON_KEY);
+ // var emblem = new GLib.Emblem (eicon);
+ // this._icon = new GLib.EmblemedIcon (icon, emblem);
+ // } else {
+ // this._icon = icon;
+ // }
+ return this._icon;
+ }
+ }
+
+ public string description {
+ owned get {
+ ensure_flags ();
+ if (this._private_key.get() != null)
+ return _("Personal certificate and key");
+ if ((this._flags & Flags.PERSONAL) == Flags.PERSONAL)
+ return _("Personal certificate");
+ else
+ return _("Certificate");
+ }
+ }
+
+ public string? label {
+ owned get { return get_subject_name(); }
+ }
+
+ public string? subject_name {
+ owned get { return get_subject_name(); }
+ }
+
+ public string? issuer_name {
+ owned get { return get_issuer_name(); }
+ }
+
+ public GLib.DateTime? expiry_date {
+ owned get { return get_expiry_date(); }
+ }
+
+ private GLib.WeakRef _token;
+ private Gck.Attributes? _attributes;
+ private unowned Gck.Attribute? _der;
+ private GLib.WeakRef _private_key;
+ private GLib.Icon? _icon;
+ private Flags _flags;
+
+ private static uint8[] EMPTY = { };
+
+ construct {
+ this._flags = (Flags)uint.MAX;
+ this._der = null;
+ this._private_key = GLib.WeakRef(null);
+ this._token = GLib.WeakRef(null);
+
+ this.notify.connect((pspec) => {
+ if (pspec.name != "attributes")
+ return;
+ if (this._attributes != null)
+ this._der = this._attributes.find(CKA.VALUE);
+ notify_property ("label");
+ notify_property ("subject-name");
+ notify_property ("issuer-name");
+ notify_property ("expiry-date");
+ });
+
+ if (this._attributes != null)
+ this._der = this._attributes.find(CKA.VALUE);
+ }
+
+ public override void dispose() {
+ this.partner = null;
+ base.dispose();
+ }
+
+ public Gtk.Window? create_viewer(Gtk.Window? parent) {
+ var viewer = new Pkcs11.Properties(this, parent);
+ viewer.show();
+ return viewer;
+ }
+
+ public Seahorse.Deleter create_deleter() {
+ Seahorse.Deleter deleter;
+
+ PrivateKey? key = this.partner;
+ if (key == null) {
+ deleter = new Pkcs11.Deleter(this);
+ } else {
+ deleter = key.create_deleter();
+ if (!deleter.add_object(this))
+ GLib.return_val_if_reached(null);
+ }
+
+ return deleter;
+ }
+
+ public GLib.List<Exporter> create_exporters(ExporterType type) {
+ var exporters = new GLib.List<Exporter>();
+
+ if (this.exportable) {
+ var exporter = new CertificateDerExporter(this);
+ exporters.append(exporter);
+ }
+
+ return exporters;
+ }
+
+ public void fill(Gck.Attributes attributes) {
+ Gck.Builder builder = new Gck.Builder(Gck.BuilderFlags.NONE);
+
+ if (this._attributes != null)
+ builder.add_all(this._attributes);
+ builder.set_all(attributes);
+ this._attributes = builder.end();
+ this.notify_property("attributes");
+ }
+
+ [CCode (array_length_type = "gsize")]
+ public unowned uint8[] get_der_data() {
+ if (this._der == null)
+ return EMPTY;
+ return this._der.get_data();
+ }
+
+ public int compare (Gcr.Comparable? other) {
+ if (other == null)
+ return -1;
+ unowned uint8[] data1 = this.get_der_data();
+ unowned uint8[] data2 = ((Gcr.Certificate)other).get_der_data();
+ return Gcr.Comparable.memcmp(data1, data2);
+ }
+
+ private Flags calc_is_personal_and_trusted() {
+ ulong category = 0;
+ bool is_ca;
+
+ /* If a matching private key, then this is personal*/
+ if (this._private_key.get() != null)
+ return Flags.PERSONAL | Flags.TRUSTED;
+
+ if (this._attributes != null &&
+ this._attributes.find_ulong (CKA.CERTIFICATE_CATEGORY, out category)) {
+ if (category == 2)
+ return 0;
+ else if (category == 1)
+ return Flags.PERSONAL;
+ }
+
+ if (get_basic_constraints (out is_ca, null))
+ return is_ca ? 0 : Flags.PERSONAL;
+
+ return Flags.PERSONAL;
+ }
+
+ private void ensure_flags() {
+ if (this._flags == uint.MAX)
+ this._flags = Flags.EXPORTABLE | calc_is_personal_and_trusted ();
+ }
}
diff --git a/pkcs11/pkcs11-deleter.vala b/pkcs11/pkcs11-deleter.vala
index 475b30c4..20e6571e 100644
--- a/pkcs11/pkcs11-deleter.vala
+++ b/pkcs11/pkcs11-deleter.vala
@@ -21,13 +21,11 @@
* Author: Stef Walter <stefw redhat com>
*/
-namespace Seahorse {
-namespace Pkcs11 {
+public class Seahorse.Pkcs11.Deleter : Seahorse.Deleter {
-public class Deleter : Seahorse.Deleter {
protected GLib.List<Gck.Object> objects;
- public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+ public override Gtk.Window create_confirm(Gtk.Window? parent) {
var num = this.objects.length();
if (num == 1) {
string label;
@@ -69,7 +67,7 @@ public class Deleter : Seahorse.Deleter {
} catch (GLib.Error e) {
/* Ignore objects that have gone away */
- if (e.domain != Gck.Error.get_quark() ||
+ if (e.domain != Gck.Error.quark() ||
e.code != CKR.OBJECT_HANDLE_INVALID)
throw e;
}
@@ -77,7 +75,3 @@ public class Deleter : Seahorse.Deleter {
return true;
}
}
-
-
-}
-}
diff --git a/pkcs11/pkcs11-generate.vala b/pkcs11/pkcs11-generate.vala
index a7dbb499..11c78c7d 100644
--- a/pkcs11/pkcs11-generate.vala
+++ b/pkcs11/pkcs11-generate.vala
@@ -19,20 +19,16 @@
* <http://www.gnu.org/licenses/>.
*/
-// FIXME: damn broken bindings
-extern Gcr.CollectionModel gcr_collection_model_new(Gcr.Collection collection,
- Gcr.CollectionModelMode mode, ...);
-
[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-pkcs11-generate.ui")]
public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
[GtkChild]
- private unowned Gtk.Entry label_entry;
+ private unowned Adw.EntryRow label_row;
private Pkcs11.Token? token;
[GtkChild]
private unowned Gtk.ComboBox token_box;
- private Gcr.CollectionModel? token_model;
+ private GLib.ListModel token_model;
private Gck.Mechanism? mechanism;
private Gtk.ListStore? mechanism_store;
@@ -77,22 +73,26 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
this.mechanism_box.changed.connect(on_mechanism_changed);
// The tokens
- Gcr.Collection collection = Pkcs11.Backend.get_writable_tokens(null,
Cryptoki.MechanismType.RSA_PKCS_KEY_PAIR_GEN);
- this.token_model = gcr_collection_model_new(collection, Gcr.CollectionModelMode.LIST,
- "icon", typeof(Icon), "label", typeof(string),
- null);
- this.token_model.set_sort_column_id(1, Gtk.SortType.ASCENDING);
- this.token_box.set_model(this.token_model);
- Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf();
- icon_renderer.stock_size = Gtk.IconSize.BUTTON;
- this.token_box.pack_start(icon_renderer, false);
- this.token_box.add_attribute(icon_renderer, "gicon", 0);
- renderer = new Gtk.CellRendererText();
- this.token_box.pack_start(renderer, true);
- this.token_box.add_attribute(renderer, "text", 1);
- this.token_box.changed.connect(on_token_changed);
- if (collection.get_length() > 0)
- this.token_box.active = 0;
+ var backend = Pkcs11.Backend.get();
+ var filter = new Pkcs11.TokenFilter();
+ filter.only_writable = true;
+ filter.mechanism = Cryptoki.MechanismType.RSA_PKCS_KEY_PAIR_GEN;
+ var model = new Gtk.FilterListModel(backend, filter);
+ // this.token_model = gcr_collection_model_new(collection, Gcr.CollectionModelMode.LIST,
+ // "icon", typeof(Icon), "label", typeof(string),
+ // null);
+ // this.token_model.set_sort_column_id(1, Gtk.SortType.ASCENDING);
+ // this.token_box.set_model(this.token_model);
+ // Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf();
+ // icon_renderer.stock_size = Gtk.IconSize.BUTTON;
+ // this.token_box.pack_start(icon_renderer, false);
+ // this.token_box.add_attribute(icon_renderer, "gicon", 0);
+ // renderer = new Gtk.CellRendererText();
+ // this.token_box.pack_start(renderer, true);
+ // this.token_box.add_attribute(renderer, "text", 1);
+ // this.token_box.changed.connect(on_token_changed);
+ // if (collection.get_length() > 0)
+ // this.token_box.active = 0;
set_default_response (Gtk.ResponseType.OK);
@@ -103,17 +103,6 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
GLib.Object(transient_for: parent);
}
- ~Generate() {
- this.token = null;
- this.token_model = null;
-
- this.mechanism = null;
- this.mechanism_store = null;
-
- this.cancellable = null;
- this.pub_attrs = this.prv_attrs = null;
- }
-
private void update_response() {
set_response_sensitive(Gtk.ResponseType.OK, this.token != null && this.mechanism != null);
}
@@ -130,10 +119,11 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
private void on_token_changed(Gtk.ComboBox combo_box) {
this.token = null;
+ // XXX
Gtk.TreeIter iter;
- if (combo_box.get_active_iter(out iter)) {
- this.token = (Pkcs11.Token) this.token_model.object_for_iter(iter);
- }
+ // if (combo_box.get_active_iter(out iter)) {
+ // this.token = (Pkcs11.Token) this.token_model.object_for_iter(iter);
+ // }
bool valid = this.mechanism_store.get_iter_first(out iter);
if (this.token != null) {
@@ -248,7 +238,7 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
priva.add_boolean(Cryptoki.Attribute.PRIVATE, true);
priva.add_boolean(Cryptoki.Attribute.SENSITIVE, true);
- string label = this.label_entry.text;
+ string label = this.label_row.text;
publi.add_string(Cryptoki.Attribute.LABEL, label);
priva.add_string(Cryptoki.Attribute.LABEL, label);
@@ -267,8 +257,8 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
warning("currently no support for this mechanism");
}
- this.prv_attrs = priva.steal();
- this.pub_attrs = publi.steal();
+ this.prv_attrs = priva.end();
+ this.pub_attrs = publi.end();
publi.clear();
priva.clear();
diff --git a/pkcs11/pkcs11-key-deleter.vala b/pkcs11/pkcs11-key-deleter.vala
index 3b34dbc6..efb7db30 100644
--- a/pkcs11/pkcs11-key-deleter.vala
+++ b/pkcs11/pkcs11-key-deleter.vala
@@ -29,7 +29,7 @@ class KeyDeleter : Deleter {
private PrivateKey? _key;
private string? _label;
- public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+ public override Gtk.Window create_confirm(Gtk.Window? parent) {
var dialog = new DeleteDialog(parent, _("Are you sure you want to permanently delete %s?"),
this._label);
dialog.check_label = _("I understand that this key will be permanently deleted.");
dialog.check_require = true;
diff --git a/pkcs11/pkcs11-private-key.vala b/pkcs11/pkcs11-private-key.vala
index c6adcfa9..f8e5869c 100644
--- a/pkcs11/pkcs11-private-key.vala
+++ b/pkcs11/pkcs11-private-key.vala
@@ -26,106 +26,103 @@ namespace Pkcs11 {
public class PrivateKey : Gck.Object, Gck.ObjectCache,
Deletable, Exportable, Viewable {
- public Token? place {
- owned get { return (Token?)this._token.get(); }
- set { this._token.set(value); }
- }
-
- public Flags object_flags {
- get { return Flags.PERSONAL; }
- }
-
- public Gtk.ActionGroup? actions {
- get { return null; }
- }
-
- public Certificate? partner {
- owned get { return (Certificate?)this._certificate.get(); }
- set {
- this._certificate.set(value);
- notify_property("partner");
- notify_property("description");
- }
- }
-
- public string? label {
- owned get {
- if (this._attributes != null) {
- string label;
- if (this._attributes.find_string(CKA.LABEL, out label))
- return label;
- }
- Certificate? cert = this.partner;
- if (cert != null)
- return cert.label;
- return _("Unnamed private key");
- }
- }
-
- public string? markup {
- owned get { return GLib.Markup.escape_text(this.label, -1); }
- }
-
- public string? description {
- get { return _("Private key"); }
- }
-
- public GLib.Icon? icon {
- get {
- if (this._icon == null)
- this._icon = new GLib.ThemedIcon(Gcr.ICON_KEY);
- return this._icon;
- }
- }
-
- public Gck.Attributes attributes {
- owned get { return this._attributes; }
- set {
- this._attributes = value;
- notify_property("attributes");
- }
- }
-
- public bool deletable {
- get {
- Token ?token = this.place;
- return token == null ? false : token.is_deletable(this);
- }
- }
-
- public bool exportable {
- get { return false; }
- }
-
- private GLib.WeakRef _token;
- private Gck.Attributes? _attributes;
- private GLib.WeakRef _certificate;
- private GLib.Icon? _icon;
-
- public void fill(Gck.Attributes attributes) {
- Gck.Builder builder = new Gck.Builder(Gck.BuilderFlags.NONE);
- if (this._attributes != null)
- builder.add_all(this._attributes);
- builder.set_all(attributes);
- this._attributes = builder.steal();
- notify_property("attributes");
- }
-
- public Seahorse.Deleter create_deleter() {
- return new KeyDeleter(this);
- }
-
- public GLib.List<Exporter> create_exporters(ExporterType type) {
- /* In the future we may exporters here, but for now no exporting */
- var exporters = new GLib.List<Exporter>();
- return exporters;
- }
-
- public Gtk.Window? create_viewer(Gtk.Window? parent) {
- var viewer = new Pkcs11.Properties(this, parent);
- viewer.show();
- return viewer;
- }
+ public Token? place {
+ owned get { return (Token?)this._token.get(); }
+ set { this._token.set(value); }
+ }
+
+ public Flags object_flags {
+ get { return Flags.PERSONAL; }
+ }
+
+ public Certificate? partner {
+ owned get { return (Certificate?)this._certificate.get(); }
+ set {
+ this._certificate.set(value);
+ notify_property("partner");
+ notify_property("description");
+ }
+ }
+
+ public string? label {
+ owned get {
+ if (this._attributes != null) {
+ string label;
+ if (this._attributes.find_string(CKA.LABEL, out label))
+ return label;
+ }
+ Certificate? cert = this.partner;
+ if (cert != null)
+ return cert.label;
+ return _("Unnamed private key");
+ }
+ }
+
+ public string? markup {
+ owned get { return GLib.Markup.escape_text(this.label, -1); }
+ }
+
+ public string? description {
+ get { return _("Private key"); }
+ }
+
+ public GLib.Icon? icon {
+ get {
+ // XXX
+ // if (this._icon == null)
+ // this._icon = new GLib.ThemedIcon(Gcr.ICON_KEY);
+ return this._icon;
+ }
+ }
+
+ public Gck.Attributes attributes {
+ owned get { return this._attributes; }
+ set {
+ this._attributes = value;
+ notify_property("attributes");
+ }
+ }
+
+ public bool deletable {
+ get {
+ Token ?token = this.place;
+ return token == null ? false : token.is_deletable(this);
+ }
+ }
+
+ public bool exportable {
+ get { return false; }
+ }
+
+ private GLib.WeakRef _token;
+ private Gck.Attributes? _attributes;
+ private GLib.WeakRef _certificate;
+ private GLib.Icon? _icon;
+
+ public void fill(Gck.Attributes attributes) {
+ Gck.Builder builder = new Gck.Builder(Gck.BuilderFlags.NONE);
+ if (this._attributes != null)
+ builder.add_all(this._attributes);
+ builder.set_all(attributes);
+ this._attributes = builder.end();
+ notify_property("attributes");
+ }
+
+ public Seahorse.Deleter create_deleter() {
+ return new KeyDeleter(this);
+ }
+
+ public GLib.List<Exporter> create_exporters(ExporterType type) {
+ /* In the future we may exporters here, but for now no exporting */
+ var exporters = new GLib.List<Exporter>();
+ return exporters;
+ }
+
+ public Gtk.Window? create_viewer(Gtk.Window? parent) {
+ var viewer = new Pkcs11.Properties(this, parent);
+ viewer.show();
+ return viewer;
+ }
}
}
diff --git a/pkcs11/pkcs11-properties.vala b/pkcs11/pkcs11-properties.vala
index e24c355b..5abe2bc0 100644
--- a/pkcs11/pkcs11-properties.vala
+++ b/pkcs11/pkcs11-properties.vala
@@ -40,9 +40,10 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
[GtkChild]
private unowned Gtk.Box content;
- private Gcr.Viewer _viewer;
+ //XXX
+ // private Gcr.Viewer _viewer;
private GLib.Cancellable _cancellable;
- private Gck.Object _request_key;
+ private Pkcs11.PrivateKey _request_key;
public Properties(Gck.Object object, Gtk.Window window) {
GLib.Object(object: object, transient_for: window);
@@ -51,11 +52,11 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
construct {
this._cancellable = new GLib.Cancellable();
- this._viewer = Gcr.Viewer.new_scrolled();
- this.content.pack_start(this._viewer);
- this._viewer.set_hexpand(true);
- this._viewer.set_vexpand(true);
- this._viewer.show();
+ // this._viewer = Gcr.Viewer.new_scrolled();
+ // this.content.append(this._viewer);
+ // this._viewer.set_hexpand(true);
+ // this._viewer.set_vexpand(true);
+ // this._viewer.show();
/* ... */
@@ -82,7 +83,7 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
this.export_button.set_visible(exporters != null);
- this._viewer.grab_focus();
+// this._viewer.grab_focus();
}
public override void dispose() {
@@ -105,18 +106,21 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
object.get("label", &label, "attributes", &attributes);
if (attributes != null) {
- var renderer = Gcr.Renderer.create(label, attributes);
- if (renderer != null) {
- object.bind_property("label", renderer, "label",
- GLib.BindingFlags.DEFAULT);
- object.bind_property("attributes", renderer, "attributes",
- GLib.BindingFlags.DEFAULT);
-
- if (renderer.get_class().find_property("object") != null)
- renderer.set("object", object);
-
- this._viewer.add_renderer(renderer);
- }
+ // XXX
+ // var renderer = Gcr.Renderer.create(label, attributes);
+ // if (renderer != null) {
+ // object.bind_property("label", renderer, "label",
+ // GLib.BindingFlags.DEFAULT);
+ // object.bind_property("attributes", renderer, "attributes",
+ // GLib.BindingFlags.DEFAULT);
+
+ // if (renderer.get_class().find_property("object") != null)
+ // renderer.set("object", object);
+
+// #if 0
+ // this._viewer.add_renderer(renderer);
+// #endif
+ // }
}
}
@@ -145,7 +149,15 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
deleter = new Deleter((Gck.Object)this.object);
}
- if (deleter.prompt(this)) {
+ var prompt = deleter.create_confirm(this);
+ //XXX
+ ((Gtk.Dialog) prompt).response.connect((response) => {
+ if (response != Gtk.ResponseType.ACCEPT) {
+ prompt.destroy();
+ return;
+ }
+ prompt.destroy();
+
deleter.delete.begin(this._cancellable, (obj, res) => {
try {
if (deleter.delete.end(res))
@@ -154,12 +166,16 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
Util.show_error(this, _("Couldn’t delete"), err.message);
}
});
- }
+ });
}
[GtkCallback]
private void on_request_certificate_button_clicked(Gtk.Button request_button) {
- Request.prompt(this, this._request_key);
+ var req_dialog = new Pkcs11.Request(this, this._request_key);
+ req_dialog.response.connect((resp) => {
+ req_dialog.destroy();
+ });
+ req_dialog.present();
}
private void check_certificate_request_capable(GLib.Object object) {
@@ -170,7 +186,7 @@ public class Seahorse.Pkcs11.Properties : Gtk.Dialog {
try {
if (Gcr.CertificateRequest.capable_async.end(res)) {
this.request_certificate_button.set_visible(true);
- this._request_key = (PrivateKey)object;
+ this._request_key = (Pkcs11.PrivateKey) object;
}
} catch (GLib.Error err) {
GLib.message("couldn't check capabilities of private key: %s", err.message);
diff --git a/pkcs11/pkcs11-request.vala b/pkcs11/pkcs11-request.vala
index 688acd4d..f227aa1e 100644
--- a/pkcs11/pkcs11-request.vala
+++ b/pkcs11/pkcs11-request.vala
@@ -23,81 +23,76 @@
* Stef Walter <stefw redhat com>
*/
-namespace Seahorse {
-namespace Pkcs11 {
-
-public class Request : Gtk.Dialog {
- public PrivateKey private_key { construct; get; }
-
- Gtk.Entry _name_entry;
- uint8[] _encoded;
-
- construct {
- var builder = new Gtk.Builder();
- var path = "/org/gnome/Seahorse/seahorse-pkcs11-request.ui";
- try {
- builder.add_from_resource(path);
- } catch (GLib.Error err) {
- GLib.warning("couldn't load ui file: %s", path);
- return;
- }
-
- this.set_resizable(false);
- var content = this.get_content_area();
- var widget = (Gtk.Widget)builder.get_object("pkcs11-request");
- content.add(widget);
- widget.show();
-
- this._name_entry = (Gtk.Entry)builder.get_object("request-name");
- this._name_entry.changed.connect(() => { update_response(); });
+public class Seahorse.Pkcs11.Request : Gtk.Dialog {
+
+ public Pkcs11.PrivateKey private_key { construct; get; }
+
+ private Gtk.Entry _name_entry;
+ private uint8[] _encoded;
+
+ construct {
+ var builder = new Gtk.Builder();
+ var path = "/org/gnome/Seahorse/seahorse-pkcs11-request.ui";
+ try {
+ builder.add_from_resource(path);
+ } catch (GLib.Error err) {
+ GLib.warning("couldn't load ui file: %s", path);
+ return;
+ }
+
+ this.set_resizable(false);
+ var content = this.get_content_area();
+ var widget = (Gtk.Widget)builder.get_object("pkcs11-request");
+ content.append(widget);
+
+ this._name_entry = (Gtk.Entry)builder.get_object("request-name");
+ this._name_entry.changed.connect(() => { update_response(); });
// The buttons
this.add_buttons(_("_Cancel"), Gtk.ResponseType.CANCEL,
_("Create"), Gtk.ResponseType.OK);
this.set_default_response (Gtk.ResponseType.OK);
- this.update_response ();
-
- if (!(this.private_key is Gck.Object)) {
- GLib.critical("private key is not of type %s", typeof(Gck.Object).name());
- }
- }
-
- public static void prompt(Gtk.Window? parent,
- Gck.Object private_key) {
- var dialog = (Request)GLib.Object.new(typeof(Request), transient_for: parent,
- private_key: private_key);
- dialog.run();
- }
-
- public override void response(int response_id) {
- if (response_id == Gtk.ResponseType.OK) {
- var interaction = new Interaction(this.transient_for);
- var session = this.private_key.get_session();
- session.set_interaction(interaction);
-
- var req =
Gcr.CertificateRequest.prepare(Gcr.CertificateRequestFormat.CERTIFICATE_REQUEST_PKCS10,
- this.private_key);
- req.set_cn(this._name_entry.get_text());
- req.complete_async.begin(null, (obj, res) => {
- try {
- req.complete_async.end(res);
- this.save_certificate_request(req, this.transient_for);
- } catch (GLib.Error err) {
- Util.show_error(this.transient_for, _("Couldn’t create certificate
request"), err.message);
- }
- });
-
- this.hide();
- }
- }
-
- private void update_response() {
- string name = this._name_entry.get_text();
- this.set_response_sensitive(Gtk.ResponseType.OK, name != "");
- }
-
- private static string BAD_FILENAME_CHARS = "/\\<>|?*";
+ this.update_response ();
+
+ if (!(this.private_key is Gck.Object)) {
+ GLib.critical("private key is not of type %s", typeof(Gck.Object).name());
+ }
+ }
+
+ public Request(Gtk.Window? parent,
+ Pkcs11.PrivateKey private_key) {
+ GLib.Object(transient_for: parent, private_key: private_key);
+ }
+
+ public override void response(int response_id) {
+ if (response_id == Gtk.ResponseType.OK) {
+ var interaction = new Interaction(this.transient_for);
+ var session = this.private_key.get_session();
+ session.set_interaction(interaction);
+
+ var req = Gcr.CertificateRequest.prepare(Gcr.CertificateRequestFormat.CERTIFICATE_REQUEST_PKCS10,
+ this.private_key);
+ req.set_cn(this._name_entry.get_text());
+ req.complete_async.begin(null, (obj, res) => {
+ try {
+ req.complete_async.end(res);
+ this.save_certificate_request(req, this.transient_for);
+ } catch (GLib.Error err) {
+ Util.show_error(this.transient_for, _("Couldn’t create certificate request"),
err.message);
+ }
+ });
+
+ this.hide();
+ }
+ }
+
+ private void update_response() {
+ string name = this._name_entry.get_text();
+ this.set_response_sensitive(Gtk.ResponseType.OK, name != "");
+ }
+
+ private static string BAD_FILENAME_CHARS = "/\\<>|?*";
private void save_certificate_request(Gcr.CertificateRequest req,
Gtk.Window? parent) {
@@ -105,53 +100,47 @@ public class Request : Gtk.Dialog {
parent, Gtk.FileChooserAction.SAVE,
_("_Save"), _("_Cancel"));
- chooser.set_local_only(false);
-
- var der_filter = new Gtk.FileFilter();
- der_filter.set_name(_("Certificate request"));
- der_filter.add_mime_type("application/pkcs10");
- der_filter.add_pattern("*.p10");
- der_filter.add_pattern("*.csr");
- chooser.add_filter(der_filter);
- chooser.set_filter(der_filter);
-
- var pem_filter = new Gtk.FileFilter();
- pem_filter.set_name(_("PEM encoded request"));
- pem_filter.add_mime_type("application/pkcs10+pem");
- pem_filter.add_pattern("*.pem");
- chooser.add_filter(pem_filter);
-
- string? label;
- this.private_key.get("label", out label);
- if (label == null || label == "")
- label = "Certificate Request";
- var filename = label + ".csr";
- filename = filename.delimit(BAD_FILENAME_CHARS, '_');
- chooser.set_current_name(filename);
-
- chooser.set_do_overwrite_confirmation(true);
-
- var response = chooser.run();
- if (response == Gtk.ResponseType.ACCEPT) {
- bool textual = chooser.get_filter() == pem_filter;
- this._encoded = req.encode(textual);
-
- var file = chooser.get_file();
- file.replace_contents_async.begin(this._encoded, null, false,
- GLib.FileCreateFlags.NONE,
- null, (obj, res) => {
- try {
- string new_etag;
- file.replace_contents_async.end(res, out new_etag);
- } catch (GLib.Error err) {
- Util.show_error(parent, _("Couldn’t save certificate request"),
err.message);
- }
- });
- }
-
- chooser.destroy();
- }
-}
-
-}
+ var der_filter = new Gtk.FileFilter();
+ der_filter.name = _("Certificate request");
+ der_filter.add_mime_type("application/pkcs10");
+ der_filter.add_pattern("*.p10");
+ der_filter.add_pattern("*.csr");
+ chooser.add_filter(der_filter);
+ chooser.set_filter(der_filter);
+
+ var pem_filter = new Gtk.FileFilter();
+ pem_filter.name = _("PEM encoded request");
+ pem_filter.add_mime_type("application/pkcs10+pem");
+ pem_filter.add_pattern("*.pem");
+ chooser.add_filter(pem_filter);
+
+ string? label;
+ this.private_key.get("label", out label);
+ if (label == null || label == "")
+ label = "Certificate Request";
+ var filename = label + ".csr";
+ filename = filename.delimit(BAD_FILENAME_CHARS, '_');
+ chooser.set_current_name(filename);
+
+ chooser.response.connect((response) => {
+ if (response == Gtk.ResponseType.ACCEPT) {
+ bool textual = chooser.get_filter() == pem_filter;
+ this._encoded = req.encode(textual);
+
+ var file = chooser.get_file();
+ file.replace_contents_async.begin(this._encoded, null, false,
+ GLib.FileCreateFlags.NONE,
+ null, (obj, res) => {
+ try {
+ string new_etag;
+ file.replace_contents_async.end(res, out new_etag);
+ } catch (GLib.Error err) {
+ Util.show_error(parent, _("Couldn’t save certificate request"), err.message);
+ }
+ });
+ }
+
+ chooser.destroy();
+ });
+ }
}
diff --git a/pkcs11/pkcs11-token-filter.vala b/pkcs11/pkcs11-token-filter.vala
new file mode 100644
index 00000000..ce53a1d5
--- /dev/null
+++ b/pkcs11/pkcs11-token-filter.vala
@@ -0,0 +1,63 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2022 Niels De Graef
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+public class Seahorse.Pkcs11.TokenFilter : Gtk.Filter {
+
+ /** If set, only match tokens that are writable */
+ public bool only_writable {
+ get { return this._only_writable; }
+ set {
+ if (this._only_writable != value) {
+ this._only_writable = value;
+ changed(Gtk.FilterChange.DIFFERENT);
+ }
+ }
+ }
+ private bool _only_writable = false;
+
+ /** If not MAXUINT, only match token that have the mechanism */
+ public uint mechanism {
+ get { return this._mechanism; }
+ set {
+ if (this._mechanism == value)
+ return;
+
+ this._mechanism = value;
+ changed(Gtk.FilterChange.DIFFERENT);
+ }
+ }
+ public uint _mechanism = uint.MAX;
+
+ public override bool match (GLib.Object? item) {
+ var token = (Pkcs11.Token) item;
+ if (this.only_writable && (CKF.WRITE_PROTECTED & token.info.flags) != 0)
+ return false;
+
+ if (this.mechanism != uint.MAX && !token.has_mechanism(this.mechanism))
+ return false;
+
+ return true;
+ }
+
+ public override Gtk.FilterMatch get_strictness () {
+ return Gtk.FilterMatch.SOME;
+ }
+}
diff --git a/pkcs11/pkcs11-token.vala b/pkcs11/pkcs11-token.vala
index 28db57fc..a066e077 100644
--- a/pkcs11/pkcs11-token.vala
+++ b/pkcs11/pkcs11-token.vala
@@ -21,84 +21,72 @@
* Boston, MA 02111-1307, USA.
*/
-namespace Seahorse {
-namespace Pkcs11 {
-
-public class Token : GLib.Object, Gcr.Collection, Place, Lockable {
-
- public bool unlockable {
- get {
- this.ensure_token_info();
- if ((this._info.flags & CKF.LOGIN_REQUIRED) == 0)
- return false;
- if ((this._info.flags & CKF.USER_PIN_INITIALIZED) == 0)
- return false;
- return !is_session_logged_in(this._session);
- }
- }
-
- public bool lockable {
- get {
- this.ensure_token_info();
- if ((this._info.flags & CKF.LOGIN_REQUIRED) == 0)
- return false;
- if ((this._info.flags & CKF.USER_PIN_INITIALIZED) == 0)
- return false;
- return is_session_logged_in(this._session);
- }
- }
-
- public Gck.TokenInfo info {
- get { return this.ensure_token_info(); }
- }
-
- public Gck.Session session {
- get { return this._session; }
- set {
- this._session = session;
- notify_property("session");
- notify_property("lockable");
- notify_property("unlockable");
- }
- }
-
- public Gck.Slot slot {
- get { return this._slot; }
- construct { this._slot = value; }
- }
-
- public string label {
- owned get {
- var token = this._slot.get_token_info();
- if (token == null)
- return C_("Label", "Unknown");
- return token.label;
- }
- set {
- }
- }
-
- public string description {
- owned get {
- var token = this._slot.get_token_info();
- if (token == null)
- return "";
- return token.manufacturer_id;
- }
- }
-
- public string uri {
- owned get { return this._uri; }
- }
-
- public GLib.Icon icon {
- owned get {
- var token = this._slot.get_token_info();
- if (token == null)
- return new GLib.ThemedIcon("dialog-question");
- return Gcr.icon_for_token(token);
- }
- }
+public class Seahorse.Pkcs11.Token : GLib.Object, GLib.ListModel, Place, Lockable {
+
+ public bool unlockable {
+ get {
+ this.ensure_token_info();
+ if ((this._info.flags & CKF.LOGIN_REQUIRED) == 0)
+ return false;
+ if ((this._info.flags & CKF.USER_PIN_INITIALIZED) == 0)
+ return false;
+ return !is_session_logged_in(this._session);
+ }
+ }
+
+ public bool lockable {
+ get {
+ this.ensure_token_info();
+ if ((this._info.flags & CKF.LOGIN_REQUIRED) == 0)
+ return false;
+ if ((this._info.flags & CKF.USER_PIN_INITIALIZED) == 0)
+ return false;
+ return is_session_logged_in(this._session);
+ }
+ }
+
+ public Gck.TokenInfo info {
+ get { return this.ensure_token_info(); }
+ }
+
+ public Gck.Session session {
+ get { return this._session; }
+ set {
+ this._session = session;
+ notify_property("session");
+ notify_property("lockable");
+ notify_property("unlockable");
+ }
+ }
+
+ public Gck.Slot slot {
+ get { return this._slot; }
+ construct { this._slot = value; }
+ }
+
+ public string label {
+ owned get {
+ var token = this._slot.get_token_info();
+ if (token == null)
+ return C_("Label", "Unknown");
+ return token.label;
+ }
+ set {
+ }
+ }
+
+ public string description {
+ owned get {
+ var token = this._slot.get_token_info();
+ if (token == null)
+ return "";
+ return token.manufacturer_id;
+ }
+ }
+
+ public string uri {
+ owned get { return this._uri; }
+ }
public Place.Category category {
get { return Place.Category.CERTIFICATES; }
@@ -116,393 +104,390 @@ public class Token : GLib.Object, Gcr.Collection, Place, Lockable {
owned get { return null; }
}
- public Flags object_flags {
- get { return 0; }
- }
-
- public bool show_if_empty {
- get { return false; }
- }
-
- public unowned GLib.Array<ulong> mechanisms {
- get {
- if (this._mechanisms == null)
- this._mechanisms = this._slot.get_mechanisms();
- return this._mechanisms;
- }
- }
-
- private Gck.Slot _slot;
- private string _uri;
- private Gck.TokenInfo? _info;
- private GLib.Array<ulong> _mechanisms;
- private Gck.Session? _session;
- private GLib.HashTable<ulong?, GLib.Object> _object_for_handle;
- private GLib.HashTable<Gck.Attribute, GLib.GenericArray<GLib.Object>> _objects_for_id;
- private GLib.HashTable<GLib.Object, unowned Gck.Attribute> _id_for_object;
- private GLib.HashTable<GLib.Object, GLib.Object> _objects_visible;
-
- public Token(Gck.Slot slot) {
- GLib.Object(
- slot: slot
- );
- }
-
- construct {
- this._object_for_handle = new GLib.HashTable<ulong?, GLib.Object>(ulong_hash, ulong_equal);
- this._objects_for_id = new GLib.HashTable<Gck.Attribute,
GLib.GenericArray<GLib.Object>>(Gck.Attribute.hash, Gck.Attribute.equal);
- this._id_for_object = new GLib.HashTable<GLib.Object, unowned
Gck.Attribute>(GLib.direct_hash, GLib.direct_equal);
- this._objects_visible = new GLib.HashTable<GLib.Object, GLib.Object>(GLib.direct_hash,
GLib.direct_equal);
-
- /* TODO: Does this happen in the background? It really should. */
- this.load.begin(null);
-
- var data = new Gck.UriData();
- this.ensure_token_info();
- data.token_info = this._info;
- this._uri = Gck.uri_build(data, Gck.UriFlags.FOR_TOKEN);
- }
-
- public override void dispose() {
- this._slot = null;
- this._session = null;
- }
-
- public async bool lock(GLib.TlsInteraction? interaction,
- GLib.Cancellable? cancellable) throws GLib.Error {
- if (!is_session_logged_in(this._session))
- return true;
-
- yield this._session.logout_async(cancellable);
- return yield this.load(cancellable);
- }
-
- public async bool unlock(GLib.TlsInteraction? interaction,
- GLib.Cancellable? cancellable) throws GLib.Error {
- if (is_session_logged_in (this._session))
- return true;
- if (this._session != null) {
- return yield this._session.login_interactive_async(CKU.USER, interaction,
cancellable);
- } else {
- var options = calculate_session_options();
- this._session = yield this._slot.open_session_async(options |
Gck.SessionOptions.LOGIN_USER,
- cancellable);
- return true;
- }
- }
-
- public bool contains (GLib.Object object) {
- return this._objects_visible.lookup(object) != null;
- }
-
- public uint get_length() {
- return this._objects_visible.size();
- }
-
- public GLib.List<weak GLib.Object> get_objects() {
- return this._objects_visible.get_values();
- }
-
- public bool is_deletable(Gck.Object object) {
- this.ensure_token_info();
-
- if ((this._info.flags & CKF.WRITE_PROTECTED) == CKF.WRITE_PROTECTED)
- return false;
-
- Gck.Attributes? attributes;
- object.get("attributes", out attributes);
-
- if (attributes != null) {
- bool ret = true;
- attributes.find_boolean(CKA.MODIFIABLE, out ret);
- return ret;
- }
-
- return false;
- }
-
- public void remove_object(Gck.Object object) {
- GLib.List<Gck.Object> objects = null;
- objects.append(object);
- remove_objects(objects.copy());
- }
-
- public bool has_mechanism(ulong mechanism) {
- return Gck.mechanisms_check(this.mechanisms, mechanism, Gck.INVALID);
- }
-
- private static bool is_session_logged_in(Gck.Session? session) {
- if (session == null)
- return false;
- var info = session.get_info();
- return (info != null) &&
- (info.state == CKS.RW_USER_FUNCTIONS ||
- info.state == CKS.RO_USER_FUNCTIONS ||
- info.state == CKS.RW_SO_FUNCTIONS);
- }
-
- private unowned Gck.TokenInfo ensure_token_info() {
- if (this._info == null)
- this.update_token_info();
- return this._info;
- }
-
- private void update_token_info() {
- var info = this._slot.get_token_info();
- if (info != null) {
- this._info = info;
- this.notify_property("info");
- this.notify_property("lockable");
- this.notify_property("unlockable");
- }
- }
-
- private void update_id_map(GLib.Object object,
- Gck.Attribute* id) {
- bool add = false;
- bool remove = false;
-
- var pid = this._id_for_object.lookup(object);
- if (id == null) {
- if (pid != null) {
- id = pid;
- remove = true;
- }
- } else {
- if (pid == null) {
- add = true;
- } else if (!id->equal(pid)) {
- remove = true;
- add = true;
- }
- }
-
- if (add) {
- unowned GLib.GenericArray<GLib.Object>? objects;
- objects = this._objects_for_id.lookup(id);
- if (objects == null) {
- var objs = new GLib.GenericArray<GLib.Object>();
- this._objects_for_id.insert(id, objs);
- objects = objs;
- }
- objects.add(object);
- this._id_for_object.insert(object, id);
- }
-
- /* Remove this object from the map */
- if (remove) {
- if (!this._id_for_object.remove(object))
- GLib.assert_not_reached();
- var objects = this._objects_for_id.lookup(id);
- GLib.assert(objects != null);
- GLib.assert(objects.length > 0);
- if (objects.length == 1) {
- if (!this._objects_for_id.remove(id))
- GLib.assert_not_reached();
- } else {
- if (!objects.remove(object))
- GLib.assert_not_reached();
- }
- }
- }
-
- private GLib.Object? lookup_id_map(GLib.Type object_type,
- Gck.Attribute* id) {
- if (id == null)
- return null;
- var objects = this._objects_for_id.lookup(id);
- if (objects == null)
- return null;
- for (var i = 0; i < objects.length; i++) {
- if (objects[i].get_type().is_a(object_type))
- return objects[i];
- }
- return null;
- }
-
- private void update_visibility(GLib.List<GLib.Object> objects,
- bool visible) {
- foreach (var object in objects) {
- bool have = (this._objects_visible.lookup(object) != null);
- if (!have && visible) {
- this._objects_visible.insert(object, object);
- this.emit_added(object);
- } else if (have && !visible) {
- if (!this._objects_visible.remove(object))
- GLib.assert_not_reached();
- this.emit_removed(object);
- }
- }
-
- }
-
- private static bool make_certificate_key_pair(Certificate certificate,
- PrivateKey private_key) {
- if (certificate.partner != null || private_key.partner != null)
- return false;
- certificate.partner = private_key;
- private_key.partner = certificate;
- return true;
- }
-
- private static GLib.Object? break_certificate_key_pair(GLib.Object object) {
- GLib.Object? pair = null;
- if (object is Certificate) {
- var certificate = (Certificate)object;
- pair = certificate.partner;
- certificate.partner = null;
- } else if (object is PrivateKey) {
- var private_key = (PrivateKey)object;
- pair = private_key.partner;
- private_key.partner = null;
- }
- return pair;
- }
-
- private void receive_objects(GLib.List<GLib.Object> objects) {
- var show = new GLib.List<GLib.Object>();
- var hide = new GLib.List<GLib.Object>();
-
- foreach (var object in objects) {
- if (!(object is Gck.Object && object is Gck.ObjectCache))
- continue;
- var handle = ((Gck.Object)object).handle;
- var attrs = ((Gck.ObjectCache)object).attributes;
-
- var prev = this._object_for_handle.lookup(handle);
- if (prev == null) {
- this._object_for_handle.insert(handle, object);
- object.set("place", this);
- } else if (prev != object) {
- object.set("attributes", attrs);
- object = prev;
- }
-
- unowned Gck.Attribute? id = null;
- if (attrs != null)
- id = attrs.find(CKA.ID);
- this.update_id_map(object, id);
-
- if (object is Certificate) {
- var pair = this.lookup_id_map(typeof(PrivateKey), id);
- if (pair != null && make_certificate_key_pair((Certificate)object,
(PrivateKey)pair))
- hide.prepend(pair);
- show.prepend(object);
- } else if (object is PrivateKey) {
- var pair = this.lookup_id_map(typeof(Certificate), id);
- if (pair != null && make_certificate_key_pair((Certificate)pair,
(PrivateKey)object))
- hide.prepend(object);
- else
- show.prepend(object);
- } else {
- show.prepend(object);
- }
- }
-
- update_visibility(hide, false);
- update_visibility(show, true);
- }
-
- private void remove_objects(GLib.List<weak GLib.Object> objects) {
- var depaired = new GLib.List<GLib.Object>();
- var hide = new GLib.List<GLib.Object>();
-
- foreach (var object in objects) {
- var pair = break_certificate_key_pair(object);
- if (pair != null)
- depaired.prepend(pair);
- update_id_map(object, null);
- hide.prepend(object);
- }
-
- /* Remove the ownership of these */
- foreach (var object in objects) {
- var handle = ((Gck.Object)object).handle;
- object.set("place", null);
- this._object_for_handle.remove(handle);
- }
-
- update_visibility(hide, false);
-
- /* Add everything that was paired */
- receive_objects(depaired);
- }
-
- private Gck.SessionOptions calculate_session_options() {
- this.ensure_token_info();
- if ((this._info.flags & CKF.WRITE_PROTECTED) == CKF.WRITE_PROTECTED)
- return Gck.SessionOptions.READ_ONLY;
- else
- return Gck.SessionOptions.READ_WRITE;
- }
-
- public async bool load(GLib.Cancellable? cancellable) throws GLib.Error {
- var checks = new GLib.HashTable<ulong?, GLib.Object>(ulong_hash, ulong_equal);
-
- /* Make note of all the objects that were there */
- this.update_token_info();
- foreach (var object in this.get_objects()) {
- var handle = ((Gck.Object)object).handle;
- checks.insert(handle, object);
- }
-
- if (this._session == null) {
- var options = this.calculate_session_options();
- this._session = yield this._slot.open_session_async(options, cancellable);
- }
-
- var builder = new Gck.Builder(Gck.BuilderFlags.NONE);
- builder.add_boolean(CKA.TOKEN, true);
- builder.add_ulong(CKA.CLASS, CKO.CERTIFICATE);
-
- const ulong[] CERTIFICATE_ATTRS = {
- CKA.VALUE,
- CKA.ID,
- CKA.LABEL,
- CKA.CLASS,
- CKA.CERTIFICATE_CATEGORY,
- CKA.MODIFIABLE
- };
-
- var enumerator = this._session.enumerate_objects(builder.end());
- enumerator.set_object_type(typeof(Certificate), CERTIFICATE_ATTRS);
-
- builder = new Gck.Builder(Gck.BuilderFlags.NONE);
- builder.add_boolean(CKA.TOKEN, true);
- builder.add_ulong(CKA.CLASS, CKO.PRIVATE_KEY);
-
- const ulong[] KEY_ATTRS = {
- CKA.MODULUS_BITS,
- CKA.ID,
- CKA.LABEL,
- CKA.CLASS,
- CKA.KEY_TYPE,
- CKA.MODIFIABLE,
- };
-
- var chained = this._session.enumerate_objects(builder.end());
- chained.set_object_type(typeof(PrivateKey), KEY_ATTRS);
- enumerator.set_chained(chained);
-
- for (;;) {
- var objects = yield enumerator.next_async(16, cancellable);
-
- /* Otherwise we're done, remove everything not found */
- if (objects == null) {
- remove_objects(checks.get_values());
- return true;
- }
-
- this.receive_objects(objects);
-
- /* Remove all objects that were found from the check table */
- foreach (var object in objects) {
- var handle = ((Gck.Object)object).handle;
- checks.remove(handle);
- }
- }
- }
-}
+ public Flags object_flags {
+ get { return 0; }
+ }
-}
+ public unowned GLib.Array<ulong> mechanisms {
+ get {
+ if (this._mechanisms == null)
+ this._mechanisms = this._slot.get_mechanisms();
+ return this._mechanisms;
+ }
+ }
+
+ private Gck.Slot _slot;
+ private string _uri;
+ private Gck.TokenInfo? _info;
+ private GLib.Array<ulong> _mechanisms;
+ private Gck.Session? _session;
+ private GLib.HashTable<ulong?, GLib.Object> _object_for_handle;
+ private GLib.HashTable<Gck.Attribute, GLib.GenericArray<GLib.Object>> _objects_for_id;
+ private GLib.HashTable<GLib.Object, unowned Gck.Attribute> _id_for_object;
+
+ private GenericArray<GLib.Object> objects_visible;
+
+ public Token(Gck.Slot slot) {
+ GLib.Object(
+ slot: slot
+ );
+ }
+
+ construct {
+ this._object_for_handle = new GLib.HashTable<ulong?, GLib.Object>(ulong_hash, ulong_equal);
+ this._objects_for_id = new GLib.HashTable<Gck.Attribute,
GLib.GenericArray<GLib.Object>>(Gck.Attribute.hash, Gck.Attribute.equal);
+ this._id_for_object = new GLib.HashTable<GLib.Object, unowned Gck.Attribute>(GLib.direct_hash,
GLib.direct_equal);
+ this.objects_visible = new GenericArray<GLib.Object>();
+
+ /* TODO: Does this happen in the background? It really should. */
+ this.load.begin(null);
+
+ var data = new Gck.UriData();
+ this.ensure_token_info();
+ data.token_info = this._info;
+ this._uri = data.build(Gck.UriFlags.FOR_TOKEN);
+ }
+
+ public override void dispose() {
+ this._slot = null;
+ this._session = null;
+ }
+
+ public async bool lock(GLib.TlsInteraction? interaction,
+ GLib.Cancellable? cancellable) throws GLib.Error {
+ if (!is_session_logged_in(this._session))
+ return true;
+
+ yield this._session.logout_async(cancellable);
+ return yield this.load(cancellable);
+ }
+
+ public async bool unlock(GLib.TlsInteraction? interaction,
+ GLib.Cancellable? cancellable) throws GLib.Error {
+ if (is_session_logged_in (this._session))
+ return true;
+ if (this._session != null) {
+ return yield this._session.login_interactive_async(CKU.USER, interaction, cancellable);
+ } else {
+ var options = calculate_session_options();
+ this._session = yield this._slot.open_session_async(options | Gck.SessionOptions.LOGIN_USER,
+ null,
+ cancellable);
+ return true;
+ }
+ }
+
+ public GLib.Type get_item_type() {
+ return typeof(GLib.Object);
+ }
+
+ public uint get_n_items() {
+ return this.objects_visible.length;
+ }
+
+ public GLib.Object? get_item(uint i) {
+ if (i >= this.objects_visible.length)
+ return null;
+ return this.objects_visible[i];
+ }
+
+ public bool is_deletable(Gck.Object object) {
+ this.ensure_token_info();
+
+ if ((this._info.flags & CKF.WRITE_PROTECTED) == CKF.WRITE_PROTECTED)
+ return false;
+
+ Gck.Attributes? attributes;
+ object.get("attributes", out attributes);
+
+ if (attributes != null) {
+ bool ret = true;
+ attributes.find_boolean(CKA.MODIFIABLE, out ret);
+ return ret;
+ }
+
+ return false;
+ }
+
+ public void remove_object(Gck.Object object) {
+ GLib.List<Gck.Object> objects = null;
+ objects.append(object);
+ remove_objects(objects.copy());
+ }
+
+ public bool has_mechanism(ulong mechanism) {
+ return Gck.mechanisms_check(this.mechanisms, mechanism, Gck.INVALID);
+ }
+
+ private static bool is_session_logged_in(Gck.Session? session) {
+ if (session == null)
+ return false;
+ var info = session.get_info();
+ return (info != null) &&
+ (info.state == CKS.RW_USER_FUNCTIONS ||
+ info.state == CKS.RO_USER_FUNCTIONS ||
+ info.state == CKS.RW_SO_FUNCTIONS);
+ }
+
+ private unowned Gck.TokenInfo ensure_token_info() {
+ if (this._info == null)
+ this.update_token_info();
+ return this._info;
+ }
+
+ private void update_token_info() {
+ var info = this._slot.get_token_info();
+ if (info != null) {
+ this._info = info;
+ this.notify_property("info");
+ this.notify_property("lockable");
+ this.notify_property("unlockable");
+ }
+ }
+
+ private void update_id_map(GLib.Object object,
+ Gck.Attribute* id) {
+ bool add = false;
+ bool remove = false;
+
+ var pid = this._id_for_object.lookup(object);
+ if (id == null) {
+ if (pid != null) {
+ id = pid;
+ remove = true;
+ }
+ } else {
+ if (pid == null) {
+ add = true;
+ } else if (!id->equal(pid)) {
+ remove = true;
+ add = true;
+ }
+ }
+
+ if (add) {
+ unowned GLib.GenericArray<GLib.Object>? objects;
+ objects = this._objects_for_id.lookup(id);
+ if (objects == null) {
+ var objs = new GLib.GenericArray<GLib.Object>();
+ this._objects_for_id.insert(id, objs);
+ objects = objs;
+ }
+ objects.add(object);
+ this._id_for_object.insert(object, id);
+ }
+
+ /* Remove this object from the map */
+ if (remove) {
+ if (!this._id_for_object.remove(object))
+ GLib.assert_not_reached();
+ var objects = this._objects_for_id.lookup(id);
+ GLib.assert(objects != null);
+ GLib.assert(objects.length > 0);
+ if (objects.length == 1) {
+ if (!this._objects_for_id.remove(id))
+ GLib.assert_not_reached();
+ } else {
+ if (!objects.remove(object))
+ GLib.assert_not_reached();
+ }
+ }
+ }
+
+ private GLib.Object? lookup_id_map(GLib.Type object_type,
+ Gck.Attribute* id) {
+ if (id == null)
+ return null;
+ var objects = this._objects_for_id.lookup(id);
+ if (objects == null)
+ return null;
+ for (var i = 0; i < objects.length; i++) {
+ if (objects[i].get_type().is_a(object_type))
+ return objects[i];
+ }
+ return null;
+ }
+
+ private void update_visibility(GLib.List<GLib.Object> objects,
+ bool visible) {
+ foreach (var object in objects) {
+ uint position;
+ bool have = this.objects_visible.find(object, out position);
+ if (!have && visible) {
+ this.objects_visible.add(object);
+ items_changed(this.objects_visible.length - 1, 0, 1);
+ } else if (have && !visible) {
+ this.objects_visible.remove_index(position);
+ items_changed(position, 1, 0);
+ }
+ }
+
+ }
+
+ private static bool make_certificate_key_pair(Certificate certificate,
+ PrivateKey private_key) {
+ if (certificate.partner != null || private_key.partner != null)
+ return false;
+ certificate.partner = private_key;
+ private_key.partner = certificate;
+ return true;
+ }
+
+ private static GLib.Object? break_certificate_key_pair(GLib.Object object) {
+ GLib.Object? pair = null;
+ if (object is Certificate) {
+ var certificate = (Certificate)object;
+ pair = certificate.partner;
+ certificate.partner = null;
+ } else if (object is PrivateKey) {
+ var private_key = (PrivateKey)object;
+ pair = private_key.partner;
+ private_key.partner = null;
+ }
+ return pair;
+ }
+
+ private void receive_objects(GLib.List<GLib.Object> objects) {
+ var show = new GLib.List<GLib.Object>();
+ var hide = new GLib.List<GLib.Object>();
+
+ foreach (var object in objects) {
+ if (!(object is Gck.Object && object is Gck.ObjectCache))
+ continue;
+ var handle = ((Gck.Object)object).handle;
+ var attrs = ((Gck.ObjectCache)object).attributes;
+
+ var prev = this._object_for_handle.lookup(handle);
+ if (prev == null) {
+ this._object_for_handle.insert(handle, object);
+ object.set("place", this);
+ } else if (prev != object) {
+ object.set("attributes", attrs);
+ object = prev;
+ }
+
+ unowned Gck.Attribute? id = null;
+ if (attrs != null)
+ id = attrs.find(CKA.ID);
+ this.update_id_map(object, id);
+
+ if (object is Certificate) {
+ var pair = this.lookup_id_map(typeof(PrivateKey), id);
+ if (pair != null && make_certificate_key_pair((Certificate)object, (PrivateKey)pair))
+ hide.prepend(pair);
+ show.prepend(object);
+ } else if (object is PrivateKey) {
+ var pair = this.lookup_id_map(typeof(Certificate), id);
+ if (pair != null && make_certificate_key_pair((Certificate)pair, (PrivateKey)object))
+ hide.prepend(object);
+ else
+ show.prepend(object);
+ } else {
+ show.prepend(object);
+ }
+ }
+
+ update_visibility(hide, false);
+ update_visibility(show, true);
+ }
+
+ private void remove_objects(GLib.List<weak GLib.Object> objects) {
+ var depaired = new GLib.List<GLib.Object>();
+ var hide = new GLib.List<GLib.Object>();
+
+ foreach (var object in objects) {
+ var pair = break_certificate_key_pair(object);
+ if (pair != null)
+ depaired.prepend(pair);
+ update_id_map(object, null);
+ hide.prepend(object);
+ }
+
+ /* Remove the ownership of these */
+ foreach (var object in objects) {
+ var handle = ((Gck.Object)object).handle;
+ object.set("place", null);
+ this._object_for_handle.remove(handle);
+ }
+
+ update_visibility(hide, false);
+
+ /* Add everything that was paired */
+ receive_objects(depaired);
+ }
+
+ private Gck.SessionOptions calculate_session_options() {
+ this.ensure_token_info();
+ if ((this._info.flags & CKF.WRITE_PROTECTED) == CKF.WRITE_PROTECTED)
+ return Gck.SessionOptions.READ_ONLY;
+ else
+ return Gck.SessionOptions.READ_WRITE;
+ }
+
+ public async bool load(GLib.Cancellable? cancellable) throws GLib.Error {
+ var checks = new GLib.HashTable<ulong?, GLib.Object>(ulong_hash, ulong_equal);
+
+ /* Make note of all the objects that were there */
+ this.update_token_info();
+ for (uint i = 0; i < get_n_items(); i++) {
+ var object = (Gck.Object) get_item(i);
+ checks.insert(object.handle, object);
+ }
+
+ if (this._session == null) {
+ var options = this.calculate_session_options();
+ this._session = yield this._slot.open_session_async(options, null, cancellable);
+ }
+
+ var builder = new Gck.Builder(Gck.BuilderFlags.NONE);
+ builder.add_boolean(CKA.TOKEN, true);
+ builder.add_ulong(CKA.CLASS, CKO.CERTIFICATE);
+
+ const ulong[] CERTIFICATE_ATTRS = {
+ CKA.VALUE,
+ CKA.ID,
+ CKA.LABEL,
+ CKA.CLASS,
+ CKA.CERTIFICATE_CATEGORY,
+ CKA.MODIFIABLE
+ };
+
+ var enumerator = this._session.enumerate_objects(builder.end());
+ enumerator.set_object_type(typeof(Certificate), CERTIFICATE_ATTRS);
+
+ builder = new Gck.Builder(Gck.BuilderFlags.NONE);
+ builder.add_boolean(CKA.TOKEN, true);
+ builder.add_ulong(CKA.CLASS, CKO.PRIVATE_KEY);
+
+ const ulong[] KEY_ATTRS = {
+ CKA.MODULUS_BITS,
+ CKA.ID,
+ CKA.LABEL,
+ CKA.CLASS,
+ CKA.KEY_TYPE,
+ CKA.MODIFIABLE,
+ };
+
+ var chained = this._session.enumerate_objects(builder.end());
+ chained.set_object_type(typeof(PrivateKey), KEY_ATTRS);
+ enumerator.set_chained(chained);
+
+ for (;;) {
+ var objects = yield enumerator.next_async(16, cancellable);
+
+ /* Otherwise we're done, remove everything not found */
+ if (objects == null) {
+ remove_objects(checks.get_values());
+ return true;
+ }
+
+ this.receive_objects(objects);
+
+ /* Remove all objects that were found from the check table */
+ foreach (var object in objects) {
+ var handle = ((Gck.Object)object).handle;
+ checks.remove(handle);
+ }
+ }
+ }
}
diff --git a/pkcs11/seahorse-pkcs11-backend.c b/pkcs11/seahorse-pkcs11-backend.c
index b7ea21e1..297cb175 100644
--- a/pkcs11/seahorse-pkcs11-backend.c
+++ b/pkcs11/seahorse-pkcs11-backend.c
@@ -28,19 +28,17 @@
#include "libseahorse/seahorse-util.h"
-#include <gcr/gcr-base.h>
-
#include <gck/gck.h>
#include <glib/gi18n.h>
enum {
- PROP_0,
- PROP_NAME,
- PROP_LABEL,
- PROP_DESCRIPTION,
- PROP_ACTIONS,
- PROP_LOADED,
+ PROP_0,
+ PROP_NAME,
+ PROP_LABEL,
+ PROP_DESCRIPTION,
+ PROP_ACTIONS,
+ PROP_LOADED,
};
void seahorse_pkcs11_backend_initialize (void);
@@ -48,22 +46,24 @@ void seahorse_pkcs11_backend_initialize (void);
static SeahorsePkcs11Backend *pkcs11_backend = NULL;
struct _SeahorsePkcs11Backend {
- GObject parent;
- SeahorseActionGroup *actions;
- GList *tokens;
- GList *blacklist;
- gboolean loaded;
+ GObject parent;
+ SeahorseActionGroup *actions;
+ GList *blacklist;
+ gboolean loaded;
+
+ GPtrArray *tokens;
+ GPtrArray *tokens_visible;
};
struct _SeahorsePkcs11BackendClass {
- GObjectClass parent_class;
+ GObjectClass parent_class;
};
static const char *token_blacklist[] = {
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SSH:HOME",
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SECRET:MAIN",
- "pkcs11:manufacturer=Mozilla%20Foundation;token=NSS%20Generic%20Crypto%20Services",
- NULL
+ "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SSH:HOME",
+ "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SECRET:MAIN",
+ "pkcs11:manufacturer=Mozilla%20Foundation;token=NSS%20Generic%20Crypto%20Services",
+ NULL
};
static void
@@ -75,10 +75,10 @@ static const GActionEntry ACTION_ENTRIES[] = {
static void seahorse_pkcs11_backend_iface (SeahorseBackendIface *iface);
-static void seahorse_pkcs11_backend_collection_init (GcrCollectionIface *iface);
+static void seahorse_pkcs11_backend_list_model_init (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (SeahorsePkcs11Backend, seahorse_pkcs11_backend, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_pkcs11_backend_collection_init)
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, seahorse_pkcs11_backend_list_model_init)
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_BACKEND, seahorse_pkcs11_backend_iface);
);
@@ -97,21 +97,23 @@ init_actions (SeahorsePkcs11Backend *self)
static void
seahorse_pkcs11_backend_init (SeahorsePkcs11Backend *self)
{
- GError *error = NULL;
- GckUriData *uri;
- guint i;
-
- g_return_if_fail (pkcs11_backend == NULL);
- pkcs11_backend = self;
-
- for (i = 0; token_blacklist[i] != NULL; i++) {
- uri = gck_uri_parse (token_blacklist[i], GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, &error);
- if (uri == NULL) {
- g_warning ("couldn't parse pkcs11 blacklist uri: %s", error->message);
- g_clear_error (&error);
- }
- self->blacklist = g_list_prepend (self->blacklist, uri);
- }
+
+ g_return_if_fail (pkcs11_backend == NULL);
+ pkcs11_backend = self;
+
+ self->tokens = g_ptr_array_new_with_free_func (g_object_unref);
+ self->tokens_visible = g_ptr_array_new ();
+
+ for (unsigned int i = 0; token_blacklist[i] != NULL; i++) {
+ g_autoptr(GError) error = NULL;
+ GckUriData *uri;
+
+ uri = gck_uri_data_parse (token_blacklist[i], GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, &error);
+ if (uri == NULL) {
+ g_warning ("couldn't parse pkcs11 blacklist uri: %s", error->message);
+ }
+ self->blacklist = g_list_prepend (self->blacklist, uri);
+ }
init_actions (self);
}
@@ -121,24 +123,61 @@ is_token_usable (SeahorsePkcs11Backend *self,
GckSlot *slot,
GckTokenInfo *token)
{
- GList *l;
-
- if (!(token->flags & CKF_TOKEN_INITIALIZED)) {
- /* _gcr_debug ("token is not importable: %s: not initialized", token->label); */
- return FALSE;
- }
- if ((token->flags & CKF_LOGIN_REQUIRED) &&
- !(token->flags & CKF_USER_PIN_INITIALIZED)) {
- /* _gcr_debug ("token is not importable: %s: user pin not initialized", token->label); */
- return FALSE;
- }
-
- for (l = self->blacklist; l != NULL; l = g_list_next (l)) {
- if (gck_slot_match (slot, l->data))
- return FALSE;
- }
-
- return TRUE;
+ if (!(token->flags & CKF_TOKEN_INITIALIZED)) {
+ /* _gcr_debug ("token is not importable: %s: not initialized", token->label); */
+ return FALSE;
+ }
+ if ((token->flags & CKF_LOGIN_REQUIRED) &&
+ !(token->flags & CKF_USER_PIN_INITIALIZED)) {
+ /* _gcr_debug ("token is not importable: %s: user pin not initialized", token->label); */
+ return FALSE;
+ }
+
+ for (GList *l = self->blacklist; l != NULL; l = g_list_next (l)) {
+ if (gck_slot_match (slot, l->data))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* We only expose non-empty tokens */
+static void
+on_token_items_changed (GListModel *list,
+ unsigned int position,
+ unsigned int removed,
+ unsigned int added,
+ void *user_data)
+{
+ SeahorsePkcs11Token *token = SEAHORSE_PKCS11_TOKEN (list);
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (user_data);
+ unsigned int n_items;
+ gboolean was_empty, is_empty;
+
+ n_items = g_list_model_get_n_items (list);
+ is_empty = (n_items == 0);
+ was_empty = (n_items + removed - added == 0);
+
+ if (is_empty == was_empty)
+ return;
+
+ /* Token was empty, but no longer is: add to exposed items */
+ if (was_empty) {
+ g_return_if_fail (!g_ptr_array_find (self->tokens_visible, token, NULL));
+ g_ptr_array_add (self->tokens_visible, token);
+ g_list_model_items_changed (G_LIST_MODEL (self), self->tokens_visible->len - 1, 0, 1);
+ }
+
+ /* Token was not empty, but now is: remove from exposed items */
+ if (is_empty) {
+ gboolean found;
+ unsigned int pos;
+
+ found = g_ptr_array_find (self->tokens_visible, token, &pos);
+ g_return_if_fail (found);
+ g_ptr_array_remove_index (self->tokens_visible, pos);
+ g_list_model_items_changed (G_LIST_MODEL (self), pos, 1, 0);
+ }
}
static void
@@ -146,79 +185,79 @@ on_initialized_registered (GObject *unused,
GAsyncResult *result,
gpointer user_data)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (user_data);
- SeahorsePlace *place;
- GList *slots, *s;
- GList *modules, *m;
- GError *error = NULL;
- GckTokenInfo *token;
-
- modules = gck_modules_initialize_registered_finish (result, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
-
- for (m = modules; m != NULL; m = g_list_next (m)) {
- slots = gck_module_get_slots (m->data, TRUE);
- for (s = slots; s; s = g_list_next (s)) {
- token = gck_slot_get_token_info (s->data);
- if (token == NULL)
- continue;
- if (is_token_usable (self, s->data, token)) {
- place = SEAHORSE_PLACE (seahorse_pkcs11_token_new (s->data));
- self->tokens = g_list_append (self->tokens, place);
- gcr_collection_emit_added (GCR_COLLECTION (self), G_OBJECT (place));
- }
- gck_token_info_free (token);
- }
-
- /* These will have been refed by the source above */
- gck_list_unref_free (slots);
- }
-
- self->loaded = TRUE;
- g_object_notify (G_OBJECT (self), "loaded");
-
- gck_list_unref_free (modules);
- g_object_unref (self);
+ g_autoptr(SeahorsePkcs11Backend) self = SEAHORSE_PKCS11_BACKEND (user_data);
+ g_autolist(GckModule) modules = NULL;
+ g_autoptr(GError) error = NULL;
+
+ modules = gck_modules_initialize_registered_finish (result, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ }
+
+ for (GList *m = modules; m != NULL; m = g_list_next (m)) {
+ g_autolist(GckSlot) slots = NULL;
+
+ slots = gck_module_get_slots (m->data, TRUE);
+ for (GList *s = slots; s; s = g_list_next (s)) {
+ g_autoptr(GckTokenInfo) info = NULL;
+ SeahorsePkcs11Token *token;
+
+ info = gck_slot_get_token_info (s->data);
+ if (info == NULL || !is_token_usable (self, s->data, info))
+ continue;
+
+ token = seahorse_pkcs11_token_new (s->data);
+ g_ptr_array_add (self->tokens, token);
+
+ if (g_list_model_get_n_items (G_LIST_MODEL (token)) > 0) {
+ g_ptr_array_add (self->tokens_visible, token);
+ g_list_model_items_changed (G_LIST_MODEL (self),
+ self->tokens_visible->len - 1,
+ 0, 1);
+ }
+ g_signal_connect (token, "items-changed", G_CALLBACK (on_token_items_changed), self);
+ }
+ }
+
+ self->loaded = TRUE;
+ g_object_notify (G_OBJECT (self), "loaded");
}
static void
seahorse_pkcs11_backend_constructed (GObject *obj)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
- G_OBJECT_CLASS (seahorse_pkcs11_backend_parent_class)->constructed (obj);
+ G_OBJECT_CLASS (seahorse_pkcs11_backend_parent_class)->constructed (obj);
- gck_modules_initialize_registered_async (NULL, on_initialized_registered,
- g_object_ref (self));
+ gck_modules_initialize_registered_async (NULL, on_initialized_registered,
+ g_object_ref (self));
}
static const gchar *
seahorse_pkcs11_backend_get_name (SeahorseBackend *backend)
{
- return SEAHORSE_PKCS11_NAME;
+ return SEAHORSE_PKCS11_NAME;
}
static const gchar *
seahorse_pkcs11_backend_get_label (SeahorseBackend *backend)
{
- return _("Certificates");
+ return _("Certificates");
}
static const gchar *
seahorse_pkcs11_backend_get_description (SeahorseBackend *backend)
{
- return _("X.509 certificates and related keys");
+ return _("X.509 certificates and related keys");
}
static gboolean
seahorse_pkcs11_backend_get_loaded (SeahorseBackend *backend)
{
- g_return_val_if_fail (SEAHORSE_IS_PKCS11_BACKEND (backend), FALSE);
+ g_return_val_if_fail (SEAHORSE_IS_PKCS11_BACKEND (backend), FALSE);
- return SEAHORSE_PKCS11_BACKEND (backend)->loaded;
+ return SEAHORSE_PKCS11_BACKEND (backend)->loaded;
}
static SeahorseActionGroup *
@@ -233,197 +272,147 @@ seahorse_pkcs11_backend_get_property (GObject *obj,
GValue *value,
GParamSpec *pspec)
{
- SeahorseBackend *backend = SEAHORSE_BACKEND (obj);
-
- switch (prop_id) {
- case PROP_NAME:
- g_value_set_string (value, seahorse_pkcs11_backend_get_name (backend));
- break;
- case PROP_LABEL:
- g_value_set_string (value, seahorse_pkcs11_backend_get_label (backend));
- break;
- case PROP_DESCRIPTION:
- g_value_set_string (value, seahorse_pkcs11_backend_get_description (backend));
- break;
- case PROP_ACTIONS:
- g_value_take_object (value, seahorse_pkcs11_backend_get_actions (backend));
- break;
- case PROP_LOADED:
- g_value_set_boolean (value, seahorse_pkcs11_backend_get_loaded (backend));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-seahorse_pkcs11_backend_dispose (GObject *obj)
-{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
-
- g_list_free_full (self->tokens, g_object_unref);
- self->tokens = NULL;
-
- G_OBJECT_CLASS (seahorse_pkcs11_backend_parent_class)->dispose (obj);
+ SeahorseBackend *backend = SEAHORSE_BACKEND (obj);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, seahorse_pkcs11_backend_get_name (backend));
+ break;
+ case PROP_LABEL:
+ g_value_set_string (value, seahorse_pkcs11_backend_get_label (backend));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, seahorse_pkcs11_backend_get_description (backend));
+ break;
+ case PROP_ACTIONS:
+ g_value_take_object (value, seahorse_pkcs11_backend_get_actions (backend));
+ break;
+ case PROP_LOADED:
+ g_value_set_boolean (value, seahorse_pkcs11_backend_get_loaded (backend));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
}
static void
seahorse_pkcs11_backend_finalize (GObject *obj)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
- g_list_free_full (self->blacklist, (GDestroyNotify)gck_uri_data_free);
+ g_list_free_full (self->blacklist, (GDestroyNotify)gck_uri_data_free);
g_clear_object (&self->actions);
- g_assert (self->tokens == NULL);
- g_return_if_fail (pkcs11_backend == self);
- pkcs11_backend = NULL;
+ g_clear_pointer (&self->tokens_visible, g_ptr_array_unref);
+ g_clear_pointer (&self->tokens, g_ptr_array_unref);
+ g_return_if_fail (pkcs11_backend == self);
+ pkcs11_backend = NULL;
- G_OBJECT_CLASS (seahorse_pkcs11_backend_parent_class)->finalize (obj);
+ G_OBJECT_CLASS (seahorse_pkcs11_backend_parent_class)->finalize (obj);
}
static void
seahorse_pkcs11_backend_class_init (SeahorsePkcs11BackendClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructed = seahorse_pkcs11_backend_constructed;
- gobject_class->dispose = seahorse_pkcs11_backend_dispose;
- gobject_class->finalize = seahorse_pkcs11_backend_finalize;
- gobject_class->get_property = seahorse_pkcs11_backend_get_property;
-
- g_object_class_override_property (gobject_class, PROP_NAME, "name");
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
- g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
- g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
- g_object_class_override_property (gobject_class, PROP_LOADED, "loaded");
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructed = seahorse_pkcs11_backend_constructed;
+ gobject_class->finalize = seahorse_pkcs11_backend_finalize;
+ gobject_class->get_property = seahorse_pkcs11_backend_get_property;
+
+ g_object_class_override_property (gobject_class, PROP_NAME, "name");
+ g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+ g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
+ g_object_class_override_property (gobject_class, PROP_LOADED, "loaded");
}
-static guint
-seahorse_pkcs11_backend_get_length (GcrCollection *collection)
+static GType
+seahorse_pkcs11_backend_get_item_type (GListModel *model)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (collection);
- return g_list_length (self->tokens);
+ return SEAHORSE_PKCS11_TYPE_TOKEN;
}
-static GList *
-seahorse_pkcs11_backend_get_objects (GcrCollection *collection)
+static unsigned int
+seahorse_pkcs11_backend_get_n_items (GListModel *model)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (collection);
- return g_list_copy (self->tokens);
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (model);
+ return self->tokens_visible->len;
}
-static gboolean
-seahorse_pkcs11_backend_contains (GcrCollection *collection,
- GObject *object)
+static void *
+seahorse_pkcs11_backend_get_item (GListModel *model,
+ unsigned int position)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (collection);
- return g_list_find (self->tokens, object) != NULL;
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (model);
+
+ if (position >= self->tokens_visible->len)
+ return NULL;
+ return g_object_ref (g_ptr_array_index (self->tokens_visible, position));
}
static void
-seahorse_pkcs11_backend_collection_init (GcrCollectionIface *iface)
+seahorse_pkcs11_backend_list_model_init (GListModelInterface *iface)
{
- iface->contains = seahorse_pkcs11_backend_contains;
- iface->get_length = seahorse_pkcs11_backend_get_length;
- iface->get_objects = seahorse_pkcs11_backend_get_objects;
+ iface->get_item_type = seahorse_pkcs11_backend_get_item_type;
+ iface->get_n_items = seahorse_pkcs11_backend_get_n_items;
+ iface->get_item = seahorse_pkcs11_backend_get_item;
}
static SeahorsePlace *
seahorse_pkcs11_backend_lookup_place (SeahorseBackend *backend,
const gchar *uri)
{
- SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (backend);
- GckUriData *uri_data;
- GList *l;
+ SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (backend);
+ g_autoptr(GckUriData) uri_data = NULL;
+
+ if (!g_str_has_prefix (uri, "pkcs11:"))
+ return NULL;
- if (!g_str_has_prefix (uri, "pkcs11:"))
- return NULL;
+ uri_data = gck_uri_data_parse (uri, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, NULL);
+ if (uri_data == NULL)
+ return NULL;
- uri_data = gck_uri_parse (uri, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, NULL);
- if (uri_data == NULL)
- return NULL;
+ for (unsigned int i = 0; i < self->tokens->len; i++) {
+ SeahorsePkcs11Token *token = g_ptr_array_index (self->tokens, i);
- for (l = self->tokens; l != NULL; l = g_list_next (l)) {
- if (gck_slot_match (seahorse_pkcs11_token_get_slot (l->data), uri_data))
- break;
- }
+ if (gck_slot_match (seahorse_pkcs11_token_get_slot (token), uri_data))
+ return SEAHORSE_PLACE (token);
+ }
- gck_uri_data_free (uri_data);
- return l != NULL ? l->data : NULL;
+ return NULL;
}
static void
seahorse_pkcs11_backend_iface (SeahorseBackendIface *iface)
{
- iface->lookup_place = seahorse_pkcs11_backend_lookup_place;
- iface->get_actions = seahorse_pkcs11_backend_get_actions;
- iface->get_description = seahorse_pkcs11_backend_get_description;
- iface->get_label = seahorse_pkcs11_backend_get_label;
- iface->get_name = seahorse_pkcs11_backend_get_name;
- iface->get_loaded = seahorse_pkcs11_backend_get_loaded;
+ iface->lookup_place = seahorse_pkcs11_backend_lookup_place;
+ iface->get_actions = seahorse_pkcs11_backend_get_actions;
+ iface->get_description = seahorse_pkcs11_backend_get_description;
+ iface->get_label = seahorse_pkcs11_backend_get_label;
+ iface->get_name = seahorse_pkcs11_backend_get_name;
+ iface->get_loaded = seahorse_pkcs11_backend_get_loaded;
}
void
seahorse_pkcs11_backend_initialize (void)
{
- SeahorsePkcs11Backend *self;
+ SeahorsePkcs11Backend *self;
- g_return_if_fail (pkcs11_backend == NULL);
- self = g_object_new (SEAHORSE_TYPE_PKCS11_BACKEND, NULL);
+ g_return_if_fail (pkcs11_backend == NULL);
+ self = g_object_new (SEAHORSE_TYPE_PKCS11_BACKEND, NULL);
- seahorse_backend_register (SEAHORSE_BACKEND (self));
- g_object_unref (self);
+ seahorse_backend_register (SEAHORSE_BACKEND (self));
+ g_object_unref (self);
- g_return_if_fail (pkcs11_backend != NULL);
+ g_return_if_fail (pkcs11_backend != NULL);
}
SeahorsePkcs11Backend *
seahorse_pkcs11_backend_get (void)
{
- g_return_val_if_fail (pkcs11_backend, NULL);
- return pkcs11_backend;
-}
-
-static gboolean
-on_filter_writable (GObject *object,
- gpointer user_data)
-{
- SeahorsePkcs11Token *token = SEAHORSE_PKCS11_TOKEN (object);
- guint mechanism = GPOINTER_TO_UINT (user_data);
- GckTokenInfo *info;
-
- info = seahorse_pkcs11_token_get_info (token);
- g_return_val_if_fail (info != NULL, FALSE);
-
- if (info->flags & CKF_WRITE_PROTECTED)
- return FALSE;
-
- if (mechanism != G_MAXUINT) {
- if (!seahorse_pkcs11_token_has_mechanism (token, (gulong)mechanism))
- return FALSE;
- }
-
- return TRUE;
-}
-
-GcrCollection *
-seahorse_pkcs11_backend_get_writable_tokens (SeahorsePkcs11Backend *self,
- gulong with_mechanism)
-{
- gpointer mechanism;
-
- self = self ? self : seahorse_pkcs11_backend_get ();
- g_return_val_if_fail (SEAHORSE_IS_PKCS11_BACKEND (self), NULL);
-
- if (with_mechanism == GCK_INVALID)
- mechanism = GUINT_TO_POINTER (G_MAXUINT);
- else
- mechanism = GUINT_TO_POINTER (with_mechanism);
-
- return gcr_filter_collection_new_with_callback (GCR_COLLECTION (self),
- on_filter_writable,
- mechanism, NULL);
+ g_return_val_if_fail (pkcs11_backend, NULL);
+ return pkcs11_backend;
}
static void
@@ -437,7 +426,7 @@ on_generate_activate (GSimpleAction *action,
catalog = seahorse_action_group_get_catalog (actions);
dialog = seahorse_pkcs11_generate_new (GTK_WINDOW (catalog));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK(gtk_window_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
g_clear_object (&catalog);
}
diff --git a/pkcs11/seahorse-pkcs11-backend.h b/pkcs11/seahorse-pkcs11-backend.h
index ddcfd2fc..ba9310a7 100644
--- a/pkcs11/seahorse-pkcs11-backend.h
+++ b/pkcs11/seahorse-pkcs11-backend.h
@@ -27,20 +27,8 @@
#define SEAHORSE_PKCS11 (g_quark_from_static_string (SEAHORSE_PKCS11_STR))
#define SEAHORSE_TYPE_PKCS11_BACKEND (seahorse_pkcs11_backend_get_type ())
-#define SEAHORSE_PKCS11_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
SEAHORSE_TYPE_PKCS11_BACKEND, SeahorsePkcs11Backend))
-#define SEAHORSE_PKCS11_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
SEAHORSE_TYPE_PKCS11_BACKEND, SeahorsePkcs11BackendClass))
-#define SEAHORSE_IS_PKCS11_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
SEAHORSE_TYPE_PKCS11_BACKEND))
-#define SEAHORSE_IS_PKCS11_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
SEAHORSE_TYPE_PKCS11_BACKEND))
-#define SEAHORSE_PKCS11_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
SEAHORSE_TYPE_PKCS11_BACKEND, SeahorsePkcs11BackendClass))
-
-typedef struct _SeahorsePkcs11Backend SeahorsePkcs11Backend;
-typedef struct _SeahorsePkcs11BackendClass SeahorsePkcs11BackendClass;
-
-GType seahorse_pkcs11_backend_get_type (void) G_GNUC_CONST;
+G_DECLARE_FINAL_TYPE (SeahorsePkcs11Backend, seahorse_pkcs11_backend, SEAHORSE, PKCS11_BACKEND, GObject)
SeahorsePkcs11Backend * seahorse_pkcs11_backend_get (void);
-GcrCollection * seahorse_pkcs11_backend_get_writable_tokens (SeahorsePkcs11Backend *self,
- gulong with_mechanism);
-
#endif /* SEAHORSE_PKCS11_BACKEND_H_ */
diff --git a/pkcs11/seahorse-pkcs11-generate.ui b/pkcs11/seahorse-pkcs11-generate.ui
index f240c722..3a203434 100644
--- a/pkcs11/seahorse-pkcs11-generate.ui
+++ b/pkcs11/seahorse-pkcs11-generate.ui
@@ -1,176 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorsePkcs11Generate" parent="GtkDialog">
<property name="resizable">False</property>
<property name="title" translatable="yes">New private key</property>
- <child internal-child="vbox">
- <object class="GtkBox">
- <property name="visible">True</property>
+
+ <child internal-child="content_area">
+ <object class="GtkBox" id="vbox1">
<property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkLabel" id="label45">
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Create a new private key</property>
+ </object>
+ </child>
<child>
- <object class="GtkBox" id="pkcs11-generate">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="can_focus">False</property>
- <property name="border_width">7</property>
- <property name="spacing">12</property>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkImage" id="key-image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="pixel_size">48</property>
- <property name="icon_name">gcr-key-pair</property>
+ <object class="AdwEntryRow" id="label_row">
+ <property name="title" translatable="yes">Label</property>
</object>
</child>
<child>
- <object class="GtkBox" id="vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="label45">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Create a new private key</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Stored at</property>
+ <child type="suffix">
+ <object class="GtkComboBox" id="token_box">
+ <property name="valign">center</property>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
+ <property name="title" translatable="yes">Advanced key options</property>
+ <child type="suffix">
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Key _Type</property>
+ <property name="use_underline">True</property>
<child>
- <object class="GtkGrid" id="grid2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Label:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Stored at:</property>
- <property name="halign">end</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="label_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="activates_default">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="token_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label48">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Advanced key options</property>
- <property name="use_underline">True</property>
- <property name="halign">start</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- <property name="width">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label49">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Key _Type:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="mechanism_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label50">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Key _Strength (bits):</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="key_bits">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="climb_rate">64</property>
- <property name="numeric">True</property>
- <property name="activates_default">True</property>
- </object>
- <packing>
- <property name="top_attach">4</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
+ <object class="GtkComboBox" id="mechanism_box">
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Key _Strength (bits)</property>
+ <property name="use_underline">True</property>
+ <child type="suffix">
+ <object class="GtkSpinButton" id="key_bits">
+ <property name="valign">center</property>
+ <property name="climb-rate">64</property>
+ <property name="numeric">True</property>
</object>
</child>
</object>
@@ -182,14 +72,11 @@
<child type="action">
<object class="GtkButton" id="button_cancel">
- <property name="visible">True</property>
<property name="label" translatable="yes">Cancel</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="button_ok">
- <property name="visible">True</property>
- <property name="can-default">True</property>
<property name="label" translatable="yes">Create</property>
</object>
</child>
diff --git a/pkcs11/seahorse-pkcs11-properties.ui b/pkcs11/seahorse-pkcs11-properties.ui
index 0c7b7838..711d1b3e 100644
--- a/pkcs11/seahorse-pkcs11-properties.ui
+++ b/pkcs11/seahorse-pkcs11-properties.ui
@@ -1,24 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorsePkcs11Properties" parent="GtkDialog">
<property name="width_request">400</property>
<property name="height_request">400</property>
- <property name="can_focus">False</property>
- <child internal-child="vbox">
+
+ <child internal-child="content_area">
<object class="GtkBox" id="content">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="can_focus">False</property>
<property name="spacing">12</property>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="delete_button">
- <property name="visible">True</property>
<property name="label" translatable="yes">Delete</property>
<property name="tooltip_text" translatable="yes">Delete this certificate or key</property>
<signal name="clicked" handler="on_delete_button_clicked"/>
@@ -29,7 +24,6 @@
</child>
<child>
<object class="GtkButton" id="export_button">
- <property name="visible">True</property>
<property name="label" translatable="yes">Export</property>
<property name="tooltip_text" translatable="yes">Export the certificate</property>
<signal name="clicked" handler="on_export_button_clicked"/>
@@ -42,14 +36,8 @@
<property name="tooltip_text" translatable="yes">Create a certificate request file for this
key</property>
<signal name="clicked" handler="on_request_certificate_button_clicked"/>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
diff --git a/src/application.vala b/src/application.vala
index 469844ad..088cd517 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -21,7 +21,7 @@
* <http://www.gnu.org/licenses/>.
*/
-public class Seahorse.Application : Gtk.Application {
+public class Seahorse.Application : Adw.Application {
private SearchProvider? search_provider;
private uint search_provider_dbus_id = 0;
@@ -96,14 +96,6 @@ public class Seahorse.Application : Gtk.Application {
public override void startup() {
base.startup();
- Hdy.init();
-
- // Opt-in to Color Scheme user preference
- Hdy.StyleManager.get_default ().color_scheme = Hdy.ColorScheme.PREFER_LIGHT;
-
- // Insert Icons into Stock
- icons_init();
-
// Initialize the backends
Gkr.Backend.initialize();
Ssh.Backend.initialize();
@@ -177,19 +169,13 @@ public class Seahorse.Application : Gtk.Application {
about.set_logo_icon_name(Config.APPLICATION_ID);
about.set_website("https://wiki.gnome.org/Apps/Seahorse");
about.set_website_label(_("Seahorse Project Homepage"));
-
- about.response.connect((response) => {
- about.hide();
- });
-
about.set_transient_for(this.key_mgr);
- about.run();
- about.destroy();
+ about.show();
}
private void on_app_help(SimpleAction action, Variant? param) {
try {
- Gtk.show_uri_on_window(this.key_mgr, "help:seahorse", Gtk.get_current_event_time ());
+ Gtk.show_uri(this.key_mgr, "help:seahorse", Gdk.CURRENT_TIME);
} catch (GLib.Error err) {
warning("Error showing help: %s", err.message);
}
diff --git a/src/import-dialog.vala b/src/import-dialog.vala
index d3536467..2747cef4 100644
--- a/src/import-dialog.vala
+++ b/src/import-dialog.vala
@@ -20,61 +20,62 @@
*/
public class Seahorse.ImportDialog : Gtk.Dialog {
+ //XXX
- private Gcr.ViewerWidget viewer;
- private Gcr.ImportButton import;
+ // private Gcr.ViewerWidget viewer;
+ // private Gcr.ImportButton import;
public ImportDialog(Gtk.Window? parent) {
- GLib.Object(
- transient_for: parent,
- title: _("Data to be imported"),
- use_header_bar: 1
- );
+ // GLib.Object(
+ // transient_for: parent,
+ // title: _("Data to be imported"),
+ // use_header_bar: 1
+ // );
- Gtk.Widget button = new Gtk.Button.with_mnemonic(_("_Cancel"));
- button.show();
- add_action_widget(button, Gtk.ResponseType.CANCEL);
+ // Gtk.Widget button = new Gtk.Button.with_mnemonic(_("_Cancel"));
+ // button.show();
+ // add_action_widget(button, Gtk.ResponseType.CANCEL);
- this.import = new Gcr.ImportButton(_("_Import"));
- this.import.halign = Gtk.Align.END;
- this.import.visible = true;
- this.import.get_style_context().add_class("suggested-action");
- this.import.importing.connect(() => this.viewer.clear_error());
- this.import.imported.connect(on_import_button_imported);
- ((Gtk.HeaderBar) get_header_bar()).pack_end(this.import);
+ // this.import = new Gcr.ImportButton(_("_Import"));
+ // this.import.halign = Gtk.Align.END;
+ // this.import.visible = true;
+ // this.import.get_style_context().add_class("suggested-action");
+ // this.import.importing.connect(() => this.viewer.clear_error());
+ // this.import.imported.connect(on_import_button_imported);
+ // ((Gtk.HeaderBar) get_header_bar()).pack_end(this.import);
- this.viewer = new Gcr.ViewerWidget();
- this.viewer.added.connect((v, r, parsed) => {
- debug("Parsed a '%s' with format %d", parsed.get_description(), parsed.get_format());
- this.import.add_parsed(parsed);
- });
- this.viewer.show();
- ((Gtk.Box) get_content_area()).pack_end(this.viewer);
+ // this.viewer = new Gcr.ViewerWidget();
+ // this.viewer.added.connect((v, r, parsed) => {
+ // debug("Parsed a '%s' with format %d", parsed.get_description(), parsed.get_format());
+ // this.import.add_parsed(parsed);
+ // });
+ // this.viewer.show();
+ // ((Gtk.Box) get_content_area()).pack_end(this.viewer);
}
public void add_uris(string[] uris) {
- foreach (string uri in uris)
- this.viewer.load_file(File.new_for_uri(uri));
+ // foreach (string uri in uris)
+ // this.viewer.load_file(File.new_for_uri(uri));
}
public void add_text(string? display_name, string text) {
- this.viewer.load_data(display_name, text.data);
+ // this.viewer.load_data(display_name, text.data);
}
private void on_import_button_imported(GLib.Object importer, Error? error) {
- if (error == null) {
- response(Gtk.ResponseType.OK);
+ // if (error == null) {
+ // response(Gtk.ResponseType.OK);
- string uri = ((Gcr.Importer) importer).uri;
- foreach (Backend backend in Backend.get_registered()) {
- Place? place = backend.lookup_place(uri);
- if (place != null)
- place.load.begin(null);
- }
+ // string uri = ((Gcr.Importer) importer).uri;
+ // foreach (Backend backend in Backend.get_registered()) {
+ // Place? place = backend.lookup_place(uri);
+ // if (place != null)
+ // place.load.begin(null);
+ // }
- } else {
- if (!(error is GLib.IOError.CANCELLED))
- this.viewer.show_error(_("Import failed"), error);
- }
+ // } else {
+ // if (!(error is GLib.IOError.CANCELLED))
+ // this.viewer.show_error(_("Import failed"), error);
+ // }
}
}
diff --git a/src/key-manager-filter.vala b/src/key-manager-filter.vala
new file mode 100644
index 00000000..006c753d
--- /dev/null
+++ b/src/key-manager-filter.vala
@@ -0,0 +1,125 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2022 Niels De Graef
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+public class Seahorse.KeyManagerFilter : Gtk.Filter {
+
+ public enum ShowFilter {
+ ANY,
+ PERSONAL,
+ TRUSTED;
+
+ public unowned string? to_string() {
+ switch (this) {
+ case ShowFilter.ANY:
+ return "";
+ case ShowFilter.PERSONAL:
+ return "personal";
+ case ShowFilter.TRUSTED:
+ return "trusted";
+ default:
+ assert_not_reached();
+ }
+ }
+
+ public static ShowFilter from_string(string? str) {
+ switch (str) {
+ case null:
+ case "":
+ case "any":
+ return ShowFilter.ANY;
+ case "personal":
+ return ShowFilter.PERSONAL;
+ case "trusted":
+ return ShowFilter.TRUSTED;
+ default:
+ critical ("Got unknown ShowFilter string: %s", str);
+ assert_not_reached();
+ }
+ }
+ }
+
+ public ShowFilter show_filter {
+ get { return this._show_filter; }
+ set {
+ if (value != this._show_filter) {
+ this._show_filter = value;
+ changed(Gtk.FilterChange.DIFFERENT);
+ }
+ }
+ }
+ private ShowFilter _show_filter = ShowFilter.ANY;
+
+ public string filter_text {
+ get { return this._filter_text; }
+ set {
+ if (value.casefold() == this._filter_text)
+ return;
+ this._filter_text = value.casefold();
+ changed(Gtk.FilterChange.DIFFERENT);
+ }
+ }
+ private string _filter_text = "";
+
+ public override bool match(GLib.Object? item) {
+ return matches_showfilter(item)
+ && object_contains_filtered_text(item, this._filter_text);
+ }
+
+ private bool matches_showfilter(GLib.Object? obj) {
+ Flags obj_flags = Flags.NONE;
+ obj.get("object-flags", out obj_flags, null);
+
+ switch (this.show_filter) {
+ case ShowFilter.PERSONAL:
+ return Seahorse.Flags.PERSONAL in obj_flags;
+ case ShowFilter.TRUSTED:
+ return Seahorse.Flags.TRUSTED in obj_flags;
+ case ShowFilter.ANY:
+ return true;
+ }
+
+ return false;
+ }
+
+ // Search through row for text
+ private bool object_contains_filtered_text(GLib.Object? object, string? text) {
+ // Empty search text results in a match
+ if (text == null || text == "")
+ return true;
+
+ string? name = null;
+ object.get("label", out name, null);
+ if (name != null && (text in name.down()))
+ return true;
+
+ if (object.get_class().find_property("description") != null) {
+ string? description = null;
+ object.get("description", out description, null);
+ if (description != null && (text in description.down()))
+ return true;
+ }
+
+ return false;
+ }
+
+ public override Gtk.FilterMatch get_strictness () {
+ return Gtk.FilterMatch.SOME;
+ }
+}
diff --git a/src/key-manager-item-row.vala b/src/key-manager-item-row.vala
index 12b3f16e..a8e28139 100644
--- a/src/key-manager-item-row.vala
+++ b/src/key-manager-item-row.vala
@@ -29,21 +29,20 @@ public class Seahorse.KeyManagerItemRow : Gtk.ListBoxRow {
construct {
var grid = new Gtk.Grid();
- grid.get_style_context().add_class("seahorse-item-listbox-row");
- add(grid);
+ grid.add_css_class("seahorse-item-listbox-row");
+ set_child(grid);
GLib.Icon? icon = null;
object.get("icon", out icon);
if (icon != null) {
- var img = new Gtk.Image.from_gicon(icon, Gtk.IconSize.DND);
+ var img = new Gtk.Image.from_gicon(icon);
img.margin_end = 12;
img.pixel_size = 32;
grid.attach(img, 0, 0, 1, 2);
}
var markup_label = new Gtk.Label(null);
- object.bind_property("markup", markup_label, "label", BindingFlags.SYNC_CREATE);
- markup_label.use_markup = true;
+ object.bind_property("label", markup_label, "label", BindingFlags.SYNC_CREATE);
markup_label.halign = Gtk.Align.START;
markup_label.xalign = 0.0f;
markup_label.hexpand = true;
@@ -56,8 +55,6 @@ public class Seahorse.KeyManagerItemRow : Gtk.ListBoxRow {
description_label.valign = Gtk.Align.START;
description_label.get_style_context().add_class("seahorse-item-listbox-row-description");
grid.attach(description_label, 2, 0);
-
- show_all();
}
public KeyManagerItemRow(GLib.Object object) {
diff --git a/src/key-manager.vala b/src/key-manager.vala
index 559188f1..bf514258 100644
--- a/src/key-manager.vala
+++ b/src/key-manager.vala
@@ -24,11 +24,7 @@
public class Seahorse.KeyManager : Catalog {
[GtkChild]
- private unowned Hdy.Leaflet header;
- [GtkChild]
- private unowned Gtk.HeaderBar left_header;
- [GtkChild]
- private unowned Gtk.HeaderBar right_header;
+ private unowned Adw.HeaderBar right_header;
[GtkChild]
private unowned Gtk.Revealer back_revealer;
@@ -38,12 +34,20 @@ public class Seahorse.KeyManager : Catalog {
private unowned Gtk.SearchEntry filter_entry;
[GtkChild]
- private unowned Hdy.Leaflet content_box;
+ private unowned Adw.Leaflet content_box;
[GtkChild]
private unowned Gtk.ScrolledWindow sidebar_area;
private Sidebar sidebar;
+
[GtkChild]
private unowned Gtk.Stack content_stack;
+ [GtkChild]
+ private unowned Gtk.ScrolledWindow item_listbox_page;
+ [GtkChild]
+ private unowned Adw.StatusPage empty_state_page;
+ [GtkChild]
+ private unowned Adw.StatusPage locked_keyring_page;
+
[GtkChild]
private unowned Gtk.ListBox item_listbox;
@@ -52,15 +56,13 @@ public class Seahorse.KeyManager : Catalog {
[GtkChild]
private unowned Gtk.ToggleButton show_search_button;
- private Seahorse.ItemList item_list;
- private Gcr.Collection collection;
+ [GtkChild]
+ private unowned Gtk.DropTarget drop_target;
- private GLib.Settings settings;
+ private KeyManagerFilter item_filter = new KeyManagerFilter();
+ private Gtk.FilterListModel item_list;
- private enum DndTarget { // Drag 'n Drop target type
- PLAIN,
- URIS
- }
+ private GLib.Settings settings;
private const GLib.ActionEntry[] action_entries = {
{ "new-item", on_new_item },
@@ -78,18 +80,21 @@ public class Seahorse.KeyManager : Catalog {
);
this.settings = new GLib.Settings("org.gnome.seahorse.manager");
- this.collection = setup_sidebar();
+ setup_sidebar();
+
+ this.item_list = new Gtk.FilterListModel(null, this.item_filter);
+ this.sidebar.selection.bind_property("selected-item",
+ this.item_list, "model",
+ GLib.BindingFlags.SYNC_CREATE);
load_css();
// Add new item list and bind our listbox to it
- this.item_list = new Seahorse.ItemList(this.collection);
this.item_list.items_changed.connect((idx, removed, added) => check_empty_state());
this.item_listbox.bind_model(this.item_list, (obj) => { return new KeyManagerItemRow(obj); });
this.item_listbox.row_activated.connect(on_item_listbox_row_activated);
this.item_listbox.selected_rows_changed.connect(on_item_listbox_selected_rows_changed);
- this.item_listbox.popup_menu.connect(on_item_listbox_popup_menu);
- this.item_listbox.button_press_event.connect(on_item_listbox_button_press_event);
+ // this.item_listbox.popup_menu.connect(on_item_listbox_popup_menu);
init_actions();
@@ -100,12 +105,8 @@ public class Seahorse.KeyManager : Catalog {
// For the filtering
on_filter_changed(this.filter_entry);
- // Setup drops
- Gtk.drag_dest_set(this, Gtk.DestDefaults.ALL, {}, Gdk.DragAction.COPY);
- Gtk.TargetList targets = new Gtk.TargetList(null);
- targets.add_uri_targets(DndTarget.URIS);
- targets.add_text_targets(DndTarget.PLAIN);
- Gtk.drag_dest_set_target_list(this, targets);
+ // DnD
+ this.drop_target.on_drop.connect(on_drop);
// In the beginning, nothing's selected, so show empty state
check_empty_state();
@@ -117,17 +118,17 @@ public class Seahorse.KeyManager : Catalog {
private void load_css() {
Gtk.CssProvider provider = new Gtk.CssProvider();
- Gtk.StyleContext.add_provider_for_screen(
- Gdk.Display.get_default().get_default_screen(),
- provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
provider.parsing_error.connect((section, error) => {
- uint start = section.get_start_line();
- uint end = section.get_end_line();
+ size_t start = section.get_start_location().lines + 1;
+ size_t end = section.get_end_location().lines + 1;
if (start == end)
- debug("Error parsing css on line %u: %s", start, error.message);
+ debug("Error parsing css on line %zu: %s", start, error.message);
else
- debug("Error parsing css on lines %u-%u: %s", start, end, error.message);
+ debug("Error parsing css on lines %zu-%zu: %s", start, end, error.message);
});
provider.load_from_resource("/org/gnome/Seahorse/seahorse.css");
@@ -147,34 +148,33 @@ public class Seahorse.KeyManager : Catalog {
selection_changed();
}
- private bool on_item_listbox_button_press_event (Gdk.EventButton event) {
- // Check for right click
- if ((event.type == Gdk.EventType.BUTTON_PRESS) && (event.button == 3)) {
- // Make sure that the right-clicked row is also selected
- var row = this.item_listbox.get_row_at_y((int) event.y);
- if (row != null) {
- this.item_listbox.unselect_all();
- this.item_listbox.select_row(row);
- }
-
- // Show context menu (unless no row was right clicked or nothing was selected)
- var objects = get_selected_item_listbox_items();
- debug("We have %u selected objects", objects.length());
- if (objects != null)
- show_context_menu(null);
- return true;
+ [GtkCallback]
+ private void on_item_listbox_right_click(Gtk.GestureClick gesture,
+ int n_press,
+ double x,
+ double y) {
+ // Make sure that the right-clicked row is also selected
+ var row = this.item_listbox.get_row_at_y((int) y);
+ if (row != null) {
+ this.item_listbox.unselect_all();
+ this.item_listbox.select_row(row);
}
- return false;
- }
-
- private bool on_item_listbox_popup_menu(Gtk.Widget? listview) {
+ // Show context menu (unless no row was right clicked or nothing was selected)
var objects = get_selected_item_listbox_items();
+ debug("We have %u selected objects", objects.length());
if (objects != null)
show_context_menu(null);
- return false;
}
+ // XXX
+ // private bool on_item_listbox_popup_menu(Gtk.Widget? listview) {
+ // var objects = get_selected_item_listbox_items();
+ // if (objects != null)
+ // show_context_menu(null);
+ // return false;
+ // }
+
private GLib.List<weak GLib.Object> get_selected_item_listbox_items() {
var rows = this.item_listbox.get_selected_rows();
var objects = new GLib.List<weak GLib.Object>();
@@ -189,7 +189,7 @@ public class Seahorse.KeyManager : Catalog {
base.selection_changed();
var objects = get_selected_objects();
- foreach (weak Backend backend in get_backends())
+ foreach (unowned var backend in Backend.get_registered())
backend.actions.set_actions_for_selected_objects(objects);
}
@@ -199,19 +199,19 @@ public class Seahorse.KeyManager : Catalog {
this.show_search_button.sensitive = !empty;
if (!empty) {
- this.content_stack.visible_child_name = "item_listbox_page";
+ this.content_stack.visible_child = this.item_listbox_page;
return;
}
// We have an empty page, that might still have 2 reasons:
// - we really have no items in our collections
// - we're dealing with a locked keyring
- Place? place = this.sidebar.get_focused_place();
- if (place != null && place is Lockable && ((Lockable) place).unlockable) {
- this.content_stack.visible_child_name = "locked_keyring_page";
+ var place = (Place) this.sidebar.selection.selected_item;
+ if (place != null && (place is Lockable) && ((Lockable) place).unlockable) {
+ this.content_stack.visible_child = this.locked_keyring_page;
return;
}
- this.content_stack.visible_child_name = "empty_state_page";
+ this.content_stack.visible_child = this.empty_state_page;
}
private void on_new_item(SimpleAction action, GLib.Variant? param) {
@@ -220,7 +220,7 @@ public class Seahorse.KeyManager : Catalog {
[GtkCallback]
private void on_filter_changed(Gtk.Editable entry) {
- this.item_list.filter_text = this.filter_entry.text;
+ this.item_filter.filter_text = this.filter_entry.text;
}
[GtkCallback]
@@ -244,23 +244,20 @@ public class Seahorse.KeyManager : Catalog {
}
private void update_header() {
- bool folded = this.content_box.folded;
-
- this.left_header.show_close_button =
- !folded || header.visible_child == left_header;
+ // XXX still necesssary?
+ // bool folded = this.content_box.folded;
- this.right_header.show_close_button =
- !folded || header.visible_child == right_header;
-
- this.back_revealer.reveal_child = this.back_revealer.visible =
- folded && header.visible_child == right_header;
+ // this.back_revealer.reveal_child = this.back_revealer.visible =
+ // folded && this.content_b.visible_child == right_header;
}
public void import_files(string[]? uris) {
ImportDialog dialog = new ImportDialog(this);
dialog.add_uris(uris);
- dialog.run();
- dialog.destroy();
+ dialog.response.connect((response) => {
+ dialog.destroy();
+ });
+ dialog.present();
}
private void on_import_file(SimpleAction action, GLib.Variant? parameter) {
@@ -269,11 +266,8 @@ public class Seahorse.KeyManager : Catalog {
Gtk.FileChooserAction.OPEN,
_("_Open"), _("_Cancel"));
- dialog.set_local_only(false);
-
- // TODO: This should come from libgcr somehow
Gtk.FileFilter filter = new Gtk.FileFilter();
- filter.set_name(_("All key files"));
+ filter.name = _("All key files");
filter.add_mime_type("application/pgp-keys");
filter.add_mime_type("application/x-ssh-key");
filter.add_mime_type("application/pkcs12");
@@ -307,66 +301,66 @@ public class Seahorse.KeyManager : Catalog {
dialog.set_filter(filter);
filter = new Gtk.FileFilter();
- filter.set_name(_("All files"));
+ filter.name = _("All files");
filter.add_pattern("*");
dialog.add_filter(filter);
- string? uri = null;
- if (dialog.run() == Gtk.ResponseType.ACCEPT) {
- uri = dialog.get_uri();
- }
+ dialog.response.connect((response) => {
+ GLib.File? file = null;
+ if (response == Gtk.ResponseType.ACCEPT)
+ file = dialog.get_file();
- dialog.destroy();
+ dialog.destroy();
- if (uri != null) {
- import_files({ uri });
- }
+ if (file != null) {
+ string uris[1] = { file.get_uri() };
+ import_files(uris);
+ }
+ });
}
private void import_text(string? display_name, string? text) {
ImportDialog dialog = new ImportDialog(this);
dialog.add_text(display_name, text);
- dialog.run();
- dialog.destroy();
+ dialog.response.connect((response) => {
+ dialog.destroy();
+ });
+ dialog.present();
}
- [GtkCallback]
- private void on_drag_data_received(Gdk.DragContext context, int x, int y,
- Gtk.SelectionData? selection_data, uint info, uint time) {
- if (selection_data == null)
- return;
-
- if (info == DndTarget.PLAIN) {
- string? text = selection_data.get_text();
- import_text(_("Dropped text"), text);
- } else if (info == DndTarget.URIS) {
- string[]? uris = selection_data.get_uris();
- foreach (string uri in uris)
- uri._strip();
+ private bool on_drop(Gtk.DropTarget drop_target,
+ GLib.Value? value,
+ double x,
+ double y) {
+ if (value.holds(typeof(string))) {
+ import_text(_("Dropped text"), value.get_string());
+ return true;
+ }
+ if (value.holds(typeof(GLib.Uri))) {
+ var uri = (GLib.Uri) value.get_boxed();
+ string uris[1] = { uri.to_string() };
import_files(uris);
+ return true;
}
- }
-
- private void on_paste(SimpleAction action, Variant? param) {
- Gdk.Atom atom = Gdk.Atom.intern("CLIPBOARD", false);
- Gtk.Clipboard clipboard = Gtk.Clipboard.get(atom);
-
- if (clipboard.wait_is_text_available())
- return;
- clipboard.request_text(on_clipboard_received);
+ return false;
}
- private void on_clipboard_received(Gtk.Clipboard board, string? text) {
- if (text == null)
- return;
-
- assert(this.filter_entry != null);
- if (this.filter_entry.is_focus)
- this.filter_entry.paste_clipboard();
- else
- if (text != null && text.char_count() > 0)
- import_text(_("Clipboard text"), text);
+ private void on_paste(SimpleAction action, Variant? param) {
+ var clipboard = get_clipboard();
+ clipboard.read_text_async.begin(null, (obj, res) => {
+ try {
+ var text = clipboard.read_text_async.end(res);
+
+ if (this.filter_entry.is_focus())
+ this.filter_entry.text = text;
+ else
+ if (text != null && text.char_count() > 0)
+ import_text(_("Clipboard text"), text);
+ } catch (GLib.Error err) {
+ warning("Couldn't read clipboard: %s", err.message);
+ }
+ });
}
private void update_view_filter(string filter_str, bool update_settings = true) {
@@ -379,8 +373,7 @@ public class Seahorse.KeyManager : Catalog {
action.set_state(filter_str);
// Update the item list
- this.item_list.showfilter = ItemList.ShowFilter.from_string(filter_str);
- this.item_list.refilter();
+ this.item_filter.show_filter = KeyManagerFilter.ShowFilter.from_string(filter_str);
}
private void on_show_search(SimpleAction action, Variant? param) {
@@ -411,25 +404,21 @@ public class Seahorse.KeyManager : Catalog {
}
}
- private Gcr.Collection setup_sidebar() {
+ private void setup_sidebar() {
this.sidebar = new Sidebar();
restore_keyring_selection();
// Make sure we update the empty state on any change
- this.sidebar.selected_rows_changed.connect(on_sidebar_selected_rows_changed);
- this.sidebar.current_collection_changed.connect((sidebar) => { check_empty_state (); });
+ this.sidebar.selection.selection_changed.connect(on_sidebar_selection_changed);
- foreach (weak Backend backend in get_backends()) {
+ foreach (unowned var backend in Backend.get_registered()) {
ActionGroup actions = backend.actions;
actions.catalog = this;
insert_action_group(actions.prefix, actions);
}
- this.sidebar_area.add(this.sidebar);
- this.sidebar.show();
-
- return this.sidebar.objects;
+ this.sidebar_area.set_child(this.sidebar);
}
// On setup, select the LRU place from the user's last session (if any).
@@ -455,36 +444,28 @@ public class Seahorse.KeyManager : Catalog {
return GLib.Source.REMOVE;
// Still nothing. Can happen on first run -> just select first entry
- this.sidebar.select_row(this.sidebar.get_row_at_index(0));
+ this.sidebar.selection.selected = 0;
return GLib.Source.REMOVE;
});
}
- private void on_sidebar_selected_rows_changed(Gtk.ListBox sidebar) {
+ private void on_sidebar_selection_changed(Gtk.SelectionModel selection,
+ uint position,
+ uint n_items) {
check_empty_state();
show_item_list_pane();
- Place? place = this.sidebar.get_focused_place();
+ var place = (Place) this.sidebar.selection.selected_item;
return_if_fail (place != null);
- this.right_header.title = place.label;
+ this.right_header.title_widget = new Adw.WindowTitle(place.label, "");
this.settings.set_strv("keyrings-selected", { place.uri });
}
- public override List<weak Backend> get_backends() {
- return this.sidebar.get_backends();
- }
-
- [GtkCallback]
- private void on_popover_grab_notify(Gtk.Widget widget, bool was_grabbed) {
- if (!was_grabbed)
- widget.hide();
- }
-
[GtkCallback]
private void on_locked_keyring_unlock_button_clicked(Gtk.Button unlock_button) {
- Lockable? place = this.sidebar.get_focused_place() as Lockable;
+ var place = this.sidebar.selection.selected_item as Lockable;
return_if_fail(place != null && place.unlockable);
unlock_button.sensitive = false;
@@ -502,19 +483,22 @@ public class Seahorse.KeyManager : Catalog {
}
[GtkCallback]
- private bool on_key_pressed(Gtk.Widget widget, Gdk.EventKey event) {
+ private bool on_key_pressed(Gtk.EventControllerKey controller,
+ uint keyval,
+ uint keycode,
+ Gdk.ModifierType state) {
bool folded = this.content_box.folded;
- switch (event.keyval) {
+ switch (keyval) {
// <Alt>Down and <Alt>Up for easy sidebar navigation
case Gdk.Key.Down:
- if (Gdk.ModifierType.MOD1_MASK in event.state && !folded) {
+ if (Gdk.ModifierType.ALT_MASK in state && !folded) {
this.sidebar.select_next_place();
return true;
}
break;
case Gdk.Key.Up:
- if (Gdk.ModifierType.MOD1_MASK in event.state && !folded) {
+ if (Gdk.ModifierType.ALT_MASK in state && !folded) {
this.sidebar.select_previous_place();
return true;
}
@@ -522,7 +506,7 @@ public class Seahorse.KeyManager : Catalog {
// <Alt>Left to go back to sidebar in folded mode
case Gdk.Key.Left:
- if (Gdk.ModifierType.MOD1_MASK in event.state && folded) {
+ if (Gdk.ModifierType.ALT_MASK in state && folded) {
show_sidebar_pane();
return true;
}
@@ -530,7 +514,7 @@ public class Seahorse.KeyManager : Catalog {
// <Alt>Right to open currently selected element in folded mode
case Gdk.Key.Right:
- if (Gdk.ModifierType.MOD1_MASK in event.state && folded) {
+ if (Gdk.ModifierType.ALT_MASK in state && folded) {
show_item_list_pane();
return true;
}
@@ -540,6 +524,6 @@ public class Seahorse.KeyManager : Catalog {
}
// By default: propagate to the search bar, for search-as-you-type
- return this.search_bar.handle_event(event);
+ return controller.forward(this.search_bar);
}
}
diff --git a/src/meson.build b/src/meson.build
index 396f9c4c..e8a62088 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -8,6 +8,7 @@ seahorse_sources = [
'application.vala',
'import-dialog.vala',
'key-manager.vala',
+ 'key-manager-filter.vala',
'key-manager-item-row.vala',
'main.vala',
'search-provider.vala',
@@ -19,8 +20,8 @@ seahorse_sources = [
seahorse_dependencies = [
glib_deps,
- gtk,
- libhandy_dep,
+ gtk4_dep,
+ libadwaita_dep,
libsecret,
common_dep,
libseahorse_dep,
diff --git a/src/seahorse-key-manager.ui b/src/seahorse-key-manager.ui
index 4b69b6af..aefc0ff0 100644
--- a/src/seahorse-key-manager.ui
+++ b/src/seahorse-key-manager.ui
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<menu id="main_menu">
<section>
<item>
@@ -57,19 +56,12 @@
</menu>
<object class="GtkPopover" id="new_item_menu_popover">
- <signal name="grab-notify" handler="on_popover_grab_notify" after="yes"/>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
<child>
<object class="GtkListBox" id="generate_list">
- <property name="visible">True</property>
<property name="selection-mode">none</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
<property name="selection-mode">browse</property>
<style>
<class name="new-item-list"/>
@@ -77,23 +69,19 @@
<child>
<object class="GtkListBoxRow" id="ssh_generate_key_button">
<property name="visible" bind-source="ssh_generate_key_button" bind-property="sensitive" />
- <property name="margin">3</property>
<property name="selectable">False</property>
<property name="action-name">ssh.generate-key</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Secure Shell key</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Used to access other computers</property>
<attributes>
@@ -111,23 +99,19 @@
<child>
<object class="GtkListBoxRow" id="pgp_generate_key_button">
<property name="visible" bind-source="pgp_generate_key_button" bind-property="sensitive" />
- <property name="margin">3</property>
<property name="selectable">False</property>
<property name="action-name">pgp.pgp-generate-key</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">GPG key</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Used to encrypt emails and files</property>
<attributes>
@@ -145,23 +129,19 @@
<child>
<object class="GtkListBoxRow" id="gkr_generate_keyring_button">
<property name="visible" bind-source="gkr_generate_keyring_button" bind-property="sensitive"
/>
- <property name="margin">3</property>
<property name="selectable">False</property>
<property name="action-name">gkr.keyring-new</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Password keyring</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Used to store application and network
passwords</property>
<attributes>
@@ -179,23 +159,19 @@
<child>
<object class="GtkListBoxRow" id="gkr_generate_item_button">
<property name="visible" bind-source="gkr_generate_item_button" bind-property="sensitive" />
- <property name="margin">3</property>
<property name="selectable">False</property>
<property name="action-name">gkr.keyring-item-new</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Password</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Safely store a password or
secret</property>
<attributes>
@@ -213,23 +189,19 @@
<child>
<object class="GtkListBoxRow" id="pkcs11_generate_key_button">
<property name="visible" bind-source="pkcs11_generate_key_button" bind-property="sensitive"
/>
- <property name="margin">3</property>
<property name="selectable">False</property>
<property name="action-name">pkcs11.pkcs11-generate-key</property>
<child>
<object class="GtkGrid">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Private key</property>
</object>
</child>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Used to request a certificate</property>
<attributes>
@@ -247,16 +219,12 @@
<child>
<object class="GtkListBoxRow" id="import_from_file_button">
<property name="visible" bind-source="import_from_file_button" bind-property="sensitive" />
- <property name="margin">6</property>
<property name="selectable">False</property>
<property name="action-name">win.import-file</property>
<child>
<object class="GtkLabel">
- <property name="visible">True</property>
<property name="halign">start</property>
<property name="vexpand">True</property>
- <property name="margin-top">3</property>
- <property name="margin-bottom">3</property>
<property name="label" translatable="yes">Import from file…</property>
</object>
</child>
@@ -271,324 +239,242 @@
<template class="SeahorseKeyManager" parent="SeahorseCatalog">
<property name="default-width">600</property>
<property name="default-height">476</property>
- <signal name="drag-data-received" handler="on_drag_data_received" />
- <signal name="key-press-event" handler="on_key_pressed"/>
- <child type="titlebar">
- <object class="HdyTitleBar" id="titlebar">
- <property name="visible">True</property>
+
+ <!-- Event controllers -->
+ <child>
+ <object class="GtkEventControllerKey">
+ <signal name="key-pressed" handler="on_key_pressed"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropTarget" id="drop_target">
+ <property name="actions">copy</property>
+ <!-- We can't use this here since Vala can't handle the "drop" name conflict -->
+ <!-- <signal name="drop" handler="on_drop"/> -->
+ </object>
+ </child>
+
+ <child>
+ <object class="AdwLeaflet" id="content_box">
+ <property name="vexpand">True</property>
+ <property name="can-navigate-back">True</property>
+ <property name="transition-type">over</property>
+ <signal name="notify::fold" handler="on_fold" object="SeahorseKeyManager" after="yes" swapped="no"/>
+
+ <!-- The sidebar pane -->
<child>
- <object class="HdyLeaflet" id="header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="mode-transition-duration" bind-source="content_box"
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
- <property name="child-transition-duration" bind-source="content_box"
bind-property="child-transition-duration" bind-flags="bidirectional|sync-create"/>
- <property name="transition-type" bind-source="content_box" bind-property="transition-type"
bind-flags="bidirectional|sync-create"/>
- <child>
- <object class="GtkHeaderBar" id="left_header">
- <property name="visible">True</property>
- <property name="hexpand">False</property>
- <property name="can_focus">False</property>
- <property name="title" translatable="yes">Passwords and Keys</property>
- <property name="show_close_button">True</property>
- <child>
- <object class="GtkMenuButton" id="new_item_button">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="tooltip_text" translatable="yes">Add a new key or item</property>
- <property name="popover">new_item_menu_popover</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">list-add-symbolic</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="pack_type">start</property>
- </packing>
- </child>
+ <object class="AdwLeafletPage">
+ <property name="name">sidebar-pane</property>
+ <property name="child">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkMenuButton" id="main_menu_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="focus_on_click">False</property>
- <property name="menu-model">main_menu</property>
- <accelerator key="F10" signal="activate"/>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">open-menu-symbolic</property>
+ <object class="AdwHeaderBar" id="left_header">
+ <property name="hexpand">False</property>
+ <property name="title-widget">
+ <object class="AdwWindowTitle">
+ <property name="title" translatable="yes">Passwords and Keys</property>
</object>
- </child>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="name">sidebar-pane</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator" id="header_separator">
- <property name="visible">True</property>
- <style>
- <class name="sidebar"/>
- </style>
- </object>
- <packing>
- <property name="navigatable">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkHeaderBar" id="right_header">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="show_close_button">True</property>
- <child>
- <object class="GtkRevealer" id="back_revealer">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="transition-type">slide-right</property>
- <property name="transition-duration" bind-source="content_box"
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+ </property>
+ <binding name="show-end-title-buttons">
+ <lookup name="folded">content_box</lookup>
+ </binding>
<child>
- <object class="GtkButton" id="back">
- <property name="visible">True</property>
- <property name="valign">center</property>
- <property name="use-underline">True</property>
- <signal name="clicked" handler="on_back_clicked"/>
- <style>
- <class name="image-button"/>
- </style>
- <child internal-child="accessible">
- <object class="AtkObject" id="a11y-back">
- <property name="accessible-name" translatable="yes">Back</property>
- </object>
- </child>
+ <object class="GtkMenuButton" id="new_item_button">
+ <property name="halign">start</property>
+ <property name="tooltip_text" translatable="yes">Add a new key or item</property>
+ <property name="popover">new_item_menu_popover</property>
<child>
- <object class="GtkImage" id="back_image">
- <property name="visible">True</property>
- <property name="icon-name">go-previous-symbolic</property>
- <property name="icon-size">1</property>
+ <object class="GtkImage">
+ <property name="icon_name">list-add-symbolic</property>
</object>
</child>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="GtkMenuButton" id="items_menu_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="focus_on_click">False</property>
- <property name="menu-model">items_menu</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">view-more-symbolic</property>
+ <child type="end">
+ <object class="GtkMenuButton" id="main_menu_button">
+ <property name="focus_on_click">False</property>
+ <property name="menu-model">main_menu</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
+ </child>
</object>
</child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
<child>
- <object class="GtkToggleButton" id="show_search_button">
- <property name="visible">True</property>
- <property name="tooltip_text" translatable="yes">Search for a key or password</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">edit-find-symbolic</property>
- </object>
- </child>
+ <object class="GtkScrolledWindow" id="sidebar_area">
+ <property name="hscrollbar-policy">never</property>
+ <property name="vexpand">True</property>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
- <packing>
- <property name="name">item-list-pane</property>
- </packing>
- </child>
+ </property>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="HdyLeaflet" id="content_box">
- <property name="visible">True</property>
- <property name="vexpand">True</property>
- <property name="can_focus">False</property>
- <property name="can-swipe-back">True</property>
- <property name="transition-type">over</property>
- <signal name="notify::fold" handler="on_fold" object="SeahorseKeyManager" after="yes" swapped="no"/>
- <child>
- <object class="GtkScrolledWindow" id="sidebar_area">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hscrollbar-policy">never</property>
- </object>
- <packing>
- <property name="name">sidebar-pane</property>
- </packing>
- </child>
+ <!-- Separator -->
<child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- <style>
- <class name="sidebar"/>
- </style>
- </object>
- <packing>
+ <object class="AdwLeafletPage">
<property name="navigatable">False</property>
- </packing>
+ <property name="child">
+ <object class="GtkSeparator"/>
+ </property>
+ </object>
</child>
+
+ <!-- The items (right hand) pane -->
<child>
- <object class="GtkBox" id="right_content">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkSearchBar" id="search_bar">
- <property name="visible">True</property>
- <property name="search-mode-enabled" bind-source="show_search_button" bind-property="active"
bind-flags="bidirectional|sync-create" />
- <property name="can_focus">False</property>
- <child>
- <object class="GtkSearchEntry" id="filter_entry">
- <property name="visible">True</property>
- <property name="width_chars">30</property>
- <property name="placeholder_text" translatable="yes">Filter</property>
- <signal name="search-changed" handler="on_filter_changed" />
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkStack" id="content_stack">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
+ <object class="AdwLeafletPage">
+ <property name="name">item-list-pane</property>
+ <property name="child">
+ <object class="GtkBox" id="right_content">
+ <property name="orientation">vertical</property>
+ <property name="vexpand">True</property>
<child>
- <object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar-policy">never</property>
+ <object class="AdwHeaderBar" id="right_header">
+ <property name="hexpand">True</property>
+ <property name="title-widget">
+ <object class="AdwWindowTitle">
+ <property name="title"></property>
+ </object>
+ </property>
+ <binding name="show-start-title-buttons">
+ <lookup name="folded">content_box</lookup>
+ </binding>
<child>
- <object class="HdyClamp">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tightening-threshold">400</property>
- <property name="maximum-size">800</property>
- <property name="margin-top">12</property>
- <property name="margin-bottom">12</property>
+ <object class="GtkRevealer" id="back_revealer">
+ <property name="transition-type">slide-right</property>
+ <property name="transition-duration" bind-source="content_box"
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
<child>
- <object class="GtkListBox" id="item_listbox">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="can-focus">True</property>
- <property name="has-focus">True</property>
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="activate-on-single-click">False</property>
- <property name="selection-mode">multiple</property>
+ <object class="GtkButton" id="back">
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <signal name="clicked" handler="on_back_clicked"/>
<style>
- <class name="content"/>
+ <class name="image-button"/>
</style>
+ <child>
+ <object class="GtkImage" id="back_image">
+ <property name="icon-name">go-previous-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="end">
+ <object class="GtkMenuButton" id="items_menu_button">
+ <property name="focus_on_click">False</property>
+ <property name="menu-model">items_menu</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">view-more-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="end">
+ <object class="GtkToggleButton" id="show_search_button">
+ <property name="tooltip_text" translatable="yes">Search for a key or
password</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">edit-find-symbolic</property>
</object>
</child>
</object>
</child>
</object>
- <packing>
- <property name="name">item_listbox_page</property>
- </packing>
</child>
<child>
- <object class="HdyStatusPage">
- <property name="visible">True</property>
- <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
- <property name="title" translatable="yes">This collection seems to be empty</property>
+ <object class="GtkSearchBar" id="search_bar">
+ <property name="search-mode-enabled" bind-source="show_search_button"
bind-property="active" bind-flags="bidirectional|sync-create" />
<child>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="halign">center</property>
- <property name="action-name">win.new-item</property>
- <property name="label" translatable="yes">Add new items</property>
- <style>
- <class name="suggested-action"/>
- </style>
+ <object class="GtkSearchEntry" id="filter_entry">
+ <property name="width_chars">30</property>
+ <property name="placeholder_text" translatable="yes">Filter</property>
+ <signal name="search-changed" handler="on_filter_changed" />
</object>
</child>
</object>
- <packing>
- <property name="name">empty_state_page</property>
- </packing>
</child>
<child>
- <object class="HdyStatusPage">
- <property name="visible">True</property>
- <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
- <property name="title" translatable="yes">Keyring is locked</property>
+ <object class="GtkStack" id="content_stack">
+ <property name="hhomogeneous">True</property>
+ <property name="vhomogeneous">True</property>
<child>
- <object class="GtkButton" id="locked_keyring_unlock_button">
- <property name="visible">True</property>
- <property name="halign">center</property>
- <property name="label" translatable="yes">Unlock</property>
- <signal name="clicked" handler="on_locked_keyring_unlock_button_clicked"/>
- <style>
- <class name="suggested-action"/>
- </style>
+ <object class="GtkScrolledWindow" id="item_listbox_page">
+ <property name="hscrollbar-policy">never</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="AdwClamp">
+ <property name="tightening-threshold">400</property>
+ <property name="maximum-size">800</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <child>
+ <object class="GtkListBox" id="item_listbox">
+ <property name="hexpand">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="activate-on-single-click">False</property>
+ <property name="selection-mode">multiple</property>
+ <style>
+ <class name="content"/>
+ </style>
+ <child>
+ <object class="GtkGestureClick">
+ <property name="button">3</property>
+ <signal name="pressed" handler="on_item_listbox_right_click"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwStatusPage" id="empty_state_page">
+ <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
+ <property name="title" translatable="yes">This collection seems to be
empty</property>
+ <child>
+ <object class="GtkButton">
+ <property name="halign">center</property>
+ <property name="action-name">win.new-item</property>
+ <property name="label" translatable="yes">Add new items</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="AdwStatusPage" id="locked_keyring_page">
+ <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
+ <property name="title" translatable="yes">Keyring is locked</property>
+ <child>
+ <object class="GtkButton" id="locked_keyring_unlock_button">
+ <property name="halign">center</property>
+ <property name="label" translatable="yes">Unlock</property>
+ <signal name="clicked" handler="on_locked_keyring_unlock_button_clicked"/>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ </child>
</object>
</child>
</object>
- <packing>
- <property name="name">locked_keyring_page</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
+ </property>
</object>
- <packing>
- <property name="name">item-list-pane</property>
- </packing>
</child>
</object>
</child>
</template>
-
- <object class="GtkSizeGroup" id="left_pane_size_group">
- <property name="mode">horizontal</property>
- <widgets>
- <widget name="left_header"/>
- <widget name="sidebar_area"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup" id="right_pane_size_group">
- <property name="mode">horizontal</property>
- <widgets>
- <widget name="right_header"/>
- <widget name="right_content"/>
- </widgets>
- </object>
- <object class="HdyHeaderGroup" id="header_group">
- <headerbars>
- <headerbar name="left_header"/>
- <headerbar name="right_header"/>
- </headerbars>
- </object>
- <object class="HdySwipeGroup" id="swipe_group">
- <swipeables>
- <swipeable name="header"/>
- <swipeable name="content_box"/>
- </swipeables>
- </object>
</interface>
diff --git a/src/search-provider.vala b/src/search-provider.vala
index 6873f191..0753efa4 100644
--- a/src/search-provider.vala
+++ b/src/search-provider.vala
@@ -20,11 +20,13 @@
[DBus (name = "org.gnome.Shell.SearchProvider2")]
public class Seahorse.SearchProvider : GLib.Object {
- private Gcr.UnionCollection union_collection = new Gcr.UnionCollection();
+
+ private GLib.ListStore backends;
+ private Gtk.FilterListModel collection;
+
private HashTable<string, weak GLib.Object> handles
= new HashTable<string, weak GLib.Object>.full(str_hash, str_equal, free, null);
- private Gcr.FilterCollection collection;
private GLib.Application app;
private int n_loading = 0;
private RWLock n_loading_lock = RWLock();
@@ -32,10 +34,14 @@ public class Seahorse.SearchProvider : GLib.Object {
public SearchProvider(GLib.Application app) {
this.app = app;
- this.collection = new Gcr.FilterCollection.with_callback(this.union_collection, filter_objects);
+
+ var backends = new GLib.ListStore(typeof(Backend));
+ var places = new Gtk.FlattenListModel(backends);
+ var filter = new Gtk.CustomFilter(filter_objects);
+ this.collection = new Gtk.FilterListModel(places, filter);
}
- private static bool filter_objects (GLib.Object? obj) {
+ private static bool filter_objects(GLib.Object obj) {
unowned Object? object = obj as Object;
if (object == null || !(Flags.PERSONAL in object.object_flags))
return false;
@@ -52,13 +58,7 @@ public class Seahorse.SearchProvider : GLib.Object {
return true;
}
- ~SearchProvider() {
- this.handles.foreach( (__, obj) => {
- obj.weak_unref(on_object_gone);
- });
- }
-
- public async void load () throws GLib.Error {
+ public async void load() throws GLib.Error {
// avoid reentering load () from a different request
while (!this.loaded && get_n_loading() > 0) {
var wait = notify["loaded"].connect (() => {
@@ -72,9 +72,9 @@ public class Seahorse.SearchProvider : GLib.Object {
return;
}
- var backends = Backend.get_registered();
- this.n_loading = (int) backends.length();
- foreach (var backend in backends) {
+ var reg_backends = Backend.get_registered();
+ this.n_loading = (int) reg_backends.length();
+ foreach (var backend in reg_backends) {
if (!backend.loaded) {
backend.notify["loaded"].connect(() => {
change_n_loading(-1);
@@ -85,11 +85,7 @@ public class Seahorse.SearchProvider : GLib.Object {
change_n_loading(-1);
}
- backend.added.connect(on_place_added);
- backend.removed.connect(on_place_removed);
-
- foreach (GLib.Object place in backend.get_objects())
- on_place_added(backend, place);
+ backends.append(backend);
}
}
@@ -113,7 +109,9 @@ public class Seahorse.SearchProvider : GLib.Object {
yield load();
string?[] results = {};
- foreach (unowned GLib.Object obj in this.collection.get_objects()) {
+ for (uint i = 0; i < this.collection.get_n_items(); i++) {
+ var obj = this.collection.get_item(i);
+
if (object_matches_search(obj, terms)) {
string str = "%p".printf(obj);
@@ -136,7 +134,7 @@ public class Seahorse.SearchProvider : GLib.Object {
string?[] results = {};
foreach (string previous_result in previous_results) {
unowned GLib.Object? object = this.handles.lookup(previous_result);
- if (object == null || !this.collection.contains(object))
+ if (object == null)
continue; // Bogus value
if (object_matches_search(object, new_terms))
@@ -154,7 +152,7 @@ public class Seahorse.SearchProvider : GLib.Object {
int good_results = 0;
foreach (unowned string result in results) {
unowned GLib.Object object = this.handles.lookup(result);
- if (object == null || !(object in this.collection))
+ if (object == null)
continue; // Bogus value
HashTable<string, Variant> meta = new HashTable<string, Variant>(str_hash, str_equal);
@@ -189,7 +187,7 @@ public class Seahorse.SearchProvider : GLib.Object {
unowned GLib.Object? object = null;
identifier.scanf("%p", &object);
object = this.handles.lookup(identifier);
- if (object == null || !(object in this.collection) || !(object is Viewable))
+ if (object == null || !(object is Viewable))
return; // Bogus value
KeyManager key_manager = new KeyManager(GLib.Application.get_default() as Application);
@@ -230,18 +228,6 @@ public class Seahorse.SearchProvider : GLib.Object {
this.handles.remove("%p".printf(where_the_object_was));
}
- private void on_place_added (Gcr.Collection places, GLib.Object object) {
- unowned var place = (Place) object;
- if (!this.union_collection.have(place))
- this.union_collection.add(place);
- }
-
- private void on_place_removed (Gcr.Collection places, GLib.Object object) {
- unowned var place = (Place) object;
- if (this.union_collection.have(place))
- this.union_collection.remove(place);
- }
-
private static string? get_description_if_available (GLib.Object? obj) {
if (obj == null)
return null;
diff --git a/src/sidebar.vala b/src/sidebar.vala
index 5bdda3bb..21943fc9 100644
--- a/src/sidebar.vala
+++ b/src/sidebar.vala
@@ -18,82 +18,44 @@
* <http://www.gnu.org/licenses/>.
*/
-public class Seahorse.Sidebar : Gtk.ListBox {
+public class Seahorse.Sidebar : Adw.Bin {
- private GLib.ListStore store = new GLib.ListStore(typeof(Seahorse.Place));
- private List<Backend> backends = new List<Backend>();
+ private unowned Gtk.ListBox list_box;
- /**
- * Collection of objects sidebar represents
- */
- public Gcr.UnionCollection objects { get; private set; default = new Gcr.UnionCollection(); }
+ private Gtk.FlattenListModel places;
- /**
- * Emitted when the state of the current collection changed.
- * For example: when going from locked to unlocked and vice versa.
- */
- public signal void current_collection_changed();
+ public Gtk.SingleSelection selection { get; private set; }
construct {
- this.selection_mode = Gtk.SelectionMode.BROWSE;
-
- bind_model(this.store, place_widget_create_cb);
- set_header_func(place_header_cb);
- this.row_selected.connect(on_row_selected);
-
- load_backends();
- }
-
- ~Sidebar() {
- foreach (Backend backend in this.backends)
- foreach (weak GLib.Object obj in backend.get_objects())
- on_place_removed (backend, (Place) obj);
- }
-
- private void load_backends() {
- foreach (Backend backend in Backend.get_registered()) {
- this.backends.append(backend);
- backend.added.connect(on_place_added);
- backend.removed.connect(on_place_removed);
- backend.notify.connect(on_backend_changed);
-
- foreach (weak GLib.Object obj in backend.get_objects())
- on_place_added(backend, obj);
- }
- }
-
- private void on_place_added(Gcr.Collection? backend, GLib.Object place_obj) {
- var place = place_obj as Place;
- return_if_fail (place != null);
+ var listbox = new Gtk.ListBox();
+ this.child = listbox;
+ this.list_box = listbox;
+ listbox.add_css_class("navigation-sidebar");
+ listbox.selection_mode = Gtk.SelectionMode.BROWSE;
- debug("New place '%s' added", place.label);
+ // Load backends
+ var backends = new GLib.ListStore(typeof(Backend));
+ foreach (unowned var backend in Backend.get_registered())
+ backends.append(backend);
- if (place.get_length() > 0 || place.show_if_empty)
- this.store.insert_sorted(place, compare_places);
- place.notify.connect(on_place_changed);
- }
+ // ListModels everywhere \o/
+ this.places = new Gtk.FlattenListModel(backends);
- private void on_place_changed(GLib.Object obj, ParamSpec pspec) {
- update_places();
- }
+ var sorter = new Gtk.CustomSorter(compare_places);
+ var places_sorted = new Gtk.SortListModel(this.places, sorter);
- private void on_place_removed(Gcr.Collection? backend, GLib.Object place_obj) {
- var place = place_obj as Place;
- return_if_fail (place != null);
+ this.selection = new Gtk.SingleSelection(places_sorted);
- debug("Place '%s' removed", place.label);
- for (uint i = 0; i < this.store.get_n_items(); i++) {
- if (this.store.get_item(i) == place) {
- this.store.remove(i);
- break;
- }
- }
- }
+ // Listbox stuff
+ listbox.bind_model(this.selection, place_widget_create_cb);
+ listbox.set_header_func(place_header_cb);
+ listbox.row_selected.connect(on_row_selected);
- private void on_backend_changed(GLib.Object obj, ParamSpec spec) {
- Backend backend = (Backend) obj;
- debug("Backend '%s' changed", backend.label);
- update_places();
+ // Right click
+ var secondary_click_gesture = new Gtk.GestureClick ();
+ secondary_click_gesture.button = Gdk.BUTTON_SECONDARY;
+ secondary_click_gesture.pressed.connect (on_right_click);
+ listbox.add_controller (secondary_click_gesture);
}
private Gtk.Widget place_widget_create_cb(GLib.Object object) {
@@ -103,12 +65,13 @@ public class Seahorse.Sidebar : Gtk.ListBox {
}
private void on_sidebar_item_changed(SidebarItem item) {
- select_row(item);
- current_collection_changed();
+ // need to find proper index here
+ // this.places.items_changed(item.get_index(), 1, 1);
+ this.selection.selected = item.get_index();
}
private void place_header_cb(Gtk.ListBoxRow row, Gtk.ListBoxRow? before) {
- Seahorse.Place place = ((SidebarItem) row).place;
+ unowned var place = ((SidebarItem) row).place;
// We need a title iff
// the previous row exists, and it's part of the same category
@@ -121,7 +84,7 @@ public class Seahorse.Sidebar : Gtk.ListBox {
}
var label = new Gtk.Label(place.category.to_string());
- label.get_style_context().add_class("seahorse-sidebar-item-header");
+ label.add_css_class("seahorse-sidebar-item-header");
label.xalign = 0f;
label.margin_start = 9;
label.margin_top = 6;
@@ -130,9 +93,9 @@ public class Seahorse.Sidebar : Gtk.ListBox {
row.set_header(label);
}
- private int compare_places(GLib.Object obj_a, GLib.Object obj_b) {
- Seahorse.Place a = (Seahorse.Place) obj_a;
- Seahorse.Place b = (Seahorse.Place) obj_b;
+ private int compare_places(GLib.Object? obj_a, GLib.Object? obj_b) {
+ unowned var a = (Seahorse.Place) obj_a;
+ unowned var b = (Seahorse.Place) obj_b;
// First of all, order the categories
if (a.category != b.category)
@@ -143,113 +106,33 @@ public class Seahorse.Sidebar : Gtk.ListBox {
}
private void on_row_selected(Gtk.ListBoxRow? row) {
- debug("Updating objects");
-
- // First clear the list
- foreach (var place in this.objects.elements())
- this.objects.remove(place);
+ debug("Updating selected");
- // Only selected ones should be in this.objects
- var selected = row as SidebarItem;
- if (selected == null)
+ if (row == null) {
+ this.selection.unselect_all();
return;
-
- foreach (var place in this.objects.elements()) {
- if (selected.place != place)
- this.objects.remove(place);
}
- if (!this.objects.have(selected.place))
- this.objects.add(selected.place);
- }
-
- private void update_places() {
- // Save current selection
- var old_selected = get_selected_row() as SidebarItem;
- Place? place = null;
- if (old_selected != null)
- place = old_selected.place;
- foreach (Backend backend in this.backends)
- update_backend(backend);
-
- // Needed when you have multiple keyrings (this can lead
- // to multiple 'Password' titles).
- invalidate_headers();
+ this.selection.selected = row.get_index();
}
- private void update_backend(Backend? backend) {
- if (backend.get_objects() == null) // Ignore categories that have nothing
- return;
-
- foreach (weak GLib.Object obj in backend.get_objects()) {
- unowned Place? place = obj as Place;
- if (place == null)
- continue;
-
- bool already_in = false;
- for (int i = 0; i < this.store.get_n_items(); i++) {
- if (this.store.get_object(i) == place) {
- already_in = true;
- break;
- }
- }
-
- if (!already_in && (place.get_length() > 0 || place.show_if_empty))
- this.store.insert_sorted(place, compare_places);
- }
- }
-
- public override bool popup_menu() {
- var row = get_selected_row() as SidebarItem;
- if (row == null)
- return false;
-
- row.show_popup_menu();
- return true;
- }
-
- public override bool button_press_event(Gdk.EventButton event) {
- if (base.button_press_event(event))
- return true;
-
- if (event.button != 3 || event.type != Gdk.EventType.BUTTON_PRESS)
- return false;
-
- var row = get_row_at_y((int) event.y) as SidebarItem;
+ private void on_right_click(Gtk.GestureClick gesture, int n_press, double x, double y) {
+ var row = this.list_box.get_row_at_y((int) y) as SidebarItem;
if (row != null)
row.show_popup_menu();
-
- return true;
- }
-
- public List<weak Gcr.Collection>? get_selected_places() {
- List<weak Gcr.Collection>? places = null;
-
- foreach (var row in get_selected_rows()) {
- var item = row as SidebarItem;
- if (item != null)
- places.append(item.place);
- }
-
- return places;
- }
-
- public Place? get_focused_place() {
- var row = get_selected_row() as SidebarItem;
- return (row != null)? row.place : null;
}
/**
* Tries to find a place with the given URI and selects it.
+
*
* @return Whether a matching place was found
*/
public bool set_focused_place_for_uri(string uri) {
- // First, try to see if we have an exact match
- foreach (var row in get_children()) {
- var item = (SidebarItem) row;
- if (item.place.uri == uri) {
- select_row(item);
+ for (uint i = 0; i < this.selection.get_n_items(); i++) {
+ var place = (Place) this.selection.get_item(i);
+ if (place.uri == uri) {
+ this.selection.selected = i;
return true;
}
}
@@ -263,10 +146,10 @@ public class Seahorse.Sidebar : Gtk.ListBox {
* @return Whether a matching place was found
*/
public bool set_focused_place_for_scheme(string uri_scheme) {
- foreach (var row in get_children()) {
- var item = (SidebarItem) row;
- if (item.place.uri.has_prefix(uri_scheme)) {
- select_row(item);
+ for (uint i = 0; i < this.selection.get_n_items(); i++) {
+ var place = (Place) this.selection.get_item(i);
+ if (place.uri.has_prefix(uri_scheme)) {
+ this.selection.selected = i;
return true;
}
}
@@ -283,21 +166,13 @@ public class Seahorse.Sidebar : Gtk.ListBox {
// Selects the item that is n positions lower/above the current selection
private void select_relative(int positions) {
- var selected = get_selected_row();
- if (selected == null) {
+ if (this.selection.selected == Gtk.INVALID_LIST_POSITION) {
// Select the first row
- select_row(get_row_at_index(0));
+ this.selection.selected = 0;
return;
}
- var next = get_row_at_index(selected.get_index() + positions);
- // If we're at the top/bottom of the list, don't do anything
- if (next != null)
- select_row(next);
- }
-
- public List<weak Backend>? get_backends() {
- return this.backends.copy();
+ this.selection.selected += positions;
}
}
@@ -311,38 +186,33 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
construct {
var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6);
- box.get_style_context().add_class("seahorse-sidebar-item");
+ box.add_css_class("seahorse-sidebar-item");
box.valign = Gtk.Align.CENTER;
box.margin_top = 3;
box.margin_bottom = 3;
- add(box);
-
- var icon = new Gtk.Image.from_gicon(place.icon, Gtk.IconSize.BUTTON);
- box.pack_start(icon, false, false);
+ set_child(box);
var label = new Gtk.Label(place.label);
label.ellipsize = Pango.EllipsizeMode.END;
label.xalign = 0f;
- box.pack_start(label);
+ label.hexpand = true;
+ box.append(label);
var lockable = place as Lockable;
if (lockable != null && (lockable.lockable || lockable.unlockable)) {
- this.lock_button = new Gtk.Button.from_icon_name(get_lock_icon_name(lockable),
- Gtk.IconSize.BUTTON);
- this.lock_button.get_style_context().add_class("flat");
+ this.lock_button = new Gtk.Button.from_icon_name(get_lock_icon_name(lockable));
+ this.lock_button.add_css_class("flat");
this.lock_button.halign = Gtk.Align.END;
this.lock_button.clicked.connect((b) => {
if (lockable.unlockable)
- place_unlock(lockable, (Gtk.Window) get_toplevel());
+ place_unlock(lockable, (Gtk.Window) get_root());
else if (lockable.lockable)
- place_lock(lockable, (Gtk.Window) get_toplevel());
+ place_lock(lockable, (Gtk.Window) get_root());
update_lock_icon(lockable);
});
- box.pack_end(this.lock_button, false, false);
+ box.append(this.lock_button);
}
-
- show_all();
}
private static unowned string? get_lock_icon_name(Lockable lockable) {
@@ -356,7 +226,7 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
}
private void update_lock_icon(Lockable lockable) {
- ((Gtk.Image) this.lock_button.get_image()).icon_name = get_lock_icon_name(lockable);
+ this.lock_button.icon_name = get_lock_icon_name(lockable);
}
public SidebarItem(Seahorse.Place place) {
@@ -364,6 +234,8 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
}
public void show_popup_menu() {
+ // XXX
+#if 0
// Start from the menu model provided by the this.place (if any)
var menu = (this.place.menu_model != null)? new Gtk.Menu.from_model(this.place.menu_model)
: new Gtk.Menu();
@@ -397,7 +269,7 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
// Properties item
if (this.place is Viewable) {
Gtk.MenuItem item = new Gtk.MenuItem.with_mnemonic(_("_Properties"));
- item.activate.connect(() => Viewable.view(this.place, (Gtk.Window) item.get_toplevel()));
+ item.activate.connect(() => Viewable.view(this.place, (Gtk.Window) item.get_root()));
menu.append(item);
item.show();
}
@@ -414,6 +286,7 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
} else {
menu.destroy();
}
+#endif
}
private void place_lock(Lockable lockable, Gtk.Window? window) {
@@ -432,12 +305,12 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
}
private void on_place_lock(Gtk.Widget widget, Lockable lockable) {
- place_lock(lockable, (Gtk.Window) widget.get_toplevel());
+ place_lock(lockable, (Gtk.Window) widget.get_root());
}
private void place_unlock(Lockable lockable, Gtk.Window? window) {
- Cancellable cancellable = new Cancellable();
- TlsInteraction interaction = new Interaction(window);
+ var cancellable = new Cancellable();
+ var interaction = new Seahorse.Interaction(window);
lockable.unlock.begin(interaction, cancellable, (obj, res) => {
try {
@@ -450,20 +323,20 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
});
}
- private void on_place_unlock(Gtk.MenuItem widget, Lockable lockable) {
- place_unlock(lockable, (Gtk.Window) widget.get_toplevel());
- }
-
- private void on_place_delete(Gtk.MenuItem item, Deletable deletable) {
- Deleter deleter = deletable.create_deleter();
- if (deleter.prompt((Gtk.Window) item.get_toplevel())) {
- deleter.delete.begin(null, (obj, res) => {
- try {
- deleter.delete.end(res);
- } catch (Error e) {
- Util.show_error(parent, _("Couldn’t delete"), e.message);
- }
- });
- }
- }
+ // private void on_place_unlock(Gtk.MenuItem widget, Lockable lockable) {
+ // place_unlock(lockable, (Gtk.Window) widget.get_root());
+ // }
+
+ // private void on_place_delete(Gtk.MenuItem item, Deletable deletable) {
+ // Deleter deleter = deletable.create_deleter();
+ // if (deleter.prompt((Gtk.Window) item.get_root())) {
+ // deleter.delete.begin(null, (obj, res) => {
+ // try {
+ // deleter.delete.end(res);
+ // } catch (Error e) {
+ // Util.show_error(parent, _("Couldn’t delete"), e.message);
+ // }
+ // });
+ // }
+ // }
}
diff --git a/ssh/actions.vala b/ssh/actions.vala
index 6aad1ee5..df518d64 100644
--- a/ssh/actions.vala
+++ b/ssh/actions.vala
@@ -60,16 +60,19 @@ public class Seahorse.Ssh.Actions : ActionGroup {
var dialog = new Generate(Backend.instance.get_dot_ssh(),
this.catalog);
- if (dialog.run() != Gtk.ResponseType.ACCEPT) {
- dialog.destroy();
- return;
- }
+ dialog.response.connect((response) => {
+ if (response != Gtk.ResponseType.ACCEPT) {
+ dialog.destroy();
+ return;
+ }
- dialog.generate_key.begin ((obj, res) => {
- dialog.generate_key.end (res);
- dialog.destroy();
- this.catalog.activate_action("focus-place", "openssh");
+ dialog.generate_key.begin ((obj, res) => {
+ dialog.generate_key.end (res);
+ dialog.destroy();
+ this.catalog.activate_action("focus-place", "openssh");
+ });
});
+ dialog.show();
}
private void on_ssh_upload(SimpleAction action, Variant? param) {
diff --git a/ssh/backend.vala b/ssh/backend.vala
index 84ea529a..4cedb182 100644
--- a/ssh/backend.vala
+++ b/ssh/backend.vala
@@ -19,7 +19,7 @@
* <http://www.gnu.org/licenses/>.
*/
-public class Seahorse.Ssh.Backend : GLib.Object, Gcr.Collection, Seahorse.Backend {
+public class Seahorse.Ssh.Backend : GLib.Object, GLib.ListModel, Seahorse.Backend {
private Source dot_ssh;
@@ -48,20 +48,16 @@ public class Seahorse.Ssh.Backend : GLib.Object, Gcr.Collection, Seahorse.Backen
public static Backend? instance { get; internal set; default = null; }
- public uint get_length() {
- return 1;
+ public GLib.Type get_item_type() {
+ return typeof(Ssh.Source);
}
- public List<weak GLib.Object> get_objects() {
- List<weak GLib.Object> list = new List<weak GLib.Object>();
- list.append(this.dot_ssh);
- return list;
+ public uint get_n_items() {
+ return 1;
}
- public bool contains(GLib.Object object) {
- Source? src = object as Source;
-
- return (src != null) && (this.dot_ssh == src);
+ public GLib.Object? get_item(uint position) {
+ return (position == 0)? this.dot_ssh : null;
}
public Seahorse.Place? lookup_place(string uri) {
diff --git a/ssh/deleter.vala b/ssh/deleter.vala
index e2e1221b..80e248bd 100644
--- a/ssh/deleter.vala
+++ b/ssh/deleter.vala
@@ -31,7 +31,7 @@ public class Seahorse.Ssh.Deleter : Seahorse.Deleter {
assert_not_reached ();
}
- public override Gtk.Dialog create_confirm(Gtk.Window? parent) {
+ public override Gtk.Window create_confirm(Gtk.Window? parent) {
uint num = this.keys.length();
string confirm, prompt;
diff --git a/ssh/exporter.vala b/ssh/exporter.vala
index e9499493..b71aa1fe 100644
--- a/ssh/exporter.vala
+++ b/ssh/exporter.vala
@@ -49,11 +49,11 @@ public class Seahorse.Ssh.Exporter : GLib.Object, Seahorse.Exporter {
Gtk.FileFilter filter = new Gtk.FileFilter();
if (this.secret) {
- filter.set_name(_("Secret SSH keys"));
+ filter.name = _("Secret SSH keys");
filter.add_mime_type("application/x-pem-key");
filter.add_pattern("id_*");
} else {
- filter.set_name(_("Public SSH keys"));
+ filter.name = _("Public SSH keys");
filter.add_mime_type("application/x-ssh-key");
filter.add_pattern("*.pub");
}
diff --git a/ssh/generate.vala b/ssh/generate.vala
index e797d779..021808f3 100644
--- a/ssh/generate.vala
+++ b/ssh/generate.vala
@@ -27,10 +27,10 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
public Ssh.Source source { get; construct set; }
[GtkChild]
- private unowned Gtk.Grid details_grid;
+ private unowned Adw.ActionRow key_strength_row;
private KeyLengthChooser key_length_chooser;
[GtkChild]
- private unowned Gtk.Entry email_entry;
+ private unowned Adw.EntryRow email_row;
[GtkChild]
private unowned Gtk.ComboBoxText algorithm_combo_box;
@@ -44,8 +44,8 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
this.source = src;
this.key_length_chooser = new KeyLengthChooser();
- this.key_length_chooser.halign = Gtk.Align.START;
- this.details_grid.attach(this.key_length_chooser, 1, 3);
+ this.key_length_chooser.valign = Gtk.Align.CENTER;
+ this.key_strength_row.add_suffix(this.key_length_chooser);
// on_algo_changed() gets called, bits chooser is setup
algorithm_combo_box.set_active(0);
@@ -65,7 +65,7 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
*/
public async void generate_key() {
// The email address
- string email = this.email_entry.text;
+ string email = this.email_row.text;
// The algorithm
string t = this.algorithm_combo_box.get_active_text();
diff --git a/ssh/key-length-chooser.vala b/ssh/key-length-chooser.vala
index be65e4fc..bc767ddb 100644
--- a/ssh/key-length-chooser.vala
+++ b/ssh/key-length-chooser.vala
@@ -26,7 +26,7 @@
* Please also refer to the man pages of ssh-keygen to know why some
* some restrictions are added.
*/
-public class Seahorse.Ssh.KeyLengthChooser : Gtk.Stack {
+public class Seahorse.Ssh.KeyLengthChooser : Adw.Bin {
private Gtk.SpinButton spin_button; // For RSA
private Gtk.ComboBoxText combobox; // For ECDSA
@@ -35,12 +35,13 @@ public class Seahorse.Ssh.KeyLengthChooser : Gtk.Stack {
public Algorithm algorithm { get; set; }
public KeyLengthChooser(Algorithm algo = Algorithm.RSA) {
- this.visible = true;
+ var stack = new Gtk.Stack();
+ this.child = stack;
// RSA
var rsa_size_adj = new Gtk.Adjustment(2048, 1024, 8193, 256, 10, 1);
this.spin_button = new Gtk.SpinButton(rsa_size_adj, 1, 0);
- add(this.spin_button);
+ stack.add_child(this.spin_button);
// ECDSA
this.combobox = new Gtk.ComboBoxText();
@@ -48,13 +49,11 @@ public class Seahorse.Ssh.KeyLengthChooser : Gtk.Stack {
this.combobox.append_text("384");
this.combobox.append_text("521");
this.combobox.active = 0;
- add(this.combobox);
+ stack.add_child(this.combobox);
// DSA, ED25519, and Unknown
this.not_supported = new Gtk.Label(null);
- add(this.not_supported);
-
- show_all();
+ stack.add_child(this.not_supported);
// Now set the initial algorithm
this.notify["algorithm"].connect(on_algo_changed);
@@ -81,24 +80,26 @@ public class Seahorse.Ssh.KeyLengthChooser : Gtk.Stack {
}
private void on_algo_changed (GLib.Object src, ParamSpec pspec) {
+ unowned var stack = (Gtk.Stack) this.child;
+
switch (this.algorithm) {
case Algorithm.RSA:
- this.visible_child = this.spin_button;
+ stack.visible_child = this.spin_button;
break;
case Algorithm.ECDSA:
- this.visible_child = this.combobox;
+ stack.visible_child = this.combobox;
break;
case Algorithm.DSA:
this.not_supported.label = _("1024 bits");
- this.visible_child = this.not_supported;
+ stack.visible_child = this.not_supported;
break;
case Algorithm.ED25519:
this.not_supported.label = _("256 bits");
- this.visible_child = this.not_supported;
+ stack.visible_child = this.not_supported;
break;
case Algorithm.UNKNOWN:
this.not_supported.label = _("Unknown key type!");
- this.visible_child = this.not_supported;
+ stack.visible_child = this.not_supported;
break;
}
}
diff --git a/ssh/key-properties.vala b/ssh/key-properties.vala
index 102940d5..a347bb96 100644
--- a/ssh/key-properties.vala
+++ b/ssh/key-properties.vala
@@ -28,7 +28,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
private bool updating_ui = false;
[GtkChild]
- private unowned Gtk.Entry comment_entry;
+ private unowned Adw.EntryRow comment_row;
[GtkChild]
private unowned Gtk.Switch trust_check;
[GtkChild]
@@ -71,7 +71,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
this.updating_ui = true;
// Name and title
- this.comment_entry.text = this.key.label;
+ this.comment_row.text = this.key.label;
// Setup the check
this.trust_check.active = (this.key.trust >= Seahorse.Validity.FULL);
@@ -90,7 +90,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
}
[GtkCallback]
- public void on_ssh_comment_activate(Gtk.Entry entry) {
+ public void on_ssh_comment_apply(Adw.EntryRow entry) {
// Make sure not the same
if (key.key_data.comment != null && entry.text == key.key_data.comment)
return;
@@ -110,12 +110,6 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
});
}
- [GtkCallback]
- private bool on_ssh_comment_focus_out(Gtk.Widget widget, Gdk.EventFocus event) {
- on_ssh_comment_activate((Gtk.Entry) widget);
- return false;
- }
-
[GtkCallback]
private void on_ssh_trust_changed(GLib.Object button, GLib.ParamSpec p) {
if (updating_ui)
@@ -154,24 +148,28 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
[GtkCallback]
private void on_delete_clicked(Gtk.Button button) {
var deleter = this.key.create_deleter();
- var ret = deleter.prompt(this);
- if (!ret)
- return;
-
- deleter.delete.begin(null, (obj, res) => {
- try {
- deleter.delete.end(res);
- this.destroy();
- } catch (GLib.Error e) {
- var dialog = new Gtk.MessageDialog(this,
- Gtk.DialogFlags.MODAL,
- Gtk.MessageType.ERROR,
- Gtk.ButtonsType.OK,
- _("Error deleting the SSH key."));
- dialog.run();
- dialog.destroy();
+ var prompt = deleter.create_confirm(this);
+ //XXX
+ ((Gtk.Dialog) prompt).response.connect((response) => {
+ if (response != Gtk.ResponseType.ACCEPT) {
+ prompt.destroy();
+ return;
}
+ prompt.destroy();
+
+ deleter.delete.begin(null, (obj, res) => {
+ try {
+ deleter.delete.end(res);
+ this.destroy();
+ } catch (GLib.Error e) {
+ var dialog = new Gtk.MessageDialog(this,
+ Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.ERROR,
+ Gtk.ButtonsType.OK,
+ _("Error deleting the SSH key."));
+ }
+ });
});
}
@@ -196,9 +194,6 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
[GtkCallback]
private void on_ssh_copy_button_clicked (Gtk.Widget widget) {
- var display = widget.get_display ();
- var clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
-
- clipboard.set_text(this.key.pubkey, -1);
+ widget.get_clipboard().set_text(this.key.pubkey);
}
}
diff --git a/ssh/key.vala b/ssh/key.vala
index e2ebc30b..0e84f82d 100644
--- a/ssh/key.vala
+++ b/ssh/key.vala
@@ -136,11 +136,11 @@ public class Seahorse.Ssh.Key : Seahorse.Object, Seahorse.Exportable, Seahorse.D
if (this.key_data.privfile != null) {
this.usage = Seahorse.Usage.PRIVATE_KEY;
this.object_flags |= Seahorse.Flags.PERSONAL | Seahorse.Flags.TRUSTED;
- this.icon = new ThemedIcon(Gcr.ICON_KEY_PAIR);
+ // this.icon = new ThemedIcon(Gcr.ICON_KEY_PAIR); XXX
} else {
this.object_flags = 0;
this.usage = Seahorse.Usage.PUBLIC_KEY;
- this.icon = new ThemedIcon(Gcr.ICON_KEY);
+ // this.icon = new ThemedIcon(Gcr.ICON_KEY); XXX
}
string filename = Path.get_basename(this.key_data.privfile ?? this.key_data.pubfile);
diff --git a/ssh/meson.build b/ssh/meson.build
index 15418772..5d6bb093 100644
--- a/ssh/meson.build
+++ b/ssh/meson.build
@@ -18,10 +18,9 @@ ssh_sources = files(
ssh_dependencies = [
glib_deps,
- gcr,
- gcr_ui,
+ gcr4_dep,
posix,
- gtk,
+ gtk4_dep,
common_dep,
]
@@ -46,8 +45,8 @@ ssh_askpass_sources = files(
)
ssh_askpass_dependencies = [
- gcr,
- gtk,
+ gcr4_dep,
+ gtk4_dep,
config,
common_dep,
]
diff --git a/ssh/operation.vala b/ssh/operation.vala
index afa161ce..fa06529f 100644
--- a/ssh/operation.vala
+++ b/ssh/operation.vala
@@ -36,7 +36,6 @@ public abstract class Operation : GLib.Object {
protected string? prompt_title;
protected string? prompt_message;
protected string? prompt_argument;
- protected ulong prompt_transient_for;
/**
* Calls a command and returns the output.
@@ -77,10 +76,6 @@ public abstract class Operation : GLib.Object {
launcher.setenv("SEAHORSE_SSH_ASKPASS_TITLE", prompt_title, true);
if (this.prompt_message != null)
launcher.setenv("SEAHORSE_SSH_ASKPASS_MESSAGE", prompt_message, true);
- if (this.prompt_transient_for != 0) {
- string parent = "%lu".printf(prompt_transient_for);
- launcher.setenv("SEAHORSE_SSH_ASKPASS_PARENT", parent, true);
- }
// And off we go to run the program
var subprocess = launcher.spawnv(args);
diff --git a/ssh/seahorse-ssh-askpass.c b/ssh/seahorse-ssh-askpass.c
index b187fb9f..dbcc5f8c 100644
--- a/ssh/seahorse-ssh-askpass.c
+++ b/ssh/seahorse-ssh-askpass.c
@@ -32,113 +32,113 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkx.h>
-#endif
+static SeahorsePassphrasePrompt *dialog = NULL;
+static int response = GTK_RESPONSE_CANCEL;
+
+static void
+on_response (GtkDialog *dialog,
+ int resp,
+ void *user_data)
+{
+ GApplication *app = G_APPLICATION (user_data);
+
+ response = resp;
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+ g_application_quit (app);
+}
+
+static int
+on_app_command_line (GApplication *app,
+ GApplicationCommandLine *cmd_line,
+ void *user_data)
+{
+ g_auto(GStrv) argv = NULL;
+ int argc;
+ const char *title;
+ const char *argument;
+ g_autofree char *message = NULL;
+ const char *flags;
+
+ title = g_getenv ("SEAHORSE_SSH_ASKPASS_TITLE");
+ if (!title || !title[0])
+ title = _("Enter your Secure Shell passphrase:");
+
+ message = (char *) g_getenv ("SEAHORSE_SSH_ASKPASS_MESSAGE");
+ argv = g_application_command_line_get_arguments (cmd_line, &argc);
+ if (message && message[0])
+ message = g_strdup (message);
+ else if (argc > 1)
+ message = g_strjoinv (" ", argv + 1);
+ else
+ message = g_strdup (_("Enter your Secure Shell passphrase:"));
+
+ argument = g_getenv ("SEAHORSE_SSH_ASKPASS_ARGUMENT");
+ if (!argument)
+ argument = "";
+
+ flags = g_getenv ("SEAHORSE_SSH_ASKPASS_FLAGS");
+ if (!flags)
+ flags = "";
+ if (strstr (flags, "multiple")) {
+ g_autofree char *lower = g_ascii_strdown (message, -1);
+
+ /* Need the old passphrase */
+ if (strstr (lower, "old pass")) {
+ title = _("Old Key Passphrase");
+ message = g_strdup_printf (_("Enter the old passphrase for: %s"), argument);
+
+ /* Look for the new passphrase thingy */
+ } else if (strstr (lower, "new pass")) {
+ title = _("New Key Passphrase");
+ message = g_strdup_printf (_("Enter the new passphrase for: %s"), argument);
+
+ /* Confirm the new passphrase, just send it again */
+ } else if (strstr (lower, "again")) {
+ title = _("New Key Passphrase");
+ message = g_strdup_printf (_("Enter the new passphrase again: %s"), argument);
+ }
+ }
+
+ dialog = seahorse_passphrase_prompt_show_dialog (title, message, _("Password:"),
+ NULL, FALSE);
+ g_signal_connect (dialog, "response", G_CALLBACK (on_response), app);
+ gtk_window_present (GTK_WINDOW (dialog));
+
+ return 0;
+}
int
main (int argc, char* argv[])
{
- GdkWindow *transient_for = NULL;
- SeahorsePassphrasePrompt *dialog;
- const gchar *title;
- const gchar *argument;
- gchar *message;
- const gchar *flags;
- int result;
- const gchar *pass;
- gulong xid;
- gssize len;
-
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- gtk_init (&argc, &argv);
-
- /* Non buffered stdout */
- setvbuf (stdout, 0, _IONBF, 0);
-
-#ifdef GDK_WINDOWING_X11
- argument = g_getenv ("SEAHORSE_SSH_ASKPASS_PARENT");
- if (argument) {
- GdkDisplay *display = gdk_display_get_default ();
- if (GDK_IS_X11_DISPLAY (display)) {
- xid = strtoul (argument, NULL, 10);
- if (xid != 0)
- transient_for = gdk_x11_window_foreign_new_for_display (display, xid);
- if (transient_for == NULL)
- g_warning ("Couldn't find window to be transient for: %s", argument);
- }
- }
-#endif
-
- title = g_getenv ("SEAHORSE_SSH_ASKPASS_TITLE");
- if (!title || !title[0])
- title = _("Enter your Secure Shell passphrase:");
-
- message = (gchar *)g_getenv ("SEAHORSE_SSH_ASKPASS_MESSAGE");
- if (message && message[0])
- message = g_strdup (message);
- else if (argc > 1)
- message = g_strjoinv (" ", argv + 1);
- else
- message = g_strdup (_("Enter your Secure Shell passphrase:"));
-
- argument = g_getenv ("SEAHORSE_SSH_ASKPASS_ARGUMENT");
- if (!argument)
- argument = "";
-
- flags = g_getenv ("SEAHORSE_SSH_ASKPASS_FLAGS");
- if (!flags)
- flags = "";
- if (strstr (flags, "multiple")) {
- gchar *lower = g_ascii_strdown (message, -1);
-
- /* Need the old passphrase */
- if (strstr (lower, "old pass")) {
- title = _("Old Key Passphrase");
- message = g_strdup_printf (_("Enter the old passphrase for: %s"), argument);
-
- /* Look for the new passphrase thingy */
- } else if (strstr (lower, "new pass")) {
- title = _("New Key Passphrase");
- message = g_strdup_printf (_("Enter the new passphrase for: %s"), argument);
-
- /* Confirm the new passphrase, just send it again */
- } else if (strstr (lower, "again")) {
- title = _("New Key Passphrase");
- message = g_strdup_printf (_("Enter the new passphrase again: %s"), argument);
- }
-
- g_free (lower);
- }
-
- dialog = seahorse_passphrase_prompt_show_dialog (title, message, _("Password:"),
- NULL, FALSE);
-
- g_free (message);
-
- if (transient_for) {
- gdk_window_set_transient_for (gtk_widget_get_window (GTK_WIDGET (dialog)),
- transient_for);
- }
-
- result = 1;
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
- pass = seahorse_passphrase_prompt_get_text (dialog);
- len = strlen (pass ? pass : "");
- if (write (1, pass, len) != len) {
- g_warning ("couldn't write out password properly");
- result = 1;
- } else {
- result = 0;
- }
- }
-
- if (transient_for)
- g_object_unref (transient_for);
- gtk_widget_destroy (GTK_WIDGET (dialog));
- return result;
-}
+ g_autoptr(GtkApplication) app = NULL;
+ int result;
+ const char *pass;
+ gssize len;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ /* Non buffered stdout */
+ setvbuf (stdout, 0, _IONBF, 0);
+
+ app = gtk_application_new (NULL, G_APPLICATION_HANDLES_COMMAND_LINE);
+ g_signal_connect (app, "command-line", G_CALLBACK (on_app_command_line), NULL);
+ result = g_application_run (G_APPLICATION (app), argc, argv);
+ if (result != 0)
+ return result;
+
+ if (response != GTK_RESPONSE_ACCEPT)
+ return 2;
+
+ pass = seahorse_passphrase_prompt_get_text (dialog);
+ len = strlen (pass ? pass : "");
+ if (write (1, pass, len) != len) {
+ g_warning ("couldn't write out password properly");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/ssh/seahorse-ssh-generate.ui b/ssh/seahorse-ssh-generate.ui
index a9db2c27..f7a00130 100644
--- a/ssh/seahorse-ssh-generate.ui
+++ b/ssh/seahorse-ssh-generate.ui
@@ -1,207 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.24"/>
<template class="SeahorseSshGenerate" parent="GtkDialog">
<property name="modal">True</property>
- <property name="border_width">18</property>
<property name="title" translatable="yes">New Secure Shell Key</property>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="orientation">vertical</property>
- <property name="spacing">2</property>
+ <property name="spacing">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<child>
- <object class="GtkBox" id="vbox5">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
+ <object class="GtkLabel" id="label45">
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">A Secure Shell (SSH) key lets you connect securely to
other computers.</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwPreferencesGroup">
<child>
- <object class="GtkBox" id="vbox3">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkBox" id="hbox41">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="label45">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">A Secure Shell (SSH) key lets you connect
securely to other computers.</property>
- <property name="wrap">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="details_grid">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
- <child>
- <object class="GtkLabel" id="email_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">_Description</property>
- <property name="use_markup">True</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">email_entry</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="email_entry">
- <property name="width_request">180</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="activates_default">True</property>
- <property name="invisible_char_set">True</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xpad">3</property>
- <property name="label" translatable="yes">Your email address, or a reminder of what
this key is for.</property>
- <property name="wrap">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label49">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Encryption _Type</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">algorithm_combo_box</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBoxText" id="algorithm_combo_box">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="can_focus">False</property>
- <property name="entry_text_column">0</property>
- <property name="id_column">1</property>
- <items>
- <item translatable="yes">RSA</item>
- <item translatable="yes">DSA</item>
- <item translatable="yes">ECDSA</item>
- <item translatable="yes">ED25519</item>
- </items>
- <signal name="changed" handler="on_algo_changed"/>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="left_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label50">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="label" translatable="yes">Key _Strength (bits)</property>
- <property name="use_underline">True</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="left_attach">0</property>
- </packing>
- </child>
- <child>
- <!-- Key strength widget comes here -->
- <placeholder/>
- </child>
+ <object class="AdwEntryRow" id="email_row">
+ <property name="title" translatable="yes">_Description</property>
+ <property name="use_underline">True</property>
+ <!-- XXX Ideally, this would be a placeholder-text instead -->
+ <property name="tooltip-text" translatable="yes">Your email address, or a reminder of what
this key is for.</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwActionRow" id="algo_row">
+ <property name="title" translatable="yes">Encryption _Type</property>
+ <property name="use_underline">True</property>
+ <child type="suffix">
+ <object class="GtkComboBoxText" id="algorithm_combo_box">
+ <property name="valign">center</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <items>
+ <item translatable="yes">RSA</item>
+ <item translatable="yes">DSA</item>
+ <item translatable="yes">ECDSA</item>
+ <item translatable="yes">ED25519</item>
+ </items>
+ <signal name="changed" handler="on_algo_changed"/>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
<child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_top">24</property>
- <property name="xalign">0</property>
- <property name="max-width-chars">75</property>
- <property name="label" translatable="yes">If there is a computer you want to use this key
with, you can set up that computer to recognize your new key.</property>
- <property name="wrap">True</property>
+ <object class="AdwActionRow" id="key_strength_row">
+ <property name="title" translatable="yes">Key _Strength (bits)</property>
+ <property name="use_underline">True</property>
</object>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="margin-top">24</property>
+ <property name="xalign">0</property>
+ <property name="max-width-chars">75</property>
+ <property name="label" translatable="yes">If there is a computer you want to use this key with,
you can set up that computer to recognize your new key.</property>
+ <property name="wrap">True</property>
+ </object>
</child>
</object>
</child>
<child type="action">
<object class="GtkButton" id="cancel_button">
<property name="label" translatable="yes">_Cancel</property>
- <property name="visible">True</property>
- <property name="receives_default">False</property>
<property name="use_underline">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
<property name="label" translatable="yes">_Generate</property>
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
<property name="use_underline">True</property>
</object>
</child>
diff --git a/ssh/seahorse-ssh-key-properties.ui b/ssh/seahorse-ssh-key-properties.ui
index 4959250d..0e3b58fc 100644
--- a/ssh/seahorse-ssh-key-properties.ui
+++ b/ssh/seahorse-ssh-key-properties.ui
@@ -1,214 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.22"/>
<template class="SeahorseSshKeyProperties" parent="GtkDialog">
- <property name="can_focus">False</property>
<property name="resizable">False</property>
<child type="titlebar">
<object class="GtkHeaderBar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="title" translatable="yes">SSH Key Properties</property>
- <property name="has_subtitle">False</property>
- <property name="show_close_button">True</property>
+ <property name="show-title-buttons">True</property>
+ <property name="title-widget">
+ <object class="AdwWindowTitle">
+ <property name="title" translatable="yes">SSH Key Properties</property>
+ </object>
+ </property>
</object>
</child>
- <child internal-child="vbox">
+ <child internal-child="content_area">
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
- <object class="GtkButtonBox">
- <property name="can_focus">False</property>
+ <object class="GtkBox">
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
<property name="orientation">vertical</property>
<property name="spacing">20</property>
<child>
<object class="GtkListBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="selection-mode">none</property>
<style>
- <class name="content"/>
+ <class name="boxed-list"/>
</style>
<child>
- <object class="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="margin-top">6</property>
- <property name="margin-bottom">6</property>
- <property name="margin-start">12</property>
- <property name="margin-end">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes" context="name-of-ssh-key"
comments="Name of key, often a persons name">Name</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkEntry" id="comment_entry">
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="width-chars">24</property>
- <property name="activates_default">True</property>
- <signal name="activate" handler="on_ssh_comment_activate" swapped="no"/>
- <signal name="focus-out-event" handler="on_ssh_comment_focus_out" swapped="no"/>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
- </object>
- </child>
+ <object class="AdwEntryRow" id="comment_row">
+ <property name="show-apply-button">True</property>
+ <property name="title" translatable="yes" context="name-of-ssh-key" comments="Name of
key, often a persons name">Name</property>
+ <signal name="apply" handler="on_ssh_comment_apply"/>
</object>
</child>
<child>
- <object class="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="margin">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Algorithm</property>
- <property name="halign">start</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="algo_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="selectable">True</property>
- <property name="xalign">1</property>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Algorithm</property>
+ <child type="suffix">
+ <object class="GtkLabel" id="algo_label">
+ <property name="selectable">True</property>
</object>
</child>
</object>
</child>
<child>
- <object class="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Key Length</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="margin">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Key Length</property>
- <property name="halign">start</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="key_length_label">
- <property name="visible">True</property>
+ <object class="GtkLabel" id="key_length_label">
<property name="selectable">True</property>
- <property name="xalign">1</property>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
</object>
</child>
</object>
</child>
<child>
- <object class="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Location</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="margin">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Location</property>
- <property name="halign">start</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="location_label">
- <property name="visible">True</property>
- <property name="use_markup">True</property>
- <property name="selectable">True</property>
- <property name="ellipsize">start</property>
- <property name="xalign">1</property>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
+ <object class="GtkLabel" id="location_label">
+ <property name="use_markup">True</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">start</property>
</object>
</child>
</object>
</child>
<child>
- <object class="GtkListBoxRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
+ <property name="title" translatable="yes">Fingerprint</property>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">horizontal</property>
- <property name="margin">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Fingerprint</property>
- <property name="halign">start</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="fingerprint_label">
- <property name="visible">True</property>
- <property name="selectable">True</property>
- <property name="xalign">1</property>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
+ <object class="GtkLabel" id="fingerprint_label">
+ <property name="selectable">True</property>
</object>
</child>
</object>
@@ -217,28 +87,21 @@
</child>
<child>
<object class="GtkListBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="selection-mode">none</property>
<style>
<class name="content"/>
</style>
<child>
- <object class="HdyExpanderRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwExpanderRow">
<property name="title" translatable="yes">Public Key</property>
<child type="action">
<object class="GtkButton" id="copy_button">
- <property name="visible">True</property>
<property name="valign">center</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Copy public key to
clipboard</property>
<signal name="clicked" handler="on_ssh_copy_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
- <property name="visible">True</property>
<property name="icon_name">edit-copy-symbolic</property>
</object>
</child>
@@ -249,8 +112,6 @@
</child>
<child>
<object class="GtkLabel" id="pubkey_label">
- <property name="visible">True</property>
- <property name="margin">12</property>
<property name="wrap">True</property>
<property name="wrap_mode">char</property>
<property name="selectable">True</property>
@@ -263,23 +124,17 @@
</child>
<child>
<object class="GtkListBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="selection-mode">none</property>
<style>
<class name="content"/>
</style>
<child>
- <object class="HdyActionRow">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <object class="AdwActionRow">
<property name="title" translatable="yes">Remote access</property>
<property name="subtitle" translatable="yes">Allows accessing this computer
remotely</property>
<property name="activatable_widget">trust_check</property>
<child>
<object class="GtkSwitch" id="trust_check">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="valign">center</property>
<signal name="notify::active" handler="on_ssh_trust_changed" swapped="no"/>
</object>
@@ -290,45 +145,29 @@
</child>
<child>
<object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="halign">end</property>
<property name="spacing">12</property>
<child>
<object class="GtkButton" id="export_button">
<property name="label" translatable="yes">_Export</property>
- <property name="visible">True</property>
<property name="use_underline">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_ssh_export_button_clicked" swapped="no"/>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
</child>
<child>
<object class="GtkButton" id="passphrase_button">
<property name="label" translatable="yes">Change _Passphrase</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">end</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_ssh_passphrase_button_clicked" swapped="no"/>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">_Delete SSH Key</property>
- <property name="visible">True</property>
<property name="use_underline">True</property>
- <property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">end</property>
<signal name="clicked" handler="on_delete_clicked" swapped="no"/>
@@ -336,22 +175,10 @@
<class name="destructive-action"/>
</style>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
</child>
</object>
</child>
diff --git a/ssh/source.vala b/ssh/source.vala
index c4646c9f..911af7f5 100644
--- a/ssh/source.vala
+++ b/ssh/source.vala
@@ -23,7 +23,7 @@
* The {@link Place} where SSH keys are stored. By default that is ~/.ssh.
* Basically, this becomes an interface to the SSH home directory.
*/
-public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
+public class Seahorse.Ssh.Source : GLib.Object, GLib.ListModel, Seahorse.Place {
// Paths to the authorized_keys file and one for unauthorized keys
// The second file is Seahorse-specific, to allow users to retain public
@@ -40,7 +40,7 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
private FileMonitor? monitor_handle = null;
// The list of Seahorse.Ssh.Keys
- private ListStore keys = new ListStore(typeof(Ssh.Key));
+ private GenericArray<Ssh.Key> keys = new GenericArray<Ssh.Key>();
public string label {
owned get { return _("OpenSSH keys"); }
@@ -55,10 +55,6 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
owned get { return _("openssh://%s").printf(this.ssh_homedir); }
}
- public Icon icon {
- owned get { return new ThemedIcon(Gcr.ICON_HOME_DIRECTORY); }
- }
-
public Place.Category category {
get { return Place.Category.KEYS; }
}
@@ -75,10 +71,6 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
owned get { return null; }
}
- public bool show_if_empty {
- get { return true; }
- }
-
/**
* The directory containing the SSH keys.
*/
@@ -173,26 +165,25 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
}
}
- public uint get_length() {
- return this.keys.get_n_items();
+ public GLib.Type get_item_type() {
+ return typeof(Ssh.Key);
}
- public List<weak GLib.Object> get_objects() {
- var objects = new List<weak GLib.Object>();
- for (uint i = 0; i < this.keys.get_n_items(); i++)
- objects.append(this.keys.get_item(i));
- return objects;
+ public uint get_n_items() {
+ return this.keys.length;
}
- public bool contains(GLib.Object object) {
- return this.keys.find(object, null);
+ public GLib.Object? get_item(uint index) {
+ if (index >= this.keys.length)
+ return null;
+ return this.keys[index];
}
- public void remove_object(GLib.Object object) {
+ public void remove_object(Ssh.Key key) {
uint pos;
- if (this.keys.find(object, out pos)) {
- this.keys.remove(pos);
- removed(object);
+ if (this.keys.find(key, out pos)) {
+ this.keys.remove_index(pos);
+ items_changed(pos, 1, 0);
}
}
@@ -209,8 +200,8 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
return null;
// Check if it was already loaded once. If not, load it now
- for (uint i = 0; i < this.keys.get_n_items(); i++) {
- var key = (Ssh.Key) this.keys.get_item(i);
+ for (uint i = 0; i < this.keys.length; i++) {
+ unowned var key = this.keys[i];
if (key.key_data.privfile == privfile) {
return key;
}
@@ -324,8 +315,8 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
// Create a new key
Key key = new Key(src, keydata);
- src.keys.append(key);
- src.added(key);
+ src.keys.add(key);
+ src.items_changed(src.keys.length - 1, 0, 1);
return key;
}
@@ -455,11 +446,9 @@ public class Seahorse.Ssh.Source : GLib.Object, Gcr.Collection, Seahorse.Place {
}
public Key? find_key_by_fingerprint(string fingerprint) {
- for (uint i = 0; i < this.keys.get_n_items(); i++) {
- var key = (Ssh.Key) this.keys.get_item(i);
- if (key.fingerprint == fingerprint) {
- return key;
- }
+ for (uint i = 0; i < this.keys.length; i++) {
+ if (this.keys[i].fingerprint == fingerprint)
+ return this.keys[i];
}
return null;
diff --git a/ssh/upload.vala b/ssh/upload.vala
index aa76801d..90fe7709 100644
--- a/ssh/upload.vala
+++ b/ssh/upload.vala
@@ -98,22 +98,11 @@ public class Seahorse.Ssh.Upload : Gtk.Dialog {
return;
Upload upload_dialog = new Upload(keys, parent);
- for (;;) {
- switch (upload_dialog.run()) {
- case Gtk.ResponseType.HELP:
- /* TODO: Help */
- continue;
- case Gtk.ResponseType.ACCEPT:
+ upload_dialog.response.connect((response) => {
+ if (response == Gtk.ResponseType.ACCEPT)
upload_dialog.upload_keys();
- break;
- default:
- break;
- };
-
- break;
- }
-
- upload_dialog.destroy();
+ upload_dialog.destroy();
+ });
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]