Ensure new accounts can be created by hitting Enter.
This commit is contained in:
parent
468a7a674b
commit
81e04a21d5
2 changed files with 60 additions and 34 deletions
|
|
@ -68,6 +68,8 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
|
|||
private LoginRow smtp_login = new LoginRow();
|
||||
private PasswordRow smtp_password = new PasswordRow();
|
||||
|
||||
private bool controls_valid = false;
|
||||
|
||||
|
||||
internal EditorAddPane(Editor editor, Geary.ServiceProvider provider) {
|
||||
this.editor = editor;
|
||||
|
|
@ -101,20 +103,28 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
|
|||
this.details_list.add(this.real_name);
|
||||
this.details_list.add(this.email);
|
||||
|
||||
this.real_name.validator.notify["state"].connect(on_validated);
|
||||
this.email.validator.notify["state"].connect(on_validated);
|
||||
this.real_name.validator.state_changed.connect(on_validated);
|
||||
this.real_name.value.activate.connect(on_activated);
|
||||
this.email.validator.state_changed.connect(on_validated);
|
||||
this.email.value.activate.connect(on_activated);
|
||||
this.email.value.changed.connect(on_email_changed);
|
||||
|
||||
this.imap_hostname.validator.notify["state"].connect(on_validated);
|
||||
this.imap_hostname.validator.state_changed.connect(on_validated);
|
||||
this.imap_hostname.value.activate.connect(on_activated);
|
||||
this.imap_tls.hide();
|
||||
this.imap_login.validator.notify["state"].connect(on_validated);
|
||||
this.imap_password.validator.notify["state"].connect(on_validated);
|
||||
this.imap_login.validator.state_changed.connect(on_validated);
|
||||
this.imap_login.value.activate.connect(on_activated);
|
||||
this.imap_password.validator.state_changed.connect(on_validated);
|
||||
this.imap_password.value.activate.connect(on_activated);
|
||||
|
||||
this.smtp_hostname.validator.notify["state"].connect(on_validated);
|
||||
this.smtp_hostname.validator.state_changed.connect(on_validated);
|
||||
this.smtp_hostname.value.activate.connect(on_activated);
|
||||
this.smtp_tls.hide();
|
||||
this.smtp_auth.value.changed.connect(on_smtp_auth_changed);
|
||||
this.smtp_login.validator.notify["state"].connect(on_validated);
|
||||
this.smtp_password.validator.notify["state"].connect(on_validated);
|
||||
this.smtp_login.validator.state_changed.connect(on_validated);
|
||||
this.smtp_login.value.activate.connect(on_activated);
|
||||
this.smtp_password.validator.state_changed.connect(on_validated);
|
||||
this.smtp_password.value.activate.connect(on_activated);
|
||||
|
||||
if (provider == Geary.ServiceProvider.OTHER) {
|
||||
this.receiving_list.add(this.imap_hostname);
|
||||
|
|
@ -346,22 +356,32 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
|
|||
}
|
||||
|
||||
private void check_validation() {
|
||||
bool is_valid = true;
|
||||
bool controls_valid = true;
|
||||
foreach (Gtk.ListBox list in new Gtk.ListBox[] {
|
||||
this.details_list, this.receiving_list, this.sending_list
|
||||
}) {
|
||||
list.foreach((child) => {
|
||||
AddPaneRow? validatable = child as AddPaneRow;
|
||||
if (validatable != null && !validatable.validator.is_valid) {
|
||||
is_valid = false;
|
||||
controls_valid = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.create_button.set_sensitive(is_valid);
|
||||
this.create_button.set_sensitive(controls_valid);
|
||||
this.controls_valid = controls_valid;
|
||||
}
|
||||
|
||||
private void on_validated() {
|
||||
private void on_validated(Components.Validator.Trigger reason) {
|
||||
check_validation();
|
||||
if (this.controls_valid && reason == Components.Validator.Trigger.ACTIVATED) {
|
||||
this.create_button.clicked();
|
||||
}
|
||||
}
|
||||
|
||||
private void on_activated() {
|
||||
if (this.controls_valid) {
|
||||
this.create_button.clicked();
|
||||
}
|
||||
}
|
||||
|
||||
private void on_email_changed() {
|
||||
|
|
|
|||
|
|
@ -47,11 +47,13 @@ public class Components.Validator : GLib.Object {
|
|||
}
|
||||
|
||||
/** The cause of a validity check being required. */
|
||||
protected enum Trigger {
|
||||
public enum Trigger {
|
||||
/** The entry's contents changed */
|
||||
CHANGED,
|
||||
/** The user performed an action indicating they are done. */
|
||||
COMPLETE;
|
||||
/** The entry lost the keyboard focus. */
|
||||
LOST_FOCUS,
|
||||
/** The user activated the entry. */
|
||||
ACTIVATED;
|
||||
}
|
||||
|
||||
/** Defines the UI state for a specific validity. */
|
||||
|
|
@ -100,6 +102,10 @@ public class Components.Validator : GLib.Object {
|
|||
private Geary.TimeoutManager ui_update_timer;
|
||||
|
||||
|
||||
/** Fired when the validation state changes. */
|
||||
public signal void state_changed(Trigger reason, Validity prev_state);
|
||||
|
||||
|
||||
public Validator(Gtk.Entry target) {
|
||||
this.target = target;
|
||||
|
||||
|
|
@ -157,7 +163,7 @@ public class Components.Validator : GLib.Object {
|
|||
* By default, this always returns {@link Validity.VALID}, making
|
||||
* it useful for required, but otherwise free-form fields only.
|
||||
*/
|
||||
protected virtual Validity validate(string value, Trigger cause) {
|
||||
protected virtual Validity validate(string value, Trigger reason) {
|
||||
return Validity.VALID;
|
||||
}
|
||||
|
||||
|
|
@ -168,14 +174,20 @@ public class Components.Validator : GLib.Object {
|
|||
* CPU-intensive or long-running validation routine and it has
|
||||
* completed validating a value. See {@link validate} for details.
|
||||
*/
|
||||
protected void update_state(Validity new_state) {
|
||||
protected void update_state(Validity new_state, Trigger reason) {
|
||||
if (this.state != new_state) {
|
||||
Validity old_state = this.state;
|
||||
|
||||
// Fire the signal after updating the state but before
|
||||
// updating the UI so listeners can update UI settings
|
||||
// first if needed.
|
||||
this.state = new_state;
|
||||
if (new_state == Validity.VALID) {
|
||||
// Update the UI straight away when going valid to
|
||||
// provide instant feedback
|
||||
state_changed(reason, old_state);
|
||||
|
||||
if (new_state == Validity.VALID || reason != Trigger.CHANGED) {
|
||||
// Update the UI straight away when going valid or
|
||||
// when editing is complete to provide instant
|
||||
// feedback
|
||||
update_ui(new_state);
|
||||
} else {
|
||||
if (old_state == Validity.EMPTY) {
|
||||
|
|
@ -194,23 +206,17 @@ public class Components.Validator : GLib.Object {
|
|||
}
|
||||
}
|
||||
|
||||
private void validate_entry(Trigger cause) {
|
||||
private void validate_entry(Trigger reason) {
|
||||
string value = this.target.get_text();
|
||||
Validity new_state = this.state;
|
||||
if (Geary.String.is_empty_or_whitespace(value)) {
|
||||
new_state = this.is_required
|
||||
? Validity.EMPTY : Validity.INDETERMINATE;
|
||||
} else {
|
||||
new_state = validate(value, cause);
|
||||
new_state = validate(value, reason);
|
||||
}
|
||||
|
||||
update_state(new_state);
|
||||
|
||||
if (cause == Trigger.COMPLETE) {
|
||||
// Update the UI instantly since we know the user is done
|
||||
// editing it an will want instant feedback.
|
||||
update_ui(this.state);
|
||||
}
|
||||
update_state(new_state, reason);
|
||||
}
|
||||
|
||||
private void update_ui(Validity state) {
|
||||
|
|
@ -256,7 +262,7 @@ public class Components.Validator : GLib.Object {
|
|||
}
|
||||
|
||||
private void on_activate() {
|
||||
validate_entry(Trigger.COMPLETE);
|
||||
validate_entry(Trigger.ACTIVATED);
|
||||
}
|
||||
|
||||
private void on_update_ui() {
|
||||
|
|
@ -275,7 +281,7 @@ public class Components.Validator : GLib.Object {
|
|||
// the focused widget any more, rather than the whole window
|
||||
// having lost focus.
|
||||
if (!this.target.is_focus) {
|
||||
validate_entry(Trigger.COMPLETE);
|
||||
validate_entry(Trigger.LOST_FOCUS);
|
||||
}
|
||||
return Gdk.EVENT_PROPAGATE;
|
||||
}
|
||||
|
|
@ -302,7 +308,7 @@ public class Components.EmailValidator : Validator {
|
|||
|
||||
|
||||
protected override Validator.Validity validate(string value,
|
||||
Validator.Trigger cause) {
|
||||
Validator.Trigger reason) {
|
||||
return Geary.RFC822.MailboxAddress.is_valid_address(value)
|
||||
? Validator.Validity.VALID : Validator.Validity.INVALID;
|
||||
}
|
||||
|
|
@ -384,12 +390,12 @@ public class Components.NetworkAddressValidator : Validator {
|
|||
try {
|
||||
this.resolver.lookup_by_name_async.end(res);
|
||||
this.validated_address = address;
|
||||
update_state(Validator.Validity.VALID);
|
||||
update_state(Validator.Validity.VALID, reason);
|
||||
} catch (GLib.IOError.CANCELLED err) {
|
||||
this.validated_address = null;
|
||||
} catch (GLib.Error err) {
|
||||
this.validated_address = null;
|
||||
update_state(Validator.Validity.INVALID);
|
||||
update_state(Validator.Validity.INVALID, reason);
|
||||
}
|
||||
this.cancellable = null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue