* src/engine/app/conversation-monitor/app-conversation-set.vala
(ConversationSet.remove_emails_and_check_in_folder_async): Removed in
favour of remove_all_emails_by_identifier. Move
check_conversation(s)_in_folder_async to ConversationMonitor so
all ConversationSet operations are synchronised and side-effect free.
* src/engine/app/app-conversation-monitor.vala (ConversationMonitor):
Merge check_conversation(s)_in_folder_async calls together and
simplify. Call ConversationSet.remove_all_emails_by_identifier and
manually check for and integrated evaporated conversations.
Since Conversation instances no longer listen to Account signals to keep
its email paths updated and to fire email_flags_changed, it needs the
ConversationMonitor to do this for it.
* src/engine/app/app-conversation-monitor.vala (ConversationMonitor):
Listen to the email appended/inserted/removed signals on the monitor's
Account and launch the appropriate operations when triggered.
(ConversationMonitor.remove_emails_async): Require a source folder to
be passed in so we know which folder should be removed from an email's
paths in a conversation.
(ConversationMonitor.notify_email_flags_changed): Also fire the signal
on the target conversation.
* src/engine/app/conversation-monitor/app-remove-operation.vala
(RemoveOperation): Pass a source folder to the operation so it can be
forwarded on to ConversationMonitor.remove_emails_async and used for
both removing an email both from the base folder, but also from other
folders.
* src/engine/app/conversation-monitor/app-conversation-set.vala
(ConversationSet.add_email): Check to see if the email already exists
in the conversation, and if so merge its paths rather than just
returning.
(ConversationSet.merge_conversations_async): Simplify removing
conversations to be merged rather than manually handling it, meaning
email will be unconditionally removed rather than potentially being
conditionally removed via remove_all_emails_by_identifier.
(ConversationSet.remove_email_by_identifier): Simply update an email's
paths in the conversation if it has more than one, rather than removing
it.
* src/engine/app/conversation-monitor/app-conversation-set.vala
(ConversationSet.add_all_emails_async): Replace monitor arg with a
multiset of email paths, update call site to do the path lookup on the
caller's side instead. Add unit tests.
(ConversationSet.merge_conversations_async): Remove monitor arg with a
multiset of email paths, get paths for emails to be merged from the
conversations themselves, since they should be up to date.
(Conversation.remove_all_emails_by_identifier): Add unit tests.
* src/engine/app/app-conversation.vala (Conversation): We currently can't
easily unit test Conversation instances since the ctor requires a
ConversationMonitor argument, which is complicated. Replace the monitor
arg with a base folder (which is what it actually needs the monitor for
anyway) and remove the signals in favour of adding and modifying the
API to allow folder paths to be explicitly updated. Remove
clear_owner() method and dtor now it's useless. Update call sites. Add
unit tests to make sure the add/remove and multi-path related code
still works at least.
This allows us to compile the engine tests against the internal VAPI, so
we can unit test internal classes.
* CMakeLists.txt: Add top-level targets test-engine-run and
test-client-run that execute the respective test binaries. Make
the tests target depend on them and make them depend on their
binaries.
* Makefile.in: Add test-client and test-engin targets for convenience.
* src/CMakeLists.txt: Make the right invocation of valac to generate a
correct geary-engine-internal.vapi. Make gsettings schema generation
depend on geary-client so it exists for test-client if the main binary
hasn't been built.
* test/CMakeLists.txt: Split everything up into to builds, one for
test-engine and the other for test-client. Use geary-engine-internal
when building test-engine for access to internal classes and members.
* test/engine/util-idle-manager-test.vala,
test/engine/util-timeout-manager-test.vala: Use Glib MainContext rather
than the GTK main loop for pumping events so the test cases compile
without GTK.
* test/test-engine.vala, test/test-client.vala: New main source file for
test binaries based on old main.vala.
* src/client/meson.build,
src/engine/meson.build,
src/sqlite3-unicodesn/meson.build: Build static libraries so they can
be found when installed.
* src/meson.build: Include GResources in the binary now we are compiling
static libraries, so the resources can be found when compiled.
This attempts to solve bug
[#714921](https://bugzilla.gnome.org/show_bug.cgi?id=714921).
They are available as two buttons on the format bar, next to font
options. The icons I used are taken from a free icons site just for demo
purposes and should be replaced by new icons. Also I did not include
hotkeys mainly because I could not come up with a good one, also they
are pretty uncommon I think.
Also added new icons to icons/CMakeLists.txt
* desktop/meson.build: Make sure the schema is re-compiled with the
source XML changes.
* meson.build: Make compiling the schema mandatory, since both running
the client locally and unit tests require it. Fix path to compiled
schema so the client can find it.
Since libmessaging-menu has a either a broken pkg_config file or a dumb
VAPI name, we need to detect the library and the VAPI in two steps, then
add them both as dependencies.
Some remarks:
* Note that Meson adds a hard dependency on Python 3.
* All dependencies and defines are now listed together.
* Some build files were put in their respective subdirectories, e.g. the Geary
engine library will be built from the Meson file in `src/engine`.
* `--fatal-warnings` is no longer an explicit flag, as Meson provides
`-Dwerror=true` for this.
* An explicit resource file needs to be used. The issue to support this from
Meson itself can be found at https://github.com/mesonbuild/meson/issues/706 .
* The `gnome.yelp()` function parses a LINGUAS file so we no longer need to keep
track of all languages in our build system.
* There are no Debian scripts defined in the meson.build files to keep them
clean, but they can be kept as separate scripts in `build-aux`.
* Left out the `dist` target as there is now `ninja dist`
* `geary-docs` is disabled by default, as valadoc-0.38.3 returns errors.
https://bugzilla.gnome.org/show_bug.cgi?id=777044
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage.load_avatar): We are very occasionally getting
crashes calling Gtk.Image.get_pixel_size() due to the image is null -
maybe a race? This obviates the problem by hard-coding the size instead
of dynamically getting it.
This ensures that only a single request for a resource is made at once,
to work around crashes in SoupCache when multiple requests for the same
resource.
Hopefully fixes Bug 778720 once and for all.
* src/client/conversation-viewer/conversation-list-box.vala
(ConversationListBox): Add new AvatarStore class and internal
AvatarLoader class to manage avatar loads for the
conversation. Construct an instance of the store in the
constructor and pass it to ConversationEmail::start_loading so its
messages can use it for loading their sender avatars. Update call
sites.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::load_avatar): Add AvatarLoader param for loading
avatars, use that rather than making the Soup calls directly. Update
call sites.
* src/engine/imap-engine/imap-engine-email-prefetcher.vala
(EmailPrefetcher): Connect to email_locally_{appended,inserted} rather
than email_{appended,inserted}.
* src/engine/imap-engine/replay-ops/imap-engine-list-email-by-id.vala
(AbstractListEmail): Throw an error if asking for a specific message,
asking for it to be included in the results, but the message not
actually appearing in the results.
Previously when appending new messages to a local folder we were ignoring
messages in the same folder with the same internal date and RFC822
size. This changes the ImapDB::Folder's behaviour in this case to use the
same message object but re-associate it with the folder, meaning on
re-sync, we don't find a hole in the message sequence again and go
searching for it over and over.
* src/engine/imap-db/imap-db-folder.vala
(Folder::do_search_for_duplicates): Break out UID check to simplify
call semantics and fast-path finding obvious duplicates. Look for
duplicate messages, but simply return them and let caller determine
policy.
(Folder::do_create_or_merge_email): Do UID duplicate check up front
before searching for dupe messages, if duplicate message is found,
append to the folder anyway and merge. Rework to be explicit about
param prerequisites up front and throw and error rather than asserting
if not met. Unify common calls in both create and merge cases.
* src/engine/imap-engine/imap-engine-account-synchronizer.vala
(AccountSynchronizer::sync_folder_async): For the last-ditch sync,
ensure we list newest-to-oldest and for int.MAX count to make sure the
folder is fully expanded.
* src/engine/imap-engine/replay-ops/imap-engine-abstract-list-email.vala
(AbstractListEmail): Update doc comments,
(AbstractListEmail::expand_vector_async): Document, re-work to simplify
the implementation and make it a bit more obvious how and why the lower
and higher bounds are calculated, and make sure they conform to the API
docs and use by existing call sites.
* src/engine/imap/api/imap-folder.vala (Account::uid_to_position_async):
Make caller's life easier by throwing an error if the results from the
server are obviously bogus and never return null.
* src/engine/imap-engine/imap-engine-account-synchronizer.vala
(AccountSynchronizer::process_folder_async): Since the folder might
not have opened yet, the counts may be wrong, so don't rely on them.