Commit 3af6837e authored by Charles Lindsay's avatar Charles Lindsay

Add Geary.iterate to replace Collection.SingleItem

This adds a way to turn lists of items into a Geary.Iterable, which then
allows you to dump results into any kind of container.  This removes the
Collection.SingleItem class, which was no longer useful.

Closes: bgo #723208
parent cce04b81
......@@ -337,7 +337,6 @@ src/engine/util/util-numeric.vala
src/engine/util/util-object.vala
src/engine/util/util-reference-semantics.vala
src/engine/util/util-scheduler.vala
src/engine/util/util-single-item.vala
src/engine/util/util-stream.vala
src/engine/util/util-string.vala
src/engine/util/util-synchronization.vala
......
......@@ -284,7 +284,6 @@ engine/util/util-numeric.vala
engine/util/util-object.vala
engine/util/util-reference-semantics.vala
engine/util/util-scheduler.vala
engine/util/util-single-item.vala
engine/util/util-stream.vala
engine/util/util-string.vala
engine/util/util-synchronization.vala
......
......@@ -170,7 +170,7 @@ public class ConversationListView : Gtk.TreeView {
if (GearyApplication.instance.controller.get_selected_conversations().contains(conversation))
to_mark = GearyApplication.instance.controller.get_selected_conversations();
else
to_mark = new Geary.Collection.SingleItem<Geary.App.Conversation>(conversation);
to_mark = Geary.iterate<Geary.App.Conversation>(conversation).to_array_list();
if (read_clicked) {
// Read/unread.
......
......@@ -1216,8 +1216,7 @@ public class ConversationViewer : Gtk.Box {
if (message != null && !message.load_remote_images().is_certain()) {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.LOAD_REMOTE_IMAGES);
mark_messages(new Geary.Collection.SingleItem<Geary.EmailIdentifier>(
message.id), flags, null);
mark_messages(Geary.iterate<Geary.EmailIdentifier>(message.id).to_array_list(), flags, null);
}
}
}
......@@ -1431,14 +1430,14 @@ public class ConversationViewer : Gtk.Box {
private void on_mark_read_message(Geary.Email message) {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.UNREAD);
mark_messages(new Geary.Collection.SingleItem<Geary.EmailIdentifier>(message.id), null, flags);
mark_messages(Geary.iterate<Geary.EmailIdentifier>(message.id).to_array_list(), null, flags);
mark_manual_read(message.id);
}
private void on_mark_unread_message(Geary.Email message) {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.UNREAD);
mark_messages(new Geary.Collection.SingleItem<Geary.EmailIdentifier>(message.id), flags, null);
mark_messages(Geary.iterate<Geary.EmailIdentifier>(message.id).to_array_list(), flags, null);
mark_manual_read(message.id);
}
......@@ -1488,13 +1487,13 @@ public class ConversationViewer : Gtk.Box {
private void flag_message(Geary.Email email) {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.FLAGGED);
mark_messages(new Geary.Collection.SingleItem<Geary.EmailIdentifier>(email.id), flags, null);
mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(), flags, null);
}
private void unflag_message(Geary.Email email) {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.FLAGGED);
mark_messages(new Geary.Collection.SingleItem<Geary.EmailIdentifier>(email.id), null, flags);
mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(), null, flags);
}
private void show_attachment_menu(Geary.Email email, Geary.Attachment attachment) {
......
......@@ -44,7 +44,7 @@ public class Geary.NamedFlags : BaseObject, Gee.Hashable<Geary.NamedFlags> {
public virtual void add(NamedFlag flag) {
if (!list.contains(flag)) {
list.add(flag);
notify_added(new Collection.SingleItem<NamedFlag>(flag));
notify_added(Geary.iterate<NamedFlag>(flag).to_array_list());
}
}
......@@ -60,7 +60,7 @@ public class Geary.NamedFlags : BaseObject, Gee.Hashable<Geary.NamedFlags> {
public virtual bool remove(NamedFlag flag) {
bool removed = list.remove(flag);
if (removed)
notify_removed(new Collection.SingleItem<NamedFlag>(flag));
notify_removed(Geary.iterate<NamedFlag>(flag).to_array_list());
return removed;
}
......
......@@ -80,7 +80,7 @@ public class Geary.App.EmailStore : BaseObject {
Cancellable? cancellable = null) throws Error {
FetchOperation op = new Geary.App.FetchOperation(required_fields, flags);
yield do_folder_operation_async(op,
new Geary.Collection.SingleItem<Geary.EmailIdentifier>(email_id), cancellable);
Geary.iterate<Geary.EmailIdentifier>(email_id).to_array_list(), cancellable);
if (op.result == null)
throw new EngineError.NOT_FOUND("Couldn't fetch email ID %s", email_id.to_string());
......
......@@ -25,6 +25,6 @@ private class Geary.App.FetchOperation : Geary.App.AsyncFolderOperation {
result = yield folder.fetch_email_async(
id, required_fields, flags, cancellable);
return new Geary.Collection.SingleItem<Geary.EmailIdentifier>(id);
return Geary.iterate<Geary.EmailIdentifier>(id).to_array_list();
}
}
......@@ -876,8 +876,8 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
}
// Check to see if message is unread (this only affects non-marked emails.)
if (do_get_unread_count_for_ids(cx, new Geary.Collection.SingleItem
<ImapDB.EmailIdentifier>(id), cancellable) > 0) {
if (do_get_unread_count_for_ids(cx,
Geary.iterate<ImapDB.EmailIdentifier>(id).to_array_list(), cancellable) > 0) {
do_add_to_unread_count(cx, -1, cancellable);
was_unread = true;
}
......
......@@ -209,7 +209,8 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
}
private GenericFolder build_folder(ImapDB.Folder local_folder) {
return Geary.Collection.get_first(build_folders(new Collection.SingleItem<ImapDB.Folder>(local_folder)));
return Geary.Collection.get_first(build_folders(
Geary.iterate<ImapDB.Folder>(local_folder).to_array_list()));
}
private Gee.Collection<GenericFolder> build_folders(Gee.Collection<ImapDB.Folder> local_folders) {
......
......@@ -936,7 +936,8 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
}
// Notify queued replay operations that the email has been removed (by EmailIdentifier)
replay_queue.notify_remote_removed_ids(new Collection.SingleItem<ImapDB.EmailIdentifier>(owned_id));
replay_queue.notify_remote_removed_ids(
Geary.iterate<ImapDB.EmailIdentifier>(owned_id).to_array_list());
} else {
debug("%s do_replay_removed_message: remote_position=%d unknown in local store "
+ "(reported_remote_count=%d local_position=%d local_count=%d)",
......@@ -964,7 +965,7 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
// notify of change
if (!marked && owned_id != null)
notify_email_removed(new Collection.SingleItem<Geary.EmailIdentifier>(owned_id));
notify_email_removed(Geary.iterate<Geary.EmailIdentifier>(owned_id).to_array_list());
if (!marked)
notify_email_count_changed(reported_remote_count, CountChangeReason.REMOVED);
......
......@@ -65,7 +65,7 @@ private class Geary.ImapEngine.CreateEmail : Geary.ImapEngine.SendReplayOperatio
// TODO: need to prevent gaps that may occur here
Geary.Email created = new Geary.Email(created_id);
Gee.Map<Geary.Email, bool> results = yield engine.local_folder.create_or_merge_email_async(
new Collection.SingleItem<Geary.Email>(created), cancellable);
Geary.iterate<Geary.Email>(created).to_array_list(), cancellable);
if (results.size > 0)
created_id = Collection.get_first<Geary.Email>(results.keys).id;
else
......
......@@ -102,12 +102,13 @@ private class Geary.ImapEngine.FetchEmail : Geary.ImapEngine.SendReplayOperation
assert(email != null);
Gee.Map<Geary.Email, bool> created_or_merged =
yield engine.local_folder.create_or_merge_email_async(new Collection.SingleItem<Geary.Email>(email),
cancellable);
yield engine.local_folder.create_or_merge_email_async(
Geary.iterate<Geary.Email>(email).to_array_list(), cancellable);
// true means created
if (created_or_merged.get(email)) {
Gee.Collection<Geary.EmailIdentifier> ids = new Collection.SingleItem<Geary.EmailIdentifier>(email.id);
Gee.Collection<Geary.EmailIdentifier> ids
= Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list();
engine.notify_email_inserted(ids);
engine.notify_email_locally_inserted(ids);
}
......
......@@ -350,7 +350,7 @@ private class Geary.Imap.Account : BaseObject {
Gee.List<MailboxInformation>? list_results, Gee.List<StatusData>? status_results,
Cancellable? cancellable) throws Error {
Gee.Map<Command, StatusResponse> responses = yield send_multiple_async(
new Geary.Collection.SingleItem<Command>(cmd), list_results, status_results,
Geary.iterate<Command>(cmd).to_array_list(), list_results, status_results,
cancellable);
assert(responses.size == 1);
......
......@@ -337,7 +337,7 @@ private class Geary.Imap.Folder : BaseObject {
FetchCommand cmd = new FetchCommand.data_type(msg_set, FetchDataSpecifier.UID);
Gee.HashMap<SequenceNumber, FetchedData>? fetched;
yield exec_commands_async(new Collection.SingleItem<Command>(cmd), out fetched, null,
yield exec_commands_async(Geary.iterate<Command>(cmd).to_array_list(), out fetched, null,
cancellable);
if (fetched == null || fetched.size == 0)
return null;
......@@ -550,9 +550,9 @@ private class Geary.Imap.Folder : BaseObject {
CopyCommand cmd = new CopyCommand(msg_set,
new MailboxSpecifier.from_folder_path(destination, null));
Gee.Collection<Command> cmds = new Collection.SingleItem<Command>(cmd);
yield exec_commands_async(cmds, null, null, cancellable);
yield exec_commands_async(Geary.iterate<Command>(cmd).to_array_list(), null,
null, cancellable);
}
// TODO: Support MOVE extension
......@@ -888,7 +888,7 @@ private class Geary.Imap.Folder : BaseObject {
Imap.EmailFlags imap_flags = Imap.EmailFlags.from_api_email_flags(flags);
msg_flags = imap_flags.message_flags;
} else {
msg_flags = new MessageFlags(new Geary.Collection.SingleItem<MessageFlag>(MessageFlag.SEEN));
msg_flags = new MessageFlags(Geary.iterate<MessageFlag>(MessageFlag.SEEN).to_array_list());
}
InternalDate? internaldate = null;
......@@ -899,7 +899,7 @@ private class Geary.Imap.Folder : BaseObject {
msg_flags, internaldate, message.get_network_buffer(false));
Gee.Map<Command, StatusResponse> responses = yield exec_commands_async(
new Collection.SingleItem<AppendCommand>(cmd), null, null, null);
Geary.iterate<AppendCommand>(cmd).to_array_list(), null, null, null);
// Grab the response and parse out the UID, if available.
StatusResponse response = responses.get(cmd);
......
......@@ -11,6 +11,22 @@ namespace Geary {
public Geary.Iterable<G> traverse<G>(Gee.Iterable<G> i) {
return new Geary.Iterable<G>(i.iterator());
}
/**
* Take some non-null items (all must be of type G) and return a
* Geary.Iterable for convenience.
*/
public Geary.Iterable<G> iterate<G>(G g, ...) {
va_list args = va_list();
G arg = g;
Gee.ArrayList<G> list = new Gee.ArrayList<G>();
do {
list.add(arg);
} while((arg = args.arg()) != null);
return Geary.traverse<G>(list);
}
}
/**
......
/* Copyright 2012-2013 Yorba Foundation
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* SingleItem is a simple way of creating a one-item read-only Gee.Collection.
*/
public class Geary.Collection.SingleItem<G> : Gee.AbstractCollection<G> {
private class IteratorImpl<G> : BaseObject, Gee.Traversable<G>, Gee.Iterator<G> {
public bool read_only { get { return true; } }
public bool valid { get { return !done; } }
private G item;
private bool done = false;
public IteratorImpl(G item) {
this.item = item;
}
public new G? get() {
return item;
}
public bool has_next() {
return !done;
}
public bool next() {
if (done)
return false;
done = true;
return true;
}
public void remove() {
warn_readonly();
}
public new bool @foreach(Gee.ForallFunc<G> f) {
return f(item);
}
}
public override bool read_only { get { return true; } }
public G item { get; private set; }
public override int size { get { return 1; } }
private Gee.EqualDataFunc equal_func;
public SingleItem(G item, owned Gee.EqualDataFunc? equal_func = null) {
this.item = item;
if (equal_func != null)
this.equal_func = (owned) equal_func;
else {
this.equal_func = Gee.Functions.get_equal_func_for(typeof(G));
}
}
private static void warn_readonly() {
message("Geary.Collection.SingleItem is read-only");
}
public override bool add(G element) {
return false;
}
public override void clear() {
warn_readonly();
}
public override bool contains(G element) {
return equal_func(item, element);
}
public override Gee.Iterator<G> iterator() {
return new IteratorImpl<G>(item);
}
public override bool remove(G element) {
warn_readonly();
return false;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment