Merge branch 'mjog/misc-fixes' into 'mainline'
Misc fixes See merge request GNOME/geary!369
This commit is contained in:
commit
e576c780c5
30 changed files with 325 additions and 348 deletions
|
|
@ -40,7 +40,7 @@ public class Application.AttachmentManager : GLib.Object {
|
|||
GLib.Cancellable? cancellable) {
|
||||
if (attachments.size == 1) {
|
||||
return yield save_attachment(
|
||||
Geary.Collection.get_first(attachments), null, cancellable
|
||||
Geary.Collection.first(attachments), null, cancellable
|
||||
);
|
||||
} else {
|
||||
return yield save_all(attachments, cancellable);
|
||||
|
|
|
|||
|
|
@ -808,7 +808,23 @@ public class Application.Client : Gtk.Application {
|
|||
this.controller.register_window(window);
|
||||
window.focus_in_event.connect(on_main_window_focus_in);
|
||||
if (select_first_inbox) {
|
||||
window.select_first_inbox(true);
|
||||
if (!window.select_first_inbox(true)) {
|
||||
// The first inbox wasn't selected, so the account is
|
||||
// likely still loading folders after being
|
||||
// opened. Add a listener to try again later.
|
||||
try {
|
||||
Geary.Account? first = Geary.Collection.first<Geary.Account>(
|
||||
this.engine.get_accounts()
|
||||
);
|
||||
if (first != null) {
|
||||
first.folders_available_unavailable.connect_after(
|
||||
on_folders_first_available
|
||||
);
|
||||
}
|
||||
} catch (GLib.Error error) {
|
||||
debug("Error getting Inbox for first account");
|
||||
}
|
||||
}
|
||||
}
|
||||
return window;
|
||||
}
|
||||
|
|
@ -1005,13 +1021,9 @@ public class Application.Client : Gtk.Application {
|
|||
// If there was an existing active main, select the same
|
||||
// account/folder/conversation.
|
||||
MainWindow? current = this.last_active_main_window;
|
||||
// Make a copy of the selection so the underlying collection
|
||||
// doesn't change as the selection does.
|
||||
this.new_window.begin(
|
||||
current.selected_folder,
|
||||
Geary.traverse(
|
||||
current.conversation_list_view.get_selected_conversations()
|
||||
).to_linked_list()
|
||||
current.conversation_list_view.copy_selected()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1093,6 +1105,18 @@ public class Application.Client : Gtk.Application {
|
|||
}
|
||||
}
|
||||
|
||||
private void on_folders_first_available(Geary.Account account,
|
||||
Gee.BidirSortedSet<Geary.Folder>? available,
|
||||
Gee.BidirSortedSet<Geary.Folder>? unavailable
|
||||
) {
|
||||
if (get_active_main_window().select_first_inbox(true)) {
|
||||
// The handler has done its job, so disconnect it
|
||||
account.folders_available_unavailable.disconnect(
|
||||
on_folders_first_available
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private bool on_main_window_focus_in(Gtk.Widget widget,
|
||||
Gdk.EventFocus event) {
|
||||
MainWindow? main = widget as MainWindow;
|
||||
|
|
@ -1107,7 +1131,7 @@ public class Application.Client : Gtk.Application {
|
|||
if (main != null) {
|
||||
this.controller.unregister_window(main);
|
||||
if (this.last_active_main_window == main) {
|
||||
this.last_active_main_window = Geary.Collection.get_first(
|
||||
this.last_active_main_window = Geary.Collection.first(
|
||||
get_main_windows()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,27 +227,6 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
warning("Error loading accounts: %s", e.message);
|
||||
}
|
||||
|
||||
// Since the accounts may still be loading folders, when the
|
||||
// main window first opens no folder might be available to be
|
||||
// selected. Add look for the inbox and if not found, add a
|
||||
// listener here as a once off for when it is loaded.
|
||||
if (!application.get_active_main_window().select_first_inbox(true)) {
|
||||
// Connect after so the folder is added to any
|
||||
// open main windows first.
|
||||
try {
|
||||
Geary.Account first = Geary.Collection.get_first(
|
||||
application.engine.get_accounts()
|
||||
);
|
||||
if (first != null) {
|
||||
first.folders_available_unavailable.connect_after(
|
||||
on_folders_first_available
|
||||
);
|
||||
}
|
||||
} catch (GLib.Error error) {
|
||||
debug("Error getting Inbox for first account");
|
||||
}
|
||||
}
|
||||
|
||||
// Expunge any deleted accounts in the background, so we're
|
||||
// not blocking the app continuing to open.
|
||||
this.expunge_accounts.begin();
|
||||
|
|
@ -1387,18 +1366,6 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
}
|
||||
}
|
||||
|
||||
private void on_folders_first_available(Geary.Account account,
|
||||
Gee.BidirSortedSet<Geary.Folder>? available,
|
||||
Gee.BidirSortedSet<Geary.Folder>? unavailable
|
||||
) {
|
||||
if (application.get_active_main_window().select_first_inbox(true)) {
|
||||
// The handler has done its job, so disconnect it
|
||||
account.folders_available_unavailable.disconnect(
|
||||
on_folders_first_available
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private bool should_notify_new_messages(Geary.Folder folder) {
|
||||
// A monitored folder must be selected to squelch notifications;
|
||||
// if conversation list is at top of display, don't display
|
||||
|
|
|
|||
|
|
@ -586,7 +586,7 @@ public class Application.MainWindow :
|
|||
if (loaded.size == 1) {
|
||||
// A single conversation was loaded, so ensure we
|
||||
// scroll to the email in the conversation.
|
||||
Geary.App.Conversation target = Geary.Collection.get_first(loaded);
|
||||
Geary.App.Conversation? target = Geary.Collection.first(loaded);
|
||||
ConversationListBox? current_list =
|
||||
this.conversation_viewer.current_list;
|
||||
if (current_list != null &&
|
||||
|
|
@ -860,7 +860,7 @@ public class Application.MainWindow :
|
|||
private Geary.Folder? get_first_inbox() {
|
||||
Geary.Folder? inbox = null;
|
||||
try {
|
||||
Geary.Account first = Geary.Collection.get_first(
|
||||
Geary.Account? first = Geary.Collection.first<Geary.Account>(
|
||||
this.application.engine.get_accounts()
|
||||
);
|
||||
if (first != null) {
|
||||
|
|
@ -1285,7 +1285,7 @@ public class Application.MainWindow :
|
|||
|
||||
case 1:
|
||||
update_conversation_actions(SINGLE);
|
||||
Geary.App.Conversation convo = Geary.Collection.get_first(to_select);
|
||||
Geary.App.Conversation? convo = Geary.Collection.first(to_select);
|
||||
|
||||
// It's possible for a conversation with zero email to
|
||||
// be selected, when it has just evaporated after its
|
||||
|
|
@ -1576,7 +1576,7 @@ public class Application.MainWindow :
|
|||
Gee.Collection<Geary.EmailIdentifier> ids =
|
||||
new Gee.LinkedList<Geary.EmailIdentifier>();
|
||||
foreach (Geary.App.Conversation convo in
|
||||
this.conversation_list_view.get_selected_conversations()) {
|
||||
this.conversation_list_view.get_selected()) {
|
||||
ids.add_all(convo.get_email_ids());
|
||||
}
|
||||
try {
|
||||
|
|
@ -1874,13 +1874,9 @@ public class Application.MainWindow :
|
|||
private void on_conversation_activated(Geary.App.Conversation activated) {
|
||||
if (this.selected_folder != null) {
|
||||
if (this.selected_folder.special_folder_type != DRAFTS) {
|
||||
// Make a copy of the selection so the underlying
|
||||
// collection doesn't change as the selection does.
|
||||
this.application.new_window.begin(
|
||||
this.selected_folder,
|
||||
Geary.traverse(
|
||||
this.conversation_list_view.get_selected_conversations()
|
||||
).to_linked_list()
|
||||
this.conversation_list_view.copy_selected()
|
||||
);
|
||||
} else {
|
||||
// TODO: Determine how to map between conversations
|
||||
|
|
@ -1974,7 +1970,7 @@ public class Application.MainWindow :
|
|||
bool starred_selected = false;
|
||||
bool unstarred_selected = false;
|
||||
foreach (Geary.App.Conversation conversation in
|
||||
this.conversation_list_view.get_selected_conversations()) {
|
||||
this.conversation_list_view.get_selected()) {
|
||||
if (conversation.is_unread())
|
||||
unread_selected = true;
|
||||
|
||||
|
|
@ -2031,7 +2027,7 @@ public class Application.MainWindow :
|
|||
if (location != null) {
|
||||
this.application.controller.mark_conversations.begin(
|
||||
location,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
Geary.EmailFlags.UNREAD,
|
||||
false,
|
||||
(obj, res) => {
|
||||
|
|
@ -2050,7 +2046,7 @@ public class Application.MainWindow :
|
|||
if (location != null) {
|
||||
this.application.controller.mark_conversations.begin(
|
||||
location,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
Geary.EmailFlags.UNREAD,
|
||||
true,
|
||||
(obj, res) => {
|
||||
|
|
@ -2069,7 +2065,7 @@ public class Application.MainWindow :
|
|||
if (location != null) {
|
||||
this.application.controller.mark_conversations.begin(
|
||||
location,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
Geary.EmailFlags.FLAGGED,
|
||||
true,
|
||||
(obj, res) => {
|
||||
|
|
@ -2088,7 +2084,7 @@ public class Application.MainWindow :
|
|||
if (location != null) {
|
||||
this.application.controller.mark_conversations.begin(
|
||||
location,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
Geary.EmailFlags.FLAGGED,
|
||||
false,
|
||||
(obj, res) => {
|
||||
|
|
@ -2112,7 +2108,7 @@ public class Application.MainWindow :
|
|||
this.application.controller.move_conversations_special.begin(
|
||||
source,
|
||||
destination,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
(obj, res) => {
|
||||
try {
|
||||
this.application.controller.move_conversations_special.end(res);
|
||||
|
|
@ -2131,7 +2127,7 @@ public class Application.MainWindow :
|
|||
this.application.controller.move_conversations.begin(
|
||||
source,
|
||||
destination,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
(obj, res) => {
|
||||
try {
|
||||
this.application.controller.move_conversations.end(res);
|
||||
|
|
@ -2151,7 +2147,7 @@ public class Application.MainWindow :
|
|||
this.application.controller.copy_conversations.begin(
|
||||
source,
|
||||
destination,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
(obj, res) => {
|
||||
try {
|
||||
this.application.controller.copy_conversations.end(res);
|
||||
|
|
@ -2170,7 +2166,7 @@ public class Application.MainWindow :
|
|||
this.application.controller.move_conversations_special.begin(
|
||||
source,
|
||||
ARCHIVE,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
(obj, res) => {
|
||||
try {
|
||||
this.application.controller.move_conversations_special.end(res);
|
||||
|
|
@ -2188,7 +2184,7 @@ public class Application.MainWindow :
|
|||
this.application.controller.move_conversations_special.begin(
|
||||
source,
|
||||
Geary.SpecialFolderType.TRASH,
|
||||
this.conversation_list_view.get_selected_conversations(),
|
||||
this.conversation_list_view.copy_selected(),
|
||||
(obj, res) => {
|
||||
try {
|
||||
this.application.controller.move_conversations_special.end(res);
|
||||
|
|
@ -2204,7 +2200,7 @@ public class Application.MainWindow :
|
|||
Geary.FolderSupport.Remove target =
|
||||
this.selected_folder as Geary.FolderSupport.Remove;
|
||||
Gee.Collection<Geary.App.Conversation> conversations =
|
||||
this.conversation_list_view.get_selected_conversations();
|
||||
this.conversation_list_view.copy_selected();
|
||||
if (target != null && this.prompt_delete_conversations(conversations.size)) {
|
||||
this.application.controller.delete_conversations.begin(
|
||||
target,
|
||||
|
|
|
|||
|
|
@ -624,24 +624,26 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
|
||||
// Assemble the headers.
|
||||
if (email.length > 0 && headers.contains("to"))
|
||||
this.to = "%s,%s".printf(email, Geary.Collection.get_first(headers.get("to")));
|
||||
this.to = "%s,%s".printf(
|
||||
email, Geary.Collection.first(headers.get("to"))
|
||||
);
|
||||
else if (email.length > 0)
|
||||
this.to = email;
|
||||
else if (headers.contains("to"))
|
||||
this.to = Geary.Collection.get_first(headers.get("to"));
|
||||
this.to = Geary.Collection.first(headers.get("to"));
|
||||
|
||||
if (headers.contains("cc"))
|
||||
this.cc = Geary.Collection.get_first(headers.get("cc"));
|
||||
this.cc = Geary.Collection.first(headers.get("cc"));
|
||||
|
||||
if (headers.contains("bcc"))
|
||||
this.bcc = Geary.Collection.get_first(headers.get("bcc"));
|
||||
this.bcc = Geary.Collection.first(headers.get("bcc"));
|
||||
|
||||
if (headers.contains("subject"))
|
||||
this.subject = Geary.Collection.get_first(headers.get("subject"));
|
||||
this.subject = Geary.Collection.first(headers.get("subject"));
|
||||
|
||||
if (headers.contains("body"))
|
||||
this.body_html = Geary.HTML.preserve_whitespace(Geary.HTML.escape_markup(
|
||||
Geary.Collection.get_first(headers.get("body"))));
|
||||
Geary.Collection.first(headers.get("body"))));
|
||||
|
||||
Gee.List<string> attachments = new Gee.LinkedList<string>();
|
||||
attachments.add_all(headers.get("attach"));
|
||||
|
|
|
|||
|
|
@ -131,11 +131,18 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
selection.changed.connect(on_selection_changed);
|
||||
}
|
||||
|
||||
/** Returns a read-only collection of the current selection. */
|
||||
public Gee.Set<Geary.App.Conversation> get_selected_conversations() {
|
||||
/** Returns a read-only iteration of the current selection. */
|
||||
public Gee.Set<Geary.App.Conversation> get_selected() {
|
||||
return this.selected.read_only_view;
|
||||
}
|
||||
|
||||
/** Returns a copy of the current selection. */
|
||||
public Gee.Set<Geary.App.Conversation> copy_selected() {
|
||||
var copy = new Gee.HashSet<Geary.App.Conversation>();
|
||||
copy.add_all(this.selected);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public void inhibit_next_autoselect() {
|
||||
this.should_inhibit_autoselect = true;
|
||||
}
|
||||
|
|
@ -288,13 +295,11 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
// Get the current conversation. If it's selected, we'll apply the mark operation to
|
||||
// all selected conversations; otherwise, it just applies to this one.
|
||||
Geary.App.Conversation conversation = get_model().get_conversation_at_path(path);
|
||||
Gee.Collection<Geary.App.Conversation> to_mark;
|
||||
if (this.selected.contains(conversation))
|
||||
// take a copy of currently selected for handling to
|
||||
// the signal
|
||||
to_mark = get_selected_conversations();
|
||||
else
|
||||
to_mark = Geary.Collection.single(conversation);
|
||||
Gee.Collection<Geary.App.Conversation> to_mark = (
|
||||
this.selected.contains(conversation)
|
||||
? copy_selected()
|
||||
: Geary.Collection.single(conversation)
|
||||
);
|
||||
|
||||
if (read_clicked) {
|
||||
mark_conversations(to_mark, Geary.EmailFlags.UNREAD);
|
||||
|
|
@ -487,8 +492,8 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
}
|
||||
|
||||
// only notify if different than what was previously reported
|
||||
if (!Geary.Collection.are_sets_equal<Geary.App.Conversation>(
|
||||
this.selected, new_selection)) {
|
||||
if (this.selected.size != new_selection.size ||
|
||||
!this.selected.contains_all(new_selection)) {
|
||||
this.selected = new_selection;
|
||||
conversations_selected(this.selected.read_only_view);
|
||||
}
|
||||
|
|
@ -515,18 +520,18 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
|
||||
// Always returns false, so it can be used as a one-time SourceFunc
|
||||
private bool update_visible_conversations() {
|
||||
bool changed = false;
|
||||
Gee.Set<Geary.App.Conversation> visible_conversations = get_visible_conversations();
|
||||
if (current_visible_conversations != null
|
||||
&& Geary.Collection.are_sets_equal<Geary.App.Conversation>(
|
||||
current_visible_conversations, visible_conversations)) {
|
||||
return false;
|
||||
if (this.current_visible_conversations == null ||
|
||||
this.current_visible_conversations.size != visible_conversations.size ||
|
||||
!this.current_visible_conversations.contains_all(visible_conversations)) {
|
||||
this.current_visible_conversations = visible_conversations;
|
||||
visible_conversations_changed(
|
||||
this.current_visible_conversations.read_only_view
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
current_visible_conversations = visible_conversations;
|
||||
|
||||
visible_conversations_changed(current_visible_conversations.read_only_view);
|
||||
|
||||
return false;
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void schedule_visible_conversations_changed() {
|
||||
|
|
|
|||
|
|
@ -678,7 +678,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
|
|||
id => this.conversation.contains_email_by_id(id)
|
||||
).to_array_list();
|
||||
valid_scroll_to.sort((a, b) => a.natural_sort_comparator(b));
|
||||
var first_scroll = Geary.Collection.get_first(valid_scroll_to);
|
||||
var first_scroll = Geary.Collection.first(valid_scroll_to);
|
||||
|
||||
if (first_scroll != null) {
|
||||
foreach (Geary.Email email in all_email) {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ public class ConversationViewer : Gtk.Stack, Geary.BaseInterface {
|
|||
// XXX move the ConversationListView management code into
|
||||
// MainWindow or somewhere more appropriate
|
||||
ConversationListView conversation_list = main_window.conversation_list_view;
|
||||
this.selection_while_composing = conversation_list.get_selected_conversations();
|
||||
this.selection_while_composing = conversation_list.copy_selected();
|
||||
conversation_list.get_selection().unselect_all();
|
||||
|
||||
box.vanished.connect(on_composer_closed);
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class ConversationWebView : ClientWebView {
|
|||
});
|
||||
|
||||
controller.search(
|
||||
Geary.Collection.get_first(terms),
|
||||
Geary.Collection.first(terms),
|
||||
WebKit.FindOptions.CASE_INSENSITIVE |
|
||||
WebKit.FindOptions.WRAP_AROUND,
|
||||
128
|
||||
|
|
|
|||
|
|
@ -766,17 +766,6 @@ public class Sidebar.Tree : Gtk.TreeView {
|
|||
store.set(iter, Columns.ICON, icon);
|
||||
}
|
||||
|
||||
private void load_branch_icons(Gtk.TreeIter iter) {
|
||||
load_entry_icons(iter);
|
||||
|
||||
Gtk.TreeIter child_iter;
|
||||
if (store.iter_children(out child_iter, iter)) {
|
||||
do {
|
||||
load_branch_icons(child_iter);
|
||||
} while (store.iter_next(ref child_iter));
|
||||
}
|
||||
}
|
||||
|
||||
private bool on_selection(Gtk.TreeSelection selection, Gtk.TreeModel model, Gtk.TreePath path,
|
||||
bool path_currently_selected) {
|
||||
// only allow selection if a page is selectable
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ private class Geary.App.ConversationSet : BaseObject {
|
|||
} else {
|
||||
Gee.Set<Conversation> associated =
|
||||
get_associated_conversations(email);
|
||||
conversation = Collection.get_first<Conversation>(associated);
|
||||
conversation = Collection.first(associated);
|
||||
if (conversation == null) {
|
||||
// Not in or related to any existing conversations, so
|
||||
// create one
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ private class Geary.App.CopyOperation : Geary.App.AsyncFolderOperation {
|
|||
Geary.FolderSupport.Copy? copy = folder as Geary.FolderSupport.Copy;
|
||||
assert(copy != null);
|
||||
|
||||
Gee.List<Geary.EmailIdentifier> list
|
||||
= Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids);
|
||||
yield copy.copy_email_async(list, destination, cancellable);
|
||||
yield copy.copy_email_async(
|
||||
Collection.copy(ids), destination, cancellable
|
||||
);
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ private class Geary.App.FetchOperation : Geary.App.AsyncFolderOperation {
|
|||
Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier> ids,
|
||||
Cancellable? cancellable) throws Error {
|
||||
assert(result == null);
|
||||
Geary.EmailIdentifier? id = Geary.Collection.get_first(ids);
|
||||
Geary.EmailIdentifier? id = Collection.first(ids);
|
||||
assert(id != null);
|
||||
|
||||
result = yield folder.fetch_email_async(
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ private class Geary.App.MarkOperation : Geary.App.AsyncFolderOperation {
|
|||
Geary.FolderSupport.Mark? mark = folder as Geary.FolderSupport.Mark;
|
||||
assert(mark != null);
|
||||
|
||||
Gee.List<Geary.EmailIdentifier> list
|
||||
= Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids);
|
||||
yield mark.mark_email_async(list, flags_to_add, flags_to_remove, cancellable);
|
||||
yield mark.mark_email_async(
|
||||
Collection.copy(ids), flags_to_add, flags_to_remove, cancellable
|
||||
);
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,8 +319,7 @@ private class Geary.ImapDB.SearchFolder : Geary.SearchFolder, Geary.FolderSuppor
|
|||
yield folder.open_async(Geary.Folder.OpenFlags.NONE, cancellable);
|
||||
open = true;
|
||||
yield remove.remove_email_async(
|
||||
Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids),
|
||||
cancellable
|
||||
Collection.copy(ids), cancellable
|
||||
);
|
||||
} finally {
|
||||
if (open) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ private class Geary.ImapEngine.CreateEmail : SendReplayOperation {
|
|||
);
|
||||
|
||||
if (results.size > 0) {
|
||||
this.created_id = Collection.get_first<Email>(results.keys).id;
|
||||
this.created_id = Collection.first(results.keys).id;
|
||||
} else {
|
||||
// Something went wrong creating/merging the message,
|
||||
// so pretend we don't know what its UID is so the
|
||||
|
|
|
|||
|
|
@ -397,9 +397,13 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject {
|
|||
cancellable
|
||||
);
|
||||
|
||||
assert(responses.size == 1);
|
||||
|
||||
return Geary.Collection.get_first(responses.values);
|
||||
var response = Collection.first(responses.values);
|
||||
if (response == null) {
|
||||
throw new ImapError.SERVER_ERROR(
|
||||
"No status response received from server"
|
||||
);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private async Gee.Map<Command, StatusResponse>
|
||||
|
|
|
|||
|
|
@ -688,7 +688,8 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
|
|||
debug("Unable to retrieve COPYUID UIDs: %s", ierr.message);
|
||||
}
|
||||
|
||||
if (!Collection.is_empty(src_uids) && !Collection.is_empty(dst_uids)) {
|
||||
if (src_uids != null && !src_uids.is_empty &&
|
||||
dst_uids != null && !dst_uids.is_empty) {
|
||||
Gee.Map<UID, UID> copyuids = new Gee.HashMap<UID, UID>();
|
||||
int ctr = 0;
|
||||
for (;;) {
|
||||
|
|
|
|||
|
|
@ -1281,7 +1281,7 @@ public class Geary.Imap.ClientSession : BaseObject {
|
|||
check_unsupported_send_command(cmd);
|
||||
|
||||
// only issue one event to the state machine for all commands; either all succeed or all fail
|
||||
MachineParams params = new MachineParams(Geary.Collection.get_first(cmds));
|
||||
MachineParams params = new MachineParams(Collection.first(cmds));
|
||||
fsm.issue(Event.SEND_CMD, null, params);
|
||||
|
||||
if (params.err != null)
|
||||
|
|
|
|||
|
|
@ -184,19 +184,11 @@ public class Geary.RFC822.MailboxAddresses :
|
|||
}
|
||||
|
||||
public bool equal_to(MailboxAddresses other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
|
||||
if (addrs.size != other.addrs.size)
|
||||
return false;
|
||||
|
||||
Gee.HashSet<RFC822.MailboxAddress> first = new Gee.HashSet<RFC822.MailboxAddress>();
|
||||
first.add_all(addrs);
|
||||
|
||||
Gee.HashSet<RFC822.MailboxAddress> second = new Gee.HashSet<RFC822.MailboxAddress>();
|
||||
second.add_all(other.addrs);
|
||||
|
||||
return Collection.are_sets_equal<RFC822.MailboxAddress>(first, second);
|
||||
return (
|
||||
this == other ||
|
||||
(this.addrs.size == other.addrs.size &&
|
||||
this.addrs.contains_all(other.addrs))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ public class Geary.Smtp.ClientService : Geary.ClientService {
|
|||
null, 1, REFERENCES, NONE, cancellable
|
||||
);
|
||||
if (list != null && !list.is_empty) {
|
||||
Email listed = Collection.get_first<Email>(list);
|
||||
Email listed = Collection.first(list);
|
||||
if (listed.message_id != null &&
|
||||
listed.message_id.equal_to(id)) {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -6,203 +6,164 @@
|
|||
|
||||
namespace Geary.Collection {
|
||||
|
||||
public delegate uint8 ByteTransformer(uint8 b);
|
||||
public delegate uint8 ByteTransformer(uint8 b);
|
||||
|
||||
public inline bool is_empty(Gee.Collection? c) {
|
||||
return c == null || c.size == 0;
|
||||
}
|
||||
|
||||
/** Returns a modifiable collection containing a single element. */
|
||||
public Gee.Collection<T> single<T>(T element) {
|
||||
Gee.Collection<T> single = new Gee.LinkedList<T>();
|
||||
single.add(element);
|
||||
return single;
|
||||
}
|
||||
|
||||
/** Returns a modifiable map containing a single entry. */
|
||||
public Gee.Map<K,V> single_map<K,V>(K key, V value) {
|
||||
Gee.Map<K,V> single = new Gee.HashMap<K,V>();
|
||||
single.set(key, value);
|
||||
return single;
|
||||
}
|
||||
|
||||
// A substitute for ArrayList<G>.wrap() for compatibility with older versions of Gee.
|
||||
public Gee.ArrayList<G> array_list_wrap<G>(G[] a, owned Gee.EqualDataFunc<G>? equal_func = null) {
|
||||
Gee.ArrayList<G> list = new Gee.ArrayList<G>((owned) equal_func);
|
||||
add_all_array<G>(list, a);
|
||||
return list;
|
||||
}
|
||||
|
||||
public Gee.ArrayList<G> to_array_list<G>(Gee.Collection<G> c) {
|
||||
Gee.ArrayList<G> list = new Gee.ArrayList<G>();
|
||||
list.add_all(c);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Gee.HashMap<Key, Value> to_hash_map<Key, Value>(
|
||||
Gee.Collection<Value> c, Gee.MapFunc<Key, Value> key_selector) {
|
||||
Gee.HashMap<Key, Value> map = new Gee.HashMap<Key, Value>();
|
||||
foreach (Value v in c)
|
||||
map.set(key_selector(v), v);
|
||||
return map;
|
||||
}
|
||||
|
||||
public void add_all_array<G>(Gee.Collection<G> c, G[] ar) {
|
||||
foreach (G g in ar)
|
||||
c.add(g);
|
||||
}
|
||||
|
||||
public G? get_first<G>(Gee.Collection<G> c) {
|
||||
Gee.Iterator<G> iter = c.iterator();
|
||||
|
||||
return iter.next() ? iter.get() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element in the Collection that passes the Predicte function.
|
||||
*
|
||||
* The Collection is walked in Iterator order.
|
||||
*/
|
||||
public G? find_first<G>(Gee.Collection<G> c, owned Gee.Predicate<G> pred) {
|
||||
Gee.Iterator<G> iter = c.iterator();
|
||||
while (iter.next()) {
|
||||
if (pred(iter.get()))
|
||||
return iter.get();
|
||||
/** Returns a modifiable collection containing a single element. */
|
||||
public Gee.Collection<T> single<T>(T element) {
|
||||
Gee.Collection<T> single = new Gee.LinkedList<T>();
|
||||
single.add(element);
|
||||
return single;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool are_sets_equal<G>(Gee.Set<G> a, Gee.Set<G> b) {
|
||||
if (a.size != b.size)
|
||||
return false;
|
||||
|
||||
foreach (G element in a) {
|
||||
if (!b.contains(element))
|
||||
return false;
|
||||
/** Returns a modifiable map containing a single entry. */
|
||||
public Gee.Map<K,V> single_map<K,V>(K key, V value) {
|
||||
Gee.Map<K,V> single = new Gee.HashMap<K,V>();
|
||||
single.set(key, value);
|
||||
return single;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from the Collection that do pass the Predicate function.
|
||||
*
|
||||
* Note that this modifies the supplied Collection.
|
||||
*/
|
||||
public Gee.Collection<G> remove_if<G>(Gee.Collection<G> c, owned Gee.Predicate<G> pred) {
|
||||
Gee.Iterator<G> iter = c.iterator();
|
||||
while (iter.next()) {
|
||||
if (pred(iter.get()))
|
||||
iter.remove();
|
||||
/** Returns a copy of the given collection in a new collection. */
|
||||
public Gee.Collection<V> copy<V>(Gee.Collection<V> original) {
|
||||
// Use a linked list, the returned value can't be accessed by
|
||||
// index anyway
|
||||
var copy = new Gee.LinkedList<V>();
|
||||
copy.add_all(original);
|
||||
return copy;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dest Map with all keys and values in src.
|
||||
*/
|
||||
public void map_set_all<K, V>(Gee.Map<K, V> dest, Gee.Map<K, V> src) {
|
||||
foreach (K key in src.keys)
|
||||
dest.set(key, src.get(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple elements with the same key in a MultiMap.
|
||||
*/
|
||||
public void multi_map_set_all<K, V>(Gee.MultiMap<K, V> dest, K key, Gee.Collection<V> values) {
|
||||
foreach (V value in values)
|
||||
dest.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all keys from the Map.
|
||||
*/
|
||||
public void map_unset_all_keys<K, V>(Gee.Map<K, V> map, Gee.Collection<K> keys) {
|
||||
foreach (K key in keys)
|
||||
map.unset(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MultiMap of value => key of the input map's key => values.
|
||||
*/
|
||||
public Gee.MultiMap<V, K> reverse_multi_map<K, V>(Gee.MultiMap<K, V> map) {
|
||||
Gee.HashMultiMap<V, K> reverse = new Gee.HashMultiMap<V, K>();
|
||||
foreach (K key in map.get_keys()) {
|
||||
foreach (V value in map.get(key))
|
||||
reverse.set(value, key);
|
||||
/** Returns the first element from a collection. */
|
||||
public G? first<G>(Gee.Collection<G> c) {
|
||||
Gee.Iterator<G> iter = c.iterator();
|
||||
return iter.next() ? iter.get() : null;
|
||||
}
|
||||
|
||||
return reverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used by a Hashable's to_hash() method.
|
||||
*/
|
||||
public inline uint int64_hash(int64 value) {
|
||||
return hash_memory(&value, sizeof(int64));
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used as hash_func for Gee collections.
|
||||
*/
|
||||
public inline uint int64_hash_func(int64? n) {
|
||||
return hash_memory((uint8 *) n, sizeof(int64));
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used as equal_func for Gee collections.
|
||||
*/
|
||||
public bool int64_equal_func(int64? a, int64? b) {
|
||||
int64 *bia = (int64 *) a;
|
||||
int64 *bib = (int64 *) b;
|
||||
|
||||
return (*bia) == (*bib);
|
||||
}
|
||||
|
||||
/**
|
||||
* A rotating-XOR hash that can be used to hash memory buffers of any size.
|
||||
*/
|
||||
public uint hash_memory(void *ptr, size_t bytes) {
|
||||
if (ptr == null || bytes == 0)
|
||||
return 0;
|
||||
|
||||
uint8 *u8 = (uint8 *) ptr;
|
||||
|
||||
// initialize hash to first byte value and then rotate-XOR from there
|
||||
uint hash = *u8;
|
||||
for (int ctr = 1; ctr < bytes; ctr++)
|
||||
hash = (hash << 4) ^ (hash >> 28) ^ (*u8++);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* A rotating-XOR hash that can be used to hash memory buffers of any size until a terminator byte
|
||||
* is found.
|
||||
*
|
||||
* A {@link ByteTransformer} may be supplied to convert bytes before they are hashed.
|
||||
*
|
||||
* Returns zero if the initial byte is the terminator.
|
||||
*/
|
||||
public uint hash_memory_stream(void *ptr, uint8 terminator, ByteTransformer? cb) {
|
||||
uint8 *u8 = (uint8 *) ptr;
|
||||
|
||||
uint hash = 0;
|
||||
for (;;) {
|
||||
uint8 b = *u8++;
|
||||
if (b == terminator)
|
||||
break;
|
||||
|
||||
if (cb != null)
|
||||
b = cb(b);
|
||||
|
||||
hash = (hash << 4) ^ (hash >> 28) ^ b;
|
||||
/**
|
||||
* Removes all elements that pass the given predicate.
|
||||
*
|
||||
* Note that this modifies the supplied Collection.
|
||||
*/
|
||||
public Gee.Collection<G> remove_if<G>(Gee.Collection<G> c,
|
||||
owned Gee.Predicate<G> pred) {
|
||||
Gee.Iterator<G> iter = c.iterator();
|
||||
while (iter.next()) {
|
||||
if (pred(iter.get())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
/**
|
||||
* Sets the dest Map with all keys and values in src.
|
||||
*/
|
||||
public void map_set_all<K, V>(Gee.Map<K, V> dest, Gee.Map<K, V> src) {
|
||||
foreach (K key in src.keys) {
|
||||
dest.set(key, src.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple elements with the same key in a MultiMap.
|
||||
*/
|
||||
public void multi_map_set_all<K, V>(Gee.MultiMap<K, V> dest, K key, Gee.Collection<V> values) {
|
||||
foreach (V value in values) {
|
||||
dest.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all keys from the Map.
|
||||
*/
|
||||
public void map_unset_all_keys<K, V>(Gee.Map<K, V> map, Gee.Collection<K> keys) {
|
||||
foreach (K key in keys) {
|
||||
map.unset(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MultiMap of value => key of the input map's key => values.
|
||||
*/
|
||||
public Gee.MultiMap<V, K> reverse_multi_map<K, V>(Gee.MultiMap<K, V> map) {
|
||||
Gee.HashMultiMap<V, K> reverse = new Gee.HashMultiMap<V, K>();
|
||||
foreach (K key in map.get_keys()) {
|
||||
foreach (V value in map.get(key)) {
|
||||
reverse.set(value, key);
|
||||
}
|
||||
}
|
||||
|
||||
return reverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used by a Hashable's to_hash() method.
|
||||
*/
|
||||
public inline uint int64_hash(int64 value) {
|
||||
return hash_memory(&value, sizeof(int64));
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used as hash_func for Gee collections.
|
||||
*/
|
||||
public inline uint int64_hash_func(int64? n) {
|
||||
return hash_memory((uint8 *) n, sizeof(int64));
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used as equal_func for Gee collections.
|
||||
*/
|
||||
public bool int64_equal_func(int64? a, int64? b) {
|
||||
int64 *bia = (int64 *) a;
|
||||
int64 *bib = (int64 *) b;
|
||||
|
||||
return (*bia) == (*bib);
|
||||
}
|
||||
|
||||
/**
|
||||
* A rotating-XOR hash that can be used to hash memory buffers of any size.
|
||||
*/
|
||||
public uint hash_memory(void *ptr, size_t bytes) {
|
||||
if (ptr == null || bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 *u8 = (uint8 *) ptr;
|
||||
|
||||
// initialize hash to first byte value and then rotate-XOR from there
|
||||
uint hash = *u8;
|
||||
for (int ctr = 1; ctr < bytes; ctr++) {
|
||||
hash = (hash << 4) ^ (hash >> 28) ^ (*u8++);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* A rotating-XOR hash that can be used to hash memory buffers of any size until a terminator byte
|
||||
* is found.
|
||||
*
|
||||
* A {@link ByteTransformer} may be supplied to convert bytes before they are hashed.
|
||||
*
|
||||
* Returns zero if the initial byte is the terminator.
|
||||
*/
|
||||
public uint hash_memory_stream(void *ptr, uint8 terminator, ByteTransformer? cb) {
|
||||
uint8 *u8 = (uint8 *) ptr;
|
||||
|
||||
uint hash = 0;
|
||||
for (;;) {
|
||||
uint8 b = *u8++;
|
||||
if (b == terminator) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cb != null) {
|
||||
b = cb(b);
|
||||
}
|
||||
|
||||
hash = (hash << 4) ^ (hash >> 28) ^ b;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,20 +126,20 @@ public class Geary.ConfigFile {
|
|||
}
|
||||
|
||||
public Gee.List<string> get_string_list(string key) {
|
||||
var strs = new Gee.ArrayList<string>();
|
||||
try {
|
||||
string[] list = this.backing.get_string_list(this.name, key);
|
||||
if (list.length > 0)
|
||||
return Geary.Collection.array_list_wrap<string>(list);
|
||||
strs.add_all_array(this.backing.get_string_list(this.name, key));
|
||||
} catch (GLib.KeyFileError err) {
|
||||
// Oh well
|
||||
}
|
||||
return new Gee.ArrayList<string>();
|
||||
return strs;
|
||||
}
|
||||
|
||||
public Gee.List<string> get_required_string_list(string key)
|
||||
throws GLib.KeyFileError {
|
||||
string[] list = this.backing.get_string_list(this.name, key);
|
||||
return Geary.Collection.array_list_wrap<string>(list);
|
||||
var strs = new Gee.ArrayList<string>();
|
||||
strs.add_all_array(this.backing.get_string_list(this.name, key));
|
||||
return strs;
|
||||
}
|
||||
|
||||
public void set_string_list(string key, Gee.List<string> value) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ namespace Geary {
|
|||
va_list args = va_list();
|
||||
G arg = g;
|
||||
|
||||
Gee.ArrayList<G> list = new Gee.ArrayList<G>();
|
||||
// Use a linked list since we will only ever be iterating over
|
||||
// it
|
||||
var list = new Gee.LinkedList<G>();
|
||||
do {
|
||||
list.add(arg);
|
||||
} while((arg = args.arg()) != null);
|
||||
|
|
@ -31,8 +33,12 @@ namespace Geary {
|
|||
/**
|
||||
* Take an array of items and return a Geary.Iterable for convenience.
|
||||
*/
|
||||
public Geary.Iterable<G> iterate_array<G>(G[] a) {
|
||||
return Geary.traverse<G>(Geary.Collection.array_list_wrap<G>(a));
|
||||
public Geary.Iterable<G> iterate_array<G>(G[] a, owned Gee.EqualDataFunc<G>? equal_func = null) {
|
||||
// Use a linked list since we will only ever be iterating over
|
||||
// it
|
||||
var list = new Gee.LinkedList<G>((owned) equal_func);
|
||||
list.add_all_array(a);
|
||||
return Geary.traverse<G>(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,12 +12,10 @@ namespace Geary.ObjectUtils {
|
|||
public Gee.List<Binding>? mirror_properties(Object source, Object dest, BindingFlags
|
||||
flags = GLib.BindingFlags.DEFAULT | GLib.BindingFlags.SYNC_CREATE) {
|
||||
// Make sets of both object's properties.
|
||||
Gee.HashSet<ParamSpec> source_properties = new Gee.HashSet<ParamSpec>();
|
||||
Collection.add_all_array<ParamSpec>(source_properties,
|
||||
source.get_class().list_properties());
|
||||
Gee.HashSet<ParamSpec> dest_properties = new Gee.HashSet<ParamSpec>();
|
||||
Collection.add_all_array<ParamSpec>(dest_properties,
|
||||
dest.get_class().list_properties());
|
||||
Gee.HashSet<ParamSpec> source_properties =
|
||||
iterate_array(source.get_class().list_properties()).to_hash_set();
|
||||
Gee.HashSet<ParamSpec> dest_properties =
|
||||
iterate_array(dest.get_class().list_properties()).to_hash_set();
|
||||
|
||||
// Remove properties from source_properties that are not in both sets.
|
||||
source_properties.retain_all(dest_properties);
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
|
|||
assert_non_null(monitor.window_lowest, "Lowest window id");
|
||||
assert_equal(e1.id, monitor.window_lowest, "Lowest window id");
|
||||
|
||||
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
|
||||
Conversation c1 = Collection.first(monitor.read_only_view);
|
||||
assert_equal(e1, c1.get_email_by_id(e1.id), "Email not present in conversation");
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
|
|||
assert_non_null(monitor.window_lowest, "Lowest window id");
|
||||
assert_equal(e2.id, monitor.window_lowest, "Lowest window id");
|
||||
|
||||
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
|
||||
Conversation c1 = Collection.first(monitor.read_only_view);
|
||||
assert_equal(e1, c1.get_email_by_id(e1.id), "Related email not present in conversation");
|
||||
assert_equal(e2, c1.get_email_by_id(e2.id), "In folder not present in conversation");
|
||||
}
|
||||
|
|
@ -329,7 +329,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
|
|||
|
||||
assert_int(1, monitor.size, "Conversation count");
|
||||
|
||||
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
|
||||
Conversation c1 = Collection.first(monitor.read_only_view);
|
||||
assert_int(2, c1.get_count(), "Conversation message count");
|
||||
assert_equal(e3, c1.get_email_by_id(e3.id),
|
||||
"Appended email not present in conversation");
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class Geary.App.ConversationSetTest : TestCase {
|
|||
assert(this.test.get_email_count() == 1);
|
||||
|
||||
assert(added.size == 1);
|
||||
assert(Geary.Collection.get_first(added).get_email_by_id(e1.id) == e1);
|
||||
assert(Collection.first(added).get_email_by_id(e1.id) == e1);
|
||||
|
||||
assert(appended.size == 0);
|
||||
assert(removed.is_empty);
|
||||
|
|
@ -165,7 +165,7 @@ class Geary.App.ConversationSetTest : TestCase {
|
|||
|
||||
assert(added.size == 1);
|
||||
|
||||
Conversation convo1 = Geary.Collection.get_first(added);
|
||||
Conversation convo1 = Collection.first(added);
|
||||
assert(convo1.get_email_by_id(e1.id) == e1);
|
||||
assert(convo1.get_email_by_id(e2.id) == e2);
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ class Geary.App.ConversationSetTest : TestCase {
|
|||
assert(added.is_empty);
|
||||
|
||||
assert(appended.size == 1);
|
||||
Conversation convo2 = Geary.Collection.get_first(appended.get_keys());
|
||||
Conversation convo2 = Collection.first(appended.get_keys());
|
||||
assert(convo2.get_email_by_id(e1.id) == e1);
|
||||
assert(convo2.get_email_by_id(e2.id) == e2);
|
||||
assert(convo2.get_email_by_id(e3.id) == e3);
|
||||
|
|
@ -234,7 +234,7 @@ class Geary.App.ConversationSetTest : TestCase {
|
|||
assert(added.is_empty);
|
||||
|
||||
assert(appended.size == 1);
|
||||
Conversation convo = Geary.Collection.get_first(appended.get_keys());
|
||||
Conversation convo = Collection.first(appended.get_keys());
|
||||
assert(convo.get_email_by_id(e1.id) == e1);
|
||||
assert(convo.get_email_by_id(e2.id) == e2);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
|
|||
|
||||
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
|
||||
assert_int(1, contacts.size, "contacts length");
|
||||
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
|
||||
Contact? created = Collection.first(contacts) as Contact;
|
||||
assert_non_null(created, "contacts contents");
|
||||
|
||||
assert_string("Test", created.real_name);
|
||||
|
|
@ -121,7 +121,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
|
|||
this.store.assert_expectations();
|
||||
|
||||
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
|
||||
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
|
||||
Contact? created = Collection.first(contacts) as Contact;
|
||||
assert_int(
|
||||
Contact.Importance.SEEN,
|
||||
created.highest_importance,
|
||||
|
|
@ -150,7 +150,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
|
|||
this.store.assert_expectations();
|
||||
|
||||
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
|
||||
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
|
||||
Contact? created = Collection.first(contacts) as Contact;
|
||||
assert_int(
|
||||
Contact.Importance.SENT_TO,
|
||||
created.highest_importance,
|
||||
|
|
@ -179,7 +179,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
|
|||
this.store.assert_expectations();
|
||||
|
||||
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
|
||||
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
|
||||
Contact? created = Collection.first(contacts) as Contact;
|
||||
assert_int(
|
||||
Contact.Importance.RECEIVED_FROM,
|
||||
created.highest_importance,
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class Geary.ContactStoreImplTest : TestCase {
|
|||
);
|
||||
assert_int(1, results.size, "results.size");
|
||||
|
||||
Contact search_hit = Collection.get_first(results);
|
||||
Contact search_hit = Collection.first(results);
|
||||
assert_string("Test@example.com", search_hit.email, "Existing email");
|
||||
assert_string("test@example.com", search_hit.normalized_email, "Existing normalized_email");
|
||||
assert_string("Test Name", search_hit.real_name, "Existing real_name");
|
||||
|
|
@ -146,7 +146,7 @@ class Geary.ContactStoreImplTest : TestCase {
|
|||
);
|
||||
assert_int(1, results.size, "results.size");
|
||||
|
||||
Contact search_hit = Collection.get_first(results);
|
||||
Contact search_hit = Collection.first(results);
|
||||
assert_string("Test@example.com", search_hit.email, "Existing email");
|
||||
assert_string("test@example.com", search_hit.normalized_email, "Existing normalized_email");
|
||||
assert_string("Test Name", search_hit.real_name, "Existing real_name");
|
||||
|
|
@ -180,7 +180,7 @@ class Geary.ContactStoreImplTest : TestCase {
|
|||
);
|
||||
assert_int(1, results.size, "results.size");
|
||||
|
||||
Contact search_hit = Collection.get_first(results);
|
||||
Contact search_hit = Collection.first(results);
|
||||
assert_string("Germán", search_hit.real_name, "Existing real_name");
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ class Geary.ContactStoreImplTest : TestCase {
|
|||
);
|
||||
assert_int(1, results.size, "results.size");
|
||||
|
||||
Contact search_hit = Collection.get_first(results);
|
||||
Contact search_hit = Collection.first(results);
|
||||
assert_string("年収1億円目指せ", search_hit.real_name, "Existing real_name");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
|
|||
add_test("from_rfc822_string_encoded", from_rfc822_string_encoded);
|
||||
add_test("from_rfc822_string_quoted", from_rfc822_string_quoted);
|
||||
add_test("to_rfc822_string", to_rfc822_string);
|
||||
add_test("equal_to", equal_to);
|
||||
}
|
||||
|
||||
public void from_rfc822_string_encoded() throws Error {
|
||||
|
|
@ -49,6 +50,38 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
|
|||
.to_rfc822_string() == "test1@example.com, test2@example.com");
|
||||
}
|
||||
|
||||
public void equal_to() throws Error {
|
||||
var mailboxes_a = new_addreses({ "test1@example.com" });
|
||||
var mailboxes_b = new_addreses({ "test1@example.com" });
|
||||
var mailboxes_c = new_addreses({ "test2@example.com" });
|
||||
|
||||
assert_true(mailboxes_a.equal_to(mailboxes_a));
|
||||
assert_true(mailboxes_a.equal_to(mailboxes_b));
|
||||
assert_false(mailboxes_a.equal_to(mailboxes_c));
|
||||
|
||||
assert_true(
|
||||
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
|
||||
new_addreses({ "test1@example.com", "test2@example.com" })
|
||||
)
|
||||
);
|
||||
assert_true(
|
||||
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
|
||||
new_addreses({ "test2@example.com", "test1@example.com" })
|
||||
)
|
||||
);
|
||||
|
||||
assert_false(
|
||||
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
|
||||
new_addreses({ "test1@example.com" })
|
||||
)
|
||||
);
|
||||
assert_false(
|
||||
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
|
||||
new_addreses({ "test1@example.com", "test3@example.com" })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private MailboxAddresses new_addreses(string[] address_strings) {
|
||||
Gee.List<MailboxAddress> addresses = new Gee.LinkedList<MailboxAddress>();
|
||||
foreach (string address in address_strings) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue