Rename all composer classes prefixed with "Composer" so that the prefix is a namespace instead. This increases the compartmentalisation of the classes, making `internal` a useful member modifier and makes them consistent with the code style guide.
106 lines
3.1 KiB
Vala
106 lines
3.1 KiB
Vala
/* Copyright 2016 Software Freedom Conservancy Inc.
|
|
*
|
|
* This software is licensed under the GNU Lesser General Public License
|
|
* (version 2.1 or later). See the COPYING file in this distribution.
|
|
*/
|
|
|
|
// A custom entry for e-mail addresses
|
|
public class EmailEntry : Gtk.Entry {
|
|
// Whether this entry contains a valid email address
|
|
public bool valid { get; set; default = false; }
|
|
|
|
public bool empty { get; set; default = true; }
|
|
|
|
public bool modified = false;
|
|
|
|
// null or valid addresses
|
|
public Geary.RFC822.MailboxAddresses? addresses { get; set; default = null; }
|
|
|
|
private weak Composer.Widget composer;
|
|
|
|
private bool updating = false;
|
|
|
|
public EmailEntry(Composer.Widget composer) {
|
|
changed.connect(on_changed);
|
|
key_press_event.connect(on_key_press);
|
|
this.composer = composer;
|
|
|
|
notify["addresses"].connect(() => {
|
|
validate_addresses();
|
|
if (updating)
|
|
return;
|
|
|
|
updating = true;
|
|
modified = true;
|
|
text = (addresses == null) ? "" : addresses.to_full_display();
|
|
updating = false;
|
|
});
|
|
|
|
show();
|
|
}
|
|
|
|
private void on_changed() {
|
|
if (updating)
|
|
return;
|
|
modified = true;
|
|
|
|
ContactEntryCompletion? completion = get_completion() as ContactEntryCompletion;
|
|
if (completion != null) {
|
|
completion.update_model();
|
|
}
|
|
|
|
if (Geary.String.is_empty(text.strip())) {
|
|
updating = true;
|
|
addresses = null;
|
|
updating = false;
|
|
valid = false;
|
|
empty = true;
|
|
return;
|
|
}
|
|
|
|
updating = true;
|
|
addresses = new Geary.RFC822.MailboxAddresses.from_rfc822_string(text);
|
|
updating = false;
|
|
}
|
|
|
|
private void validate_addresses() {
|
|
if (addresses == null || addresses.size == 0) {
|
|
valid = false;
|
|
empty = true;
|
|
return;
|
|
}
|
|
empty = false;
|
|
|
|
foreach (Geary.RFC822.MailboxAddress address in addresses) {
|
|
if (!address.is_valid()) {
|
|
valid = false;
|
|
return;
|
|
}
|
|
}
|
|
valid = true;
|
|
}
|
|
|
|
private bool on_key_press(Gtk.Widget widget, Gdk.EventKey event) {
|
|
bool ret = Gdk.EVENT_PROPAGATE;
|
|
if (event.keyval == Gdk.Key.Tab) {
|
|
ContactEntryCompletion? completion = (
|
|
get_completion() as ContactEntryCompletion
|
|
);
|
|
if (completion != null) {
|
|
completion.trigger_selection();
|
|
composer.child_focus(Gtk.DirectionType.TAB_FORWARD);
|
|
ret = Gdk.EVENT_STOP;
|
|
}
|
|
} else {
|
|
// Keyboard shortcuts for undo/redo won't work when the
|
|
// completion UI is visible unless we explicitly check for
|
|
// them there. This may be related to the
|
|
// single-key-shortcut handling hack in the MainWindow.
|
|
Gtk.Window? window = get_toplevel() as Gtk.Window;
|
|
if (window != null) {
|
|
ret = window.activate_key(event);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
}
|