When an EmailCommand is undone, select the folder, conversation and if
relevant scroll to the email in question so as to provide better
context.
This isn't 100% bulletproof, but is about 80% of the way there. The
remainer requires some major Engine rework to decouple local and remote
actions.
Ensure accounts being removed are de-selected and the cursor moved off
of their folders in the folder list so that as they are removed, their
folders are not selected in quick succession. Don't redudantly close
inboxes in Application.Controller::close_async, and merge the two parts
to the handling of account closing.
Move more main-window specific code out of Application.Controller,
allowing consolidation of all folder selection code in the one place
and allowing it to be revamped so as to support robust programmatic
selection of folders.
Before Application.Controller executes an action, ensure it's not the
same action as was execued just before. This stops e.g. issues if
someone holds down Delete.
Fixes#578
Add context properties to EmailCommand so that MainWindow can (once
supported) re-select folder and modified conversations when undoing a
command.
Convert it into a full-blown abstract class so that subclasses don't all
need to re-implement it, and provide a default implementation of the
folder and email removal methods. Update command methods on
Application.Controller to get the required context objects.
This allows a single widget to get constructed to handle email actions,
rather than every single ConversationEmail having to do so, and thus
related signals can also be moved to and emitted from
ConversationListBox, so that MainWindow only has to hook up to a single
object's signals for a conversation, not every email in the
conversation.
Ensure shift button is assumed to be up on both focus in and focus out,
so when e.g. invoking the inspector the button is assumed to be
released. Remove the signal in preference for using notifiy when needed,
and ensure main toolbar state is updated on focus changes as well.
Create new Application.AttachmentManager class and move code for saving
attachments there from both Application.Controller and MainWindow since
aside from needing the latter for dialogs it is independent of both.
Create new Components.AttachmentPane widget for diplaying attachents
for an email in the ConversationViewer.
Update ConversationEmail and ConversationMessage to use these two new
classes directly, rather than implementing save management itself or
requiring the MainWindow to wire up signals on these classes.
Use the same implementation for moving conversations and messages so
that marking messages is notified in the same way as marking
conversations. Athough in the case of the latter, only a subset of the
messages in a conversation may get marked, it makes the UI notification
UI present more consistently.
If some event like another email client causes folders or email to be
removed, the controller's command stack needs to be trimmed to remove
any commands that refer to these.
Introduce a custom CommandStack subclass that can update the stack and
use that as the account's stack, call it as needed when folders become
unavailable or email is permanently deleted.
Give each account its own command stack, and use that when executing
commands for an account, since people are unlikely to select a different
account and expect commands for the previous account to work.
This moves a large nummber of the main window's concerns to the main
window, decouping a large number of dependencies from the controller to
the main window, and enables managing action and UI state per-window.