geary/src/client/application/geary-controller.vala

2982 lines
129 KiB
Vala
Raw Normal View History

Reenable displaying sub-messages. Geary currently displays RFC 822 attachments inline, below the email's primary message body, using the same HTML chrome for the headers and email body as for the primary body. Taking the same approach but using GTK+ widgets meant splitting ConversationMessage up into a ConversationEmail class that manages the UI for displaying an email in its entirety, and a ConversationMessage to manage the only header widgets and webview for displaying an individual RFC 822 message, usable for both the primary body and any sub-messages. Thus, this is a big change. One behavioural change is that each sub-message with remote images now requires individual approval, rather than being dependant on the containing message's sender and/or approval. This prevents some attacks e.g. a trusted sender forwarding a spam/malware message, but does not prevent it if the message is forwarded inline, obviosuly. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): New class for managing the UI for an overall email message. This replaces the old ConversationMessage and contains much of it's code and widgets - anything from that class which does not directly support displaying headers or a message body. * src/client/conversation-viewer/conversation-message.vala: (ConversationMessage): Same class as before, but now with its scope narrowed to only display message headers and body. The draft infobar remains here rather than being put ConversationEmail where it belongs since it's bit of a pain to insert in the right place and doesn't really hurt. (::email): Moved this property and any code that depends on it to ConversationEmail. (::always_load_remote_images): New property passed in via the ctor, allowing one dependency on the old ::email property to be removed. (::inlined_content_ids): Moved to ConversationEmail, since that is the class that keeps track of attachments to display. Add the signal attachment_displayed_inline to allow ConversationEmail to be notified of inlined attachments instead. (::flag_remote_images, ::remember_remote_images): New signals to notify ConversationEmail that the user has flagged this message or the message's sender for loading remote images. This is passed through since in the former's case we may need to set flags on the email itself, the latter because it is one less use of the contact_store property, which should be removed from this class at some point. * src/client/conversation-viewer/conversation-viewer.vala: Chase API changes from the above. In general, replace use of the term "message" with "email" since this class is now mostly dealing with ConversationEmail instances, rather than ConversationMessage instances. (ConversationViewer::check_mark_read): Only consider the ConversationEmail's primary message body when checking for visibility rather than that and any submessages to keep things simple. (ConversationViewer::show_message, ::hide_message): Renamed to expand_email/collapse_email respectively since we don't ever actually hide it. Carry that change on to same methods on ConversationEmail. * src/engine/rfc822/rfc822-message.vala (Geary.RFC822.Message): Add get_primary_originator(), almost vermatim from Geary.Email, to support determining the sender for remembering remote message loading for senders of sub-emails. * src/client/components/main-window.vala (MainWindow::set_styling): Fix background transition for collapsed emails. * src/client/application/geary-controller.vala: Chase API name changes. * src/CMakeLists.txt: Include new ConversationEmail source file. * ui/conversation-email.ui: New UI for ConversationEmail, move the email action box, attachments box amd sub-messages box here from conversation-message.ui. * ui/CMakeLists.txt: Include new UI in compiled resources. * po/POTFILES.in: Add new UI for transation.
2016-04-19 16:52:34 +10:00
/*
* Copyright 2016 Software Freedom Conservancy Inc.
* Copyright 2016 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
Reenable displaying sub-messages. Geary currently displays RFC 822 attachments inline, below the email's primary message body, using the same HTML chrome for the headers and email body as for the primary body. Taking the same approach but using GTK+ widgets meant splitting ConversationMessage up into a ConversationEmail class that manages the UI for displaying an email in its entirety, and a ConversationMessage to manage the only header widgets and webview for displaying an individual RFC 822 message, usable for both the primary body and any sub-messages. Thus, this is a big change. One behavioural change is that each sub-message with remote images now requires individual approval, rather than being dependant on the containing message's sender and/or approval. This prevents some attacks e.g. a trusted sender forwarding a spam/malware message, but does not prevent it if the message is forwarded inline, obviosuly. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): New class for managing the UI for an overall email message. This replaces the old ConversationMessage and contains much of it's code and widgets - anything from that class which does not directly support displaying headers or a message body. * src/client/conversation-viewer/conversation-message.vala: (ConversationMessage): Same class as before, but now with its scope narrowed to only display message headers and body. The draft infobar remains here rather than being put ConversationEmail where it belongs since it's bit of a pain to insert in the right place and doesn't really hurt. (::email): Moved this property and any code that depends on it to ConversationEmail. (::always_load_remote_images): New property passed in via the ctor, allowing one dependency on the old ::email property to be removed. (::inlined_content_ids): Moved to ConversationEmail, since that is the class that keeps track of attachments to display. Add the signal attachment_displayed_inline to allow ConversationEmail to be notified of inlined attachments instead. (::flag_remote_images, ::remember_remote_images): New signals to notify ConversationEmail that the user has flagged this message or the message's sender for loading remote images. This is passed through since in the former's case we may need to set flags on the email itself, the latter because it is one less use of the contact_store property, which should be removed from this class at some point. * src/client/conversation-viewer/conversation-viewer.vala: Chase API changes from the above. In general, replace use of the term "message" with "email" since this class is now mostly dealing with ConversationEmail instances, rather than ConversationMessage instances. (ConversationViewer::check_mark_read): Only consider the ConversationEmail's primary message body when checking for visibility rather than that and any submessages to keep things simple. (ConversationViewer::show_message, ::hide_message): Renamed to expand_email/collapse_email respectively since we don't ever actually hide it. Carry that change on to same methods on ConversationEmail. * src/engine/rfc822/rfc822-message.vala (Geary.RFC822.Message): Add get_primary_originator(), almost vermatim from Geary.Email, to support determining the sender for remembering remote message loading for senders of sub-emails. * src/client/components/main-window.vala (MainWindow::set_styling): Fix background transition for collapsed emails. * src/client/application/geary-controller.vala: Chase API name changes. * src/CMakeLists.txt: Include new ConversationEmail source file. * ui/conversation-email.ui: New UI for ConversationEmail, move the email action box, attachments box amd sub-messages box here from conversation-message.ui. * ui/CMakeLists.txt: Include new UI in compiled resources. * po/POTFILES.in: Add new UI for transation.
2016-04-19 16:52:34 +10:00
* (version 2.1 or later). See the COPYING file in this distribution.
*/
// Required because Gcr's VAPI is behind-the-times
// TODO: When bindings available, use async variants of these calls
extern const string GCR_PURPOSE_SERVER_AUTH;
extern bool gcr_trust_add_pinned_certificate(Gcr.Certificate cert, string purpose, string peer,
Cancellable? cancellable) throws Error;
extern bool gcr_trust_is_certificate_pinned(Gcr.Certificate cert, string purpose, string peer,
Cancellable? cancellable) throws Error;
extern bool gcr_trust_remove_pinned_certificate(Gcr.Certificate cert, string purpose, string peer,
Cancellable? cancellable) throws Error;
/**
* Primary controller for a Geary application instance.
*/
2013-07-23 15:43:56 -07:00
public class GearyController : Geary.BaseObject {
// Named actions.
//
// NOTE: Some actions with accelerators need to also be added to ui/accelerators.ui
public const string ACTION_NEW_MESSAGE = "GearyNewMessage";
2012-01-17 18:42:20 -08:00
public const string ACTION_REPLY_TO_MESSAGE = "GearyReplyToMessage";
public const string ACTION_REPLY_ALL_MESSAGE = "GearyReplyAllMessage";
2012-01-24 18:24:32 -08:00
public const string ACTION_FORWARD_MESSAGE = "GearyForwardMessage";
public const string ACTION_ARCHIVE_MESSAGE = "GearyArchiveMessage";
public const string ACTION_TRASH_MESSAGE = "GearyTrashMessage";
2011-12-15 16:16:27 -08:00
public const string ACTION_DELETE_MESSAGE = "GearyDeleteMessage";
public const string ACTION_EMPTY_SPAM = "GearyEmptySpam";
public const string ACTION_EMPTY_TRASH = "GearyEmptyTrash";
public const string ACTION_UNDO = "GearyUndo";
public const string ACTION_FIND_IN_CONVERSATION = "GearyFindInConversation";
public const string ACTION_ZOOM_IN = "GearyZoomIn";
public const string ACTION_ZOOM_OUT = "GearyZoomOut";
public const string ACTION_ZOOM_NORMAL = "GearyZoomNormal";
public const string ACTION_MARK_AS_MENU = "GearyMarkAsMenuButton";
public const string ACTION_MARK_AS_READ = "GearyMarkAsRead";
public const string ACTION_MARK_AS_UNREAD = "GearyMarkAsUnread";
public const string ACTION_MARK_AS_STARRED = "GearyMarkAsStarred";
public const string ACTION_MARK_AS_UNSTARRED = "GearyMarkAsUnStarred";
2013-02-21 14:57:59 -08:00
public const string ACTION_MARK_AS_SPAM = "GearyMarkAsSpam";
public const string ACTION_COPY_MENU = "GearyCopyMenuButton";
public const string ACTION_MOVE_MENU = "GearyMoveMenuButton";
public const string ACTION_SEARCH = "GearySearch";
public const string ACTION_CONVERSATION_LIST = "GearyConversationList";
public const string ACTION_TOGGLE_SEARCH = "GearyToggleSearch";
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
public const string ACTION_TOGGLE_FIND = "GearyToggleFind";
2013-07-23 15:43:56 -07:00
public const string PROP_CURRENT_CONVERSATION ="current-conversations";
public const int MIN_CONVERSATION_COUNT = 50;
private const string DELETE_MESSAGE_LABEL = _("Delete conversation");
private const string DELETE_MESSAGE_TOOLTIP_SINGLE = _("Delete conversation (Shift+Delete)");
private const string DELETE_MESSAGE_TOOLTIP_MULTIPLE = _("Delete conversations (Shift+Delete)");
private const string DELETE_MESSAGE_ICON_NAME = "edit-delete-symbolic";
// This refers to the action ("move email to the trash"), not the Trash folder itself
private const string TRASH_MESSAGE_TOOLTIP_SINGLE = _("Move conversation to Trash (Delete, Backspace)");
private const string TRASH_MESSAGE_TOOLTIP_MULTIPLE = _("Move conversations to Trash (Delete, Backspace)");
private const string TRASH_MESSAGE_ICON_NAME = "user-trash-symbolic";
// This refers to the action ("archive an email"), not the Archive folder itself
private const string ARCHIVE_MESSAGE_LABEL = _("_Archive");
private const string ARCHIVE_MESSAGE_TOOLTIP_SINGLE = _("Archive conversation (A)");
private const string ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE = _("Archive conversations (A)");
private const string ARCHIVE_MESSAGE_ICON_NAME = "mail-archive-symbolic";
private const string MARK_AS_SPAM_LABEL = _("Mark as S_pam");
private const string MARK_AS_NOT_SPAM_LABEL = _("Mark as not S_pam");
2013-02-21 14:57:59 -08:00
2013-02-22 17:54:05 -08:00
private const string MARK_MESSAGE_MENU_TOOLTIP_SINGLE = _("Mark conversation");
private const string MARK_MESSAGE_MENU_TOOLTIP_MULTIPLE = _("Mark conversations");
private const string LABEL_MESSAGE_TOOLTIP_SINGLE = _("Add label to conversation");
private const string LABEL_MESSAGE_TOOLTIP_MULTIPLE = _("Add label to conversations");
private const string MOVE_MESSAGE_TOOLTIP_SINGLE = _("Move conversation");
private const string MOVE_MESSAGE_TOOLTIP_MULTIPLE = _("Move conversations");
private const int SELECT_FOLDER_TIMEOUT_USEC = 100 * 1000;
2013-07-08 14:22:23 -07:00
private const string PROP_ATTEMPT_OPEN_ACCOUNT = "attempt-open-account";
public weak GearyApplication application { get; private set; } // circular ref
public MainWindow main_window { get; private set; }
2013-07-23 15:43:56 -07:00
public Geary.App.ConversationMonitor? current_conversations { get; private set; default = null; }
public AutostartManager? autostart_manager { get; private set; default = null; }
public LoginDialog? login_dialog { get; private set; default = null; }
public Soup.Session? avatar_session { get; private set; default = null; }
private Soup.Cache? avatar_cache = null;
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
private Geary.Account? current_account = null;
private Gee.HashMap<Geary.Account, Geary.App.EmailStore> email_stores
= new Gee.HashMap<Geary.Account, Geary.App.EmailStore>();
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
private Gee.HashMap<Geary.Account, Geary.Folder> inboxes
= new Gee.HashMap<Geary.Account, Geary.Folder>();
private Geary.Folder? current_folder = null;
private Cancellable cancellable_folder = new Cancellable();
private Cancellable cancellable_search = new Cancellable();
2013-07-08 14:22:23 -07:00
private Cancellable cancellable_open_account = new Cancellable();
private Cancellable cancellable_context_dependent_buttons = new Cancellable();
private Gee.HashMap<Geary.Account, Cancellable> inbox_cancellables
= new Gee.HashMap<Geary.Account, Cancellable>();
private Gee.Set<Geary.App.Conversation> selected_conversations = new Gee.HashSet<Geary.App.Conversation>();
private Geary.App.Conversation? last_deleted_conversation = null;
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
private Gee.LinkedList<ComposerWidget> composer_widgets = new Gee.LinkedList<ComposerWidget>();
private File? last_save_directory = null;
private NewMessagesMonitor? new_messages_monitor = null;
private NewMessagesIndicator? new_messages_indicator = null;
private UnityLauncher? unity_launcher = null;
private Libnotify? libnotify = null;
private uint select_folder_timeout_id = 0;
private int64 next_folder_select_allowed_usec = 0;
private Geary.Nonblocking.Mutex select_folder_mutex = new Geary.Nonblocking.Mutex();
private Geary.Account? account_to_select = null;
2013-05-14 11:52:02 -07:00
private Geary.Folder? previous_non_search_folder = null;
2013-07-08 14:22:23 -07:00
private UpgradeDialog upgrade_dialog;
private Gee.List<string> pending_mailtos = new Gee.ArrayList<string>();
private Geary.Nonblocking.Mutex untrusted_host_prompt_mutex = new Geary.Nonblocking.Mutex();
private Gee.HashSet<Geary.Endpoint> validating_endpoints = new Gee.HashSet<Geary.Endpoint>();
private Geary.Revokable? revokable = null;
2013-06-07 16:23:45 -07:00
2013-08-08 18:47:23 -07:00
// List of windows we're waiting to close before Geary closes.
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
private Gee.List<ComposerWidget> waiting_to_close = new Gee.ArrayList<ComposerWidget>();
2013-08-08 18:47:23 -07:00
2013-06-07 16:23:45 -07:00
/**
* Fired when the currently selected account has changed.
*/
public signal void account_selected(Geary.Account? account);
/**
* Fired when the currently selected folder has changed.
*/
public signal void folder_selected(Geary.Folder? folder);
/**
* Fired when the number of conversations changes.
*/
public signal void conversation_count_changed(int count);
/**
* Fired when the search text is changed according to the controller. This accounts
* for a brief typmatic delay.
*/
public signal void search_text_changed(string keywords);
/**
* Constructs a new instance of the controller.
*/
public GearyController(GearyApplication application) {
this.application = application;
2013-06-07 16:23:45 -07:00
}
2013-06-07 16:23:45 -07:00
~GearyController() {
assert(current_account == null);
}
2013-06-07 16:23:45 -07:00
/**
* Starts the controller and brings up Geary.
*/
public async void open_async() {
// This initializes the IconFactory, important to do before
// the actions are created (as they refer to some of Geary's
// custom icons)
IconFactory.instance.init();
// Ensure all geary windows have an icon
Gtk.Window.set_default_icon_name("geary");
apply_app_menu_fix();
// Setup actions.
setup_actions();
this.application.load_ui_resource("accelerators.ui");
// Listen for attempts to close the application.
this.application.exiting.connect(on_application_exiting);
2013-07-08 14:22:23 -07:00
// Create DB upgrade dialog.
upgrade_dialog = new UpgradeDialog();
upgrade_dialog.notify[UpgradeDialog.PROP_VISIBLE_NAME].connect(display_main_window_if_ready);
// Use a global avatar session because a cache must be used
// per-session, and we don't want to have to load the cache
// for each conversation load.
File avatar_cache_dir = this.application.get_user_cache_directory()
.get_child("avatar_cache");
this.avatar_cache = new Soup.Cache(
avatar_cache_dir.get_path(),
Soup.CacheType.SINGLE_USER
);
this.avatar_cache.load();
this.avatar_cache.set_max_size(10 * 1024 * 1024); // 4MB
this.avatar_session = new Soup.Session.with_options(
Soup.SESSION_USER_AGENT, "Geary/" + GearyApplication.VERSION
);
this.avatar_session.add_feature(avatar_cache);
// Create the main window (must be done after creating actions.)
main_window = new MainWindow(this.application);
main_window.on_shift_key.connect(on_shift_key);
main_window.notify["has-toplevel-focus"].connect(on_has_toplevel_focus);
enable_message_buttons(false);
2013-06-07 16:23:45 -07:00
Geary.Engine.instance.account_available.connect(on_account_available);
Geary.Engine.instance.account_unavailable.connect(on_account_unavailable);
Geary.Engine.instance.untrusted_host.connect(on_untrusted_host);
2013-06-07 16:23:45 -07:00
// Connect to various UI signals.
main_window.conversation_list_view.conversations_selected.connect(on_conversations_selected);
2013-07-19 15:44:20 -07:00
main_window.conversation_list_view.conversation_activated.connect(on_conversation_activated);
main_window.conversation_list_view.load_more.connect(on_load_more);
main_window.conversation_list_view.mark_conversations.connect(on_mark_conversations);
main_window.conversation_list_view.visible_conversations_changed.connect(on_visible_conversations_changed);
2012-02-01 12:32:07 -08:00
main_window.folder_list.folder_selected.connect(on_folder_selected);
main_window.folder_list.copy_conversation.connect(on_copy_conversation);
main_window.folder_list.move_conversation.connect(on_move_conversation);
main_window.main_toolbar.copy_folder_menu.folder_selected.connect(on_copy_conversation);
main_window.main_toolbar.move_folder_menu.folder_selected.connect(on_move_conversation);
main_window.search_bar.search_text_changed.connect((text) => { do_search(text); });
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
main_window.conversation_viewer.conversation_added.connect(
on_conversation_view_added
);
new_messages_monitor = new NewMessagesMonitor(should_notify_new_messages);
main_window.folder_list.set_new_messages_monitor(new_messages_monitor);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
// New messages indicator (Ubuntuism)
new_messages_indicator = NewMessagesIndicator.create(new_messages_monitor);
new_messages_indicator.application_activated.connect(on_indicator_activated_application);
new_messages_indicator.composer_activated.connect(on_indicator_activated_composer);
new_messages_indicator.inbox_activated.connect(on_indicator_activated_inbox);
unity_launcher = new UnityLauncher(new_messages_monitor);
// libnotify
libnotify = new Libnotify(new_messages_monitor);
libnotify.invoked.connect(on_libnotify_invoked);
// This is fired after the accounts are ready.
Geary.Engine.instance.opened.connect(on_engine_opened);
this.main_window.conversation_list_view.grab_focus();
// instantiate here to ensure that Config is initialized and ready
autostart_manager = new AutostartManager();
// initialize revokable
save_revokable(null, null);
// Migrate configuration if necessary.
try {
Migrate.xdg_config_dir(this.application.get_user_data_directory(),
this.application.get_user_config_directory());
} catch (Error e) {
error("Error migrating configuration directories: %s", e.message);
}
// Start Geary.
try {
yield Geary.Engine.instance.open_async(
this.application.get_user_config_directory(),
this.application.get_user_data_directory(),
this.application.get_resource_directory(),
new SecretMediator()
);
if (Geary.Engine.instance.get_accounts().size == 0) {
create_account();
}
} catch (Error e) {
error("Error opening Geary.Engine instance: %s", e.message);
}
}
2013-06-07 16:23:45 -07:00
/**
* At the moment, this is non-reversible, i.e. once closed a GearyController cannot be
* re-opened.
2013-06-07 16:23:45 -07:00
*/
public async void close_async() {
Geary.Engine.instance.account_available.disconnect(on_account_available);
Geary.Engine.instance.account_unavailable.disconnect(on_account_unavailable);
Geary.Engine.instance.untrusted_host.disconnect(on_untrusted_host);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
// Disconnect from various UI signals.
main_window.conversation_list_view.conversations_selected.disconnect(on_conversations_selected);
main_window.conversation_list_view.conversation_activated.disconnect(on_conversation_activated);
main_window.conversation_list_view.load_more.disconnect(on_load_more);
main_window.conversation_list_view.mark_conversations.disconnect(on_mark_conversations);
main_window.conversation_list_view.visible_conversations_changed.disconnect(on_visible_conversations_changed);
main_window.folder_list.folder_selected.disconnect(on_folder_selected);
main_window.folder_list.copy_conversation.disconnect(on_copy_conversation);
main_window.folder_list.move_conversation.disconnect(on_move_conversation);
main_window.main_toolbar.copy_folder_menu.folder_selected.disconnect(on_copy_conversation);
main_window.main_toolbar.move_folder_menu.folder_selected.disconnect(on_move_conversation);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
main_window.conversation_viewer.conversation_added.disconnect(
on_conversation_view_added
);
// hide window while shutting down, as this can take a few seconds under certain conditions
main_window.hide();
// drop the Revokable, which will commit it if necessary
save_revokable(null, null);
// close the ConversationMonitor
try {
if (current_conversations != null) {
debug("Stopping conversation monitor for %s...", current_conversations.folder.to_string());
bool closing = yield current_conversations.stop_monitoring_async(null);
// If not an Inbox, wait for it to close so all pending operations are flushed
if (closing) {
debug("Waiting for %s to close...", current_conversations.folder.to_string());
yield current_conversations.folder.wait_for_close_async(null);
}
debug("Stopped conversation monitor for %s", current_conversations.folder.to_string());
}
} catch (Error err) {
message("Error closing conversation monitor %s at shutdown: %s",
current_conversations.folder.to_string(), err.message);
} finally {
current_conversations = null;
}
// close all Inboxes
foreach (Geary.Folder inbox in inboxes.values) {
try {
debug("Closing %s...", inbox.to_string());
// close and wait for all pending operations to be flushed
yield inbox.close_async(null);
debug("Waiting for %s to close completely...", inbox.to_string());
yield inbox.wait_for_close_async(null);
debug("Closed %s", inbox.to_string());
} catch (Error err) {
message("Error closing Inbox %s at shutdown: %s", inbox.to_string(), err.message);
}
}
// close all Accounts
foreach (Geary.Account account in email_stores.keys) {
try {
debug("Closing account %s", account.to_string());
yield account.close_async(null);
debug("Closed account %s", account.to_string());
} catch (Error err) {
message("Error closing account %s at shutdown: %s", account.to_string(), err.message);
}
}
2013-06-07 16:23:45 -07:00
main_window.destroy();
debug("Flushing avatar cache...");
avatar_cache.flush();
avatar_cache.dump();
// Turn off the lights and lock the door behind you
try {
debug("Closing Engine...");
yield Geary.Engine.instance.close_async(null);
debug("Closed Engine");
} catch (Error err) {
message("Error closing Geary Engine instance: %s", err.message);
}
}
/**
* Opens a new, blank composer.
*/
public void compose() {
create_compose_widget(ComposerWidget.ComposeType.NEW_MESSAGE);
}
/**
* Opens or queues a new composer addressed to a specific email address.
*/
public void compose_mailto(string mailto) {
if (current_account == null) {
// Schedule the send for after we have an account open.
pending_mailtos.add(mailto);
} else {
create_compose_widget(ComposerWidget.ComposeType.NEW_MESSAGE, null, null, mailto);
}
}
private void add_accelerator(string accelerator, string action) {
GtkUtil.add_accelerator(this.application.ui_manager, this.application.actions,
accelerator, action);
}
// Fix for clients having both:
// * disabled Gtk/ShellShowsAppMenu setting
// * no 'menu' setting in Gtk/DecorationLayout
// See https://bugzilla.gnome.org/show_bug.cgi?id=770617
private void apply_app_menu_fix() {
Gtk.Settings? settings = Gtk.Settings.get_default();
if (settings == null) {
warning("Couldn't fetch Gtk default settings");
return ;
}
string? decoration_layout = settings.gtk_decoration_layout;
if (decoration_layout == null) decoration_layout = "";
if (!decoration_layout.contains("menu")) {
string prefix = "menu:";
if (decoration_layout.contains(":")) {
prefix = (decoration_layout.has_prefix(":")) ? "menu" : "menu,";
}
settings.gtk_decoration_layout = prefix + settings.gtk_decoration_layout;
}
}
private Gtk.ActionEntry[] create_actions() {
Gtk.ActionEntry[] entries = new Gtk.ActionEntry[0];
Gtk.ActionEntry mark_menu = { ACTION_MARK_AS_MENU, null, TRANSLATABLE, null, _("Mark conversation"),
on_show_mark_menu };
mark_menu.label = _("_Mark as...");
2013-02-22 17:54:05 -08:00
mark_menu.tooltip = MARK_MESSAGE_MENU_TOOLTIP_SINGLE;
entries += mark_menu;
Gtk.ActionEntry mark_read = { ACTION_MARK_AS_READ, "mail-mark-read", TRANSLATABLE, "<Ctrl>I",
null, on_mark_as_read };
mark_read.label = _("Mark as _Read");
entries += mark_read;
add_accelerator("<Shift>I", ACTION_MARK_AS_READ);
Gtk.ActionEntry mark_unread = { ACTION_MARK_AS_UNREAD, "mail-mark-unread", TRANSLATABLE,
"<Ctrl>U", null, on_mark_as_unread };
mark_unread.label = _("Mark as _Unread");
entries += mark_unread;
add_accelerator("<Shift>U", ACTION_MARK_AS_UNREAD);
Gtk.ActionEntry mark_starred = { ACTION_MARK_AS_STARRED, "star-symbolic", TRANSLATABLE, "S", null,
on_mark_as_starred };
mark_starred.label = _("_Star");
entries += mark_starred;
Gtk.ActionEntry mark_unstarred = { ACTION_MARK_AS_UNSTARRED, "non-starred", TRANSLATABLE, "D",
null, on_mark_as_unstarred };
mark_unstarred.label = _("U_nstar");
entries += mark_unstarred;
2013-02-21 14:57:59 -08:00
Gtk.ActionEntry mark_spam = { ACTION_MARK_AS_SPAM, null, TRANSLATABLE, "<Ctrl>J", null,
on_mark_as_spam };
mark_spam.label = MARK_AS_SPAM_LABEL;
entries += mark_spam;
add_accelerator("exclam", ACTION_MARK_AS_SPAM); // Exclamation mark (!)
Gtk.ActionEntry copy_menu = { ACTION_COPY_MENU, null, TRANSLATABLE, "L",
_("Add label"), null };
copy_menu.label = _("_Label");
entries += copy_menu;
Gtk.ActionEntry move_menu = { ACTION_MOVE_MENU, null, TRANSLATABLE, "M", _("Move conversation"), null };
move_menu.label = _("_Move");
entries += move_menu;
Gtk.ActionEntry new_message = { ACTION_NEW_MESSAGE, null, null, "<Ctrl>N",
_("Compose new message (Ctrl+N, N)"), on_new_message };
entries += new_message;
add_accelerator("N", ACTION_NEW_MESSAGE);
Gtk.ActionEntry reply_to_message = { ACTION_REPLY_TO_MESSAGE, null, _("_Reply"), "<Ctrl>R",
_("Reply (Ctrl+R, R)"), on_reply_to_message_action };
2012-01-17 18:42:20 -08:00
entries += reply_to_message;
add_accelerator("R", ACTION_REPLY_TO_MESSAGE);
2012-01-17 18:42:20 -08:00
Gtk.ActionEntry reply_all_message = { ACTION_REPLY_ALL_MESSAGE, null, _("R_eply All"),
"<Ctrl><Shift>R", _("Reply all (Ctrl+Shift+R, Shift+R)"),
on_reply_all_message_action };
2012-01-17 18:42:20 -08:00
entries += reply_all_message;
add_accelerator("<Shift>R", ACTION_REPLY_ALL_MESSAGE);
2012-01-17 18:42:20 -08:00
Gtk.ActionEntry forward_message = { ACTION_FORWARD_MESSAGE, null, _("_Forward"), "<Ctrl>L",
_("Forward (Ctrl+L, F)"), on_forward_message_action };
2012-01-24 18:24:32 -08:00
entries += forward_message;
add_accelerator("F", ACTION_FORWARD_MESSAGE);
2012-01-24 18:24:32 -08:00
Gtk.ActionEntry find_in_conversation = { ACTION_FIND_IN_CONVERSATION, null, null, "<Ctrl>F",
null, on_find_in_conversation_action };
entries += find_in_conversation;
add_accelerator("slash", ACTION_FIND_IN_CONVERSATION);
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
Gtk.ActionEntry archive_message = { ACTION_ARCHIVE_MESSAGE, ARCHIVE_MESSAGE_ICON_NAME,
ARCHIVE_MESSAGE_LABEL, "A", null, on_archive_message };
archive_message.tooltip = ARCHIVE_MESSAGE_TOOLTIP_SINGLE;
entries += archive_message;
// although this action changes according to the account's capabilities, set to Delete
// until they're known so the "translatable" string doesn't first appear
Gtk.ActionEntry trash_message = { ACTION_TRASH_MESSAGE, TRASH_MESSAGE_ICON_NAME,
null, "Delete", null, on_trash_message };
trash_message.tooltip = TRASH_MESSAGE_TOOLTIP_SINGLE;
entries += trash_message;
add_accelerator("BackSpace", ACTION_TRASH_MESSAGE);
Gtk.ActionEntry delete_message = { ACTION_DELETE_MESSAGE, DELETE_MESSAGE_ICON_NAME,
null, "<Shift>Delete", null, on_delete_message };
delete_message.label = DELETE_MESSAGE_LABEL;
delete_message.tooltip = DELETE_MESSAGE_TOOLTIP_SINGLE;
2011-12-15 16:16:27 -08:00
entries += delete_message;
add_accelerator("<Shift>BackSpace", ACTION_DELETE_MESSAGE);
Gtk.ActionEntry empty_spam = { ACTION_EMPTY_SPAM, null, null, null, null, on_empty_spam };
empty_spam.label = _("Empty _Spam…");
entries += empty_spam;
Gtk.ActionEntry empty_trash = { ACTION_EMPTY_TRASH, null, null, null, null, on_empty_trash };
empty_trash.label = _("Empty _Trash…");
entries += empty_trash;
Gtk.ActionEntry undo = { ACTION_UNDO, "edit-undo-symbolic", null, "<Ctrl>Z", null, on_revoke };
entries += undo;
Gtk.ActionEntry zoom_in = { ACTION_ZOOM_IN, null, null, "<Ctrl>equal",
null, on_zoom_in };
entries += zoom_in;
add_accelerator("equal", ACTION_ZOOM_IN);
Gtk.ActionEntry zoom_out = { ACTION_ZOOM_OUT, null, null, "<Ctrl>minus",
null, on_zoom_out };
entries += zoom_out;
add_accelerator("minus", ACTION_ZOOM_OUT);
Gtk.ActionEntry zoom_normal = { ACTION_ZOOM_NORMAL, null, null, "<Ctrl>0",
null, on_zoom_normal };
entries += zoom_normal;
add_accelerator("0", ACTION_ZOOM_NORMAL);
Gtk.ActionEntry search = {
ACTION_SEARCH, null, null, "<Ctrl>S", null,
() => { show_search_bar(); }
};
entries += search;
Gtk.ActionEntry conversation_list = { ACTION_CONVERSATION_LIST, null, null, "<Ctrl>B", null, on_conversation_list };
entries += conversation_list;
// No callback is connected, since we bind the toggle button to the search bar visibility
Gtk.ActionEntry toggle_search = { ACTION_TOGGLE_SEARCH, null, null, null,
_("Toggle search bar"), null };
entries += toggle_search;
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
// No callback is connected, since we bind the toggle button to the find bar visibility
Gtk.ActionEntry toggle_find = { ACTION_TOGGLE_FIND, null, null, null,
_("Toggle find bar"), null };
entries += toggle_find;
2013-04-04 19:12:22 -07:00
return entries;
}
2013-04-04 19:12:22 -07:00
private Gtk.ToggleActionEntry[] create_toggle_actions() {
Gtk.ToggleActionEntry[] entries = new Gtk.ToggleActionEntry[0];
return entries;
}
private void setup_actions() {
const string[] important_actions = {
ACTION_NEW_MESSAGE,
ACTION_REPLY_TO_MESSAGE,
ACTION_REPLY_ALL_MESSAGE,
ACTION_FORWARD_MESSAGE,
ACTION_ARCHIVE_MESSAGE,
ACTION_TRASH_MESSAGE,
ACTION_DELETE_MESSAGE,
};
Gtk.ActionGroup action_group = this.application.actions;
Gtk.ActionEntry[] action_entries = create_actions();
action_group.add_actions(action_entries, this);
foreach (Gtk.ActionEntry e in action_entries) {
Gtk.Action action = action_group.get_action(e.name);
assert(action != null);
if (e.name in important_actions)
action.is_important = true;
}
Gtk.ToggleActionEntry[] toggle_action_entries = create_toggle_actions();
action_group.add_toggle_actions(toggle_action_entries, this);
this.application.ui_manager.insert_action_group(action_group, 0);
}
2013-06-07 16:23:45 -07:00
private void open_account(Geary.Account account) {
account.report_problem.connect(on_report_problem);
account.email_removed.connect(on_account_email_removed);
2013-07-08 14:22:23 -07:00
connect_account_async.begin(account, cancellable_open_account);
2013-06-07 16:23:45 -07:00
}
private void close_account(Geary.Account account) {
account.report_problem.disconnect(on_report_problem);
account.email_removed.disconnect(on_account_email_removed);
2013-06-07 16:23:45 -07:00
disconnect_account_async.begin(account);
}
private Geary.Account get_account_instance(Geary.AccountInformation account_information) {
try {
return Geary.Engine.instance.get_account_instance(account_information);
} catch (Error e) {
error("Error creating account instance: %s", e.message);
}
}
private void on_account_available(Geary.AccountInformation account_information) {
2013-07-08 14:22:23 -07:00
Geary.Account account = get_account_instance(account_information);
upgrade_dialog.add_account(account, cancellable_open_account);
open_account(account);
2013-06-07 16:23:45 -07:00
}
private void on_account_unavailable(Geary.AccountInformation account_information) {
close_account(get_account_instance(account_information));
}
private void on_untrusted_host(Geary.AccountInformation account_information,
Geary.Endpoint endpoint, Geary.Endpoint.SecurityType security, TlsConnection cx,
Geary.Service service) {
prompt_untrusted_host_async.begin(account_information, endpoint, security, cx, service);
}
private async void prompt_untrusted_host_async(Geary.AccountInformation account_information,
Geary.Endpoint endpoint, Geary.Endpoint.SecurityType security, TlsConnection cx,
Geary.Service service) {
// use a mutex to prevent multiple dialogs popping up at the same time
int token = Geary.Nonblocking.Mutex.INVALID_TOKEN;
try {
token = yield untrusted_host_prompt_mutex.claim_async();
} catch (Error err) {
message("Unable to lock mutex to prompt user about invalid certificate: %s", err.message);
return;
}
yield locked_prompt_untrusted_host_async(account_information, endpoint, security, cx,
service);
try {
untrusted_host_prompt_mutex.release(ref token);
} catch (Error err) {
message("Unable to release mutex after prompting user about invalid certificate: %s",
err.message);
}
}
private static void get_gcr_params(Geary.Endpoint endpoint, out Gcr.Certificate cert,
out string peer) {
cert = new Gcr.SimpleCertificate(endpoint.untrusted_certificate.certificate.data);
peer = "%s:%u".printf(endpoint.remote_address.hostname, endpoint.remote_address.port);
}
private async void locked_prompt_untrusted_host_async(Geary.AccountInformation account_information,
Geary.Endpoint endpoint, Geary.Endpoint.SecurityType security, TlsConnection cx,
Geary.Service service) {
// possible while waiting on mutex that this endpoint became trusted or untrusted
if (endpoint.trust_untrusted_host != Geary.Trillian.UNKNOWN)
return;
// get GCR parameters
Gcr.Certificate cert;
string peer;
get_gcr_params(endpoint, out cert, out peer);
// Geary allows for user to auto-revoke all questionable server certificates without
// digging around in a keyring/pk manager
if (Args.revoke_certs) {
debug("Auto-revoking certificate for %s...", peer);
try {
gcr_trust_remove_pinned_certificate(cert, GCR_PURPOSE_SERVER_AUTH, peer, null);
} catch (Error err) {
message("Unable to auto-revoke server certificate for %s: %s", peer, err.message);
// drop through, not absolutely valid to do this (might also mean certificate
// was never pinned)
}
}
// if pinned, the user has already made an exception for this server and its certificate,
// so go ahead w/o asking
try {
if (gcr_trust_is_certificate_pinned(cert, GCR_PURPOSE_SERVER_AUTH, peer, null)) {
debug("Certificate for %s is pinned, accepting connection...", peer);
endpoint.trust_untrusted_host = Geary.Trillian.TRUE;
return;
}
} catch (Error err) {
message("Unable to check if server certificate for %s is pinned, assuming not: %s",
peer, err.message);
}
// if these are in validation, there are complex GTK and workflow issues from simply
// presenting the prompt now, so caller who connected will need to do it on their own dime
if (!validating_endpoints.contains(endpoint))
prompt_for_untrusted_host(main_window, account_information, endpoint, service, false);
}
private void prompt_for_untrusted_host(Gtk.Window? parent, Geary.AccountInformation account_information,
Geary.Endpoint endpoint, Geary.Service service, bool is_validation) {
CertificateWarningDialog dialog = new CertificateWarningDialog(parent, account_information,
service, endpoint.tls_validation_warnings, is_validation);
switch (dialog.run()) {
case CertificateWarningDialog.Result.TRUST:
endpoint.trust_untrusted_host = Geary.Trillian.TRUE;
break;
case CertificateWarningDialog.Result.ALWAYS_TRUST:
endpoint.trust_untrusted_host = Geary.Trillian.TRUE;
// get GCR parameters for pinning
Gcr.Certificate cert;
string peer;
get_gcr_params(endpoint, out cert, out peer);
// pinning the certificate creates an exception for the next time a connection
// is attempted
debug("Pinning certificate for %s...", peer);
try {
gcr_trust_add_pinned_certificate(cert, GCR_PURPOSE_SERVER_AUTH, peer, null);
} catch (Error err) {
ErrorDialog error_dialog = new ErrorDialog(main_window,
_("Unable to store server trust exception"), err.message);
error_dialog.run();
}
break;
default:
endpoint.trust_untrusted_host = Geary.Trillian.FALSE;
// close the account; can't go any further w/o offline mode
try {
if (Geary.Engine.instance.get_accounts().has_key(account_information.id)) {
Geary.Account account = Geary.Engine.instance.get_account_instance(account_information);
close_account(account);
}
} catch (Error err) {
message("Unable to close account due to user trust issues: %s", err.message);
}
break;
}
}
2013-06-07 16:23:45 -07:00
private void create_account() {
Geary.AccountInformation? account_information = request_account_information(null);
if (account_information != null)
do_validate_until_successful_async.begin(account_information);
}
private async void do_validate_until_successful_async(Geary.AccountInformation account_information,
Cancellable? cancellable = null) {
Geary.AccountInformation? result = account_information;
do {
result = yield validate_or_retry_async(result, cancellable);
} while (result != null);
if (login_dialog != null)
login_dialog.hide();
}
// Returns possibly modified validation results
private Geary.Engine.ValidationResult validation_check_endpoint_for_tls_warnings(
Geary.AccountInformation account_information, Geary.Service service,
Geary.Engine.ValidationResult validation_result, out bool prompted, out bool retry_required) {
prompted = false;
retry_required = false;
// use LoginDialog for parent only if available and visible
Gtk.Window? parent;
if (login_dialog != null && login_dialog.visible)
parent = login_dialog;
else
parent = main_window;
Geary.Endpoint endpoint = account_information.get_endpoint_for_service(service);
// If Endpoint had unresolved TLS issues, prompt user about them
if (endpoint.tls_validation_warnings != 0 && endpoint.trust_untrusted_host != Geary.Trillian.TRUE) {
prompt_for_untrusted_host(parent, account_information, endpoint, service, true);
prompted = true;
}
// If there are still TLS connection issues that caused the connection to fail (happens on the
// first attempt), clear those errors and retry
if (endpoint.tls_validation_warnings != 0 && endpoint.trust_untrusted_host == Geary.Trillian.TRUE) {
Geary.Engine.ValidationResult flag = (service == Geary.Service.IMAP)
? Geary.Engine.ValidationResult.IMAP_CONNECTION_FAILED
: Geary.Engine.ValidationResult.SMTP_CONNECTION_FAILED;
if ((validation_result & flag) != 0) {
validation_result &= ~flag;
retry_required = true;
}
}
return validation_result;
}
// Use after validating to see if TLS warnings were handled by the user and need to retry the
// validation; this will also modify the validation results to better indicate issues to the user
//
// Returns possibly modified validation results
public async Geary.Engine.ValidationResult validation_check_for_tls_warnings_async(
Geary.AccountInformation account_information, Geary.Engine.ValidationResult validation_result,
out bool retry_required) {
retry_required = false;
// Because TLS warnings need cycles to process, sleep and give 'em a chance to do their
// thing ... note that the signal handler does *not* invoke the user prompt dialog when the
// login dialog is in play, so this sleep does not need to worry about user input
yield Geary.Scheduler.sleep_ms_async(100);
// check each service for problems, prompting user each time for verification
bool imap_prompted, imap_retry_required;
validation_result = validation_check_endpoint_for_tls_warnings(account_information,
Geary.Service.IMAP, validation_result, out imap_prompted, out imap_retry_required);
bool smtp_prompted, smtp_retry_required;
validation_result = validation_check_endpoint_for_tls_warnings(account_information,
Geary.Service.SMTP, validation_result, out smtp_prompted, out smtp_retry_required);
// if prompted for user acceptance of bad certificates and they agreed to both, try again
if (imap_prompted && smtp_prompted
&& account_information.get_imap_endpoint().is_trusted_or_never_connected
&& account_information.get_smtp_endpoint().is_trusted_or_never_connected) {
retry_required = true;
} else if (validation_result == Geary.Engine.ValidationResult.OK) {
retry_required = true;
} else {
// if prompt requires retry or otherwise detected it, retry
retry_required = imap_retry_required && smtp_retry_required;
}
return validation_result;
}
2013-06-07 16:23:45 -07:00
// Returns null if we are done validating, or the revised account information if we should retry.
private async Geary.AccountInformation? validate_or_retry_async(Geary.AccountInformation account_information,
Cancellable? cancellable = null) {
Geary.Engine.ValidationResult result = yield validate_async(account_information,
Geary.Engine.ValidationOption.CHECK_CONNECTIONS, cancellable);
2013-06-07 16:23:45 -07:00
if (result == Geary.Engine.ValidationResult.OK)
return null;
// check Endpoints for trust (TLS) issues
bool retry_required;
result = yield validation_check_for_tls_warnings_async(account_information, result,
out retry_required);
// return for retry if required; check can also change validation results, in which case
// revalidate entirely to have them written out
if (retry_required)
return account_information;
2013-06-07 16:23:45 -07:00
debug("Validation failed. Prompting user for revised account information");
Geary.AccountInformation? new_account_information =
request_account_information(account_information, result);
// If the user refused to enter account information. There is currently no way that we
// could see this--we exit in request_account_information, and the only way that an
// exit could be canceled is if there are unsaved composer windows open (which won't
// happen before an account is created). However, best to include this check for the
// future.
if (new_account_information == null)
return null;
debug("User entered revised account information, retrying validation");
return new_account_information;
}
// Attempts to validate and add an account. Returns a result code indicating
// success or one or more errors.
public async Geary.Engine.ValidationResult validate_async(
Geary.AccountInformation account_information, Geary.Engine.ValidationOption options,
2013-06-07 16:23:45 -07:00
Cancellable? cancellable = null) {
// add Endpoints to set of validating endpoints to prevent the prompt from appearing
validating_endpoints.add(account_information.get_imap_endpoint());
validating_endpoints.add(account_information.get_smtp_endpoint());
2013-06-07 16:23:45 -07:00
Geary.Engine.ValidationResult result = Geary.Engine.ValidationResult.OK;
try {
result = yield Geary.Engine.instance.validate_account_information_async(account_information,
options, cancellable);
2013-06-07 16:23:45 -07:00
} catch (Error err) {
debug("Error validating account: %s", err.message);
this.application.exit(-1); // Fatal error
2013-06-07 16:23:45 -07:00
return result;
}
validating_endpoints.remove(account_information.get_imap_endpoint());
validating_endpoints.remove(account_information.get_smtp_endpoint());
2013-06-07 16:23:45 -07:00
if (result == Geary.Engine.ValidationResult.OK) {
Geary.AccountInformation real_account_information = account_information;
if (account_information.is_copy()) {
// We have a temporary copy of the account. Find the "real" acct info object and
// copy the new data into it.
real_account_information = get_real_account_information(account_information);
real_account_information.copy_from(account_information);
}
real_account_information.store_async.begin(cancellable);
do_update_stored_passwords_async.begin(Geary.ServiceFlag.IMAP | Geary.ServiceFlag.SMTP,
real_account_information);
2013-06-07 16:23:45 -07:00
debug("Successfully validated account information");
}
return result;
}
// Returns the "real" account info associated with a copy. If it's not a copy, null is returned.
public Geary.AccountInformation? get_real_account_information(
Geary.AccountInformation account_information) {
if (account_information.is_copy()) {
try {
return Geary.Engine.instance.get_accounts().get(account_information.id);
2013-06-07 16:23:45 -07:00
} catch (Error e) {
error("Account information is out of sync: %s", e.message);
}
}
return null;
}
// Prompt the user for a service, real name, username, and password, and try to start Geary.
private Geary.AccountInformation? request_account_information(Geary.AccountInformation? old_info,
Geary.Engine.ValidationResult result = Geary.Engine.ValidationResult.OK) {
Geary.AccountInformation? new_info = old_info;
if (login_dialog == null) {
// Create here so we know GTK is initialized.
login_dialog = new LoginDialog();
} else if (!login_dialog.get_visible()) {
// If the dialog has been dismissed, exit here.
this.application.exit();
return null;
}
2013-06-07 16:23:45 -07:00
if (new_info != null)
login_dialog.set_account_information(new_info, result);
login_dialog.present();
for (;;) {
login_dialog.show_spinner(false);
if (login_dialog.run() != Gtk.ResponseType.OK) {
debug("User refused to enter account information. Exiting...");
this.application.exit(1);
2013-06-07 16:23:45 -07:00
return null;
}
login_dialog.show_spinner(true);
new_info = login_dialog.get_account_information();
if ((!new_info.default_imap_server_ssl && !new_info.default_imap_server_starttls)
|| (!new_info.default_smtp_server_ssl && !new_info.default_smtp_server_starttls)) {
ConfirmationDialog security_dialog = new ConfirmationDialog(main_window,
_("Your settings are insecure"),
_("Your IMAP and/or SMTP settings do not specify SSL or TLS. This means your username and password could be read by another person on the network. Are you sure you want to do this?"),
_("Co_ntinue"));
if (security_dialog.run() != Gtk.ResponseType.OK)
continue;
}
break;
}
return new_info;
}
private async void do_update_stored_passwords_async(Geary.ServiceFlag services,
2013-06-07 16:23:45 -07:00
Geary.AccountInformation account_information) {
try {
yield account_information.update_stored_passwords_async(services);
} catch (Error e) {
debug("Error updating stored passwords: %s", e.message);
}
}
private void on_report_problem(Geary.Account account, Geary.Account.Problem problem, Error? err) {
debug("Reported problem: %s Error: %s", problem.to_string(), err != null ? err.message : "(N/A)");
switch (problem) {
case Geary.Account.Problem.DATABASE_FAILURE:
case Geary.Account.Problem.HOST_UNREACHABLE:
case Geary.Account.Problem.NETWORK_UNAVAILABLE:
// TODO
break;
case Geary.Account.Problem.RECV_EMAIL_LOGIN_FAILED:
case Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED:
// At this point, we've prompted them for the password and
// they've hit cancel, so there's not much for us to do here.
close_account(account);
break;
case Geary.Account.Problem.EMAIL_DELIVERY_FAILURE:
handle_outbox_failure(StatusBar.Message.OUTBOX_SEND_FAILURE);
break;
case Geary.Account.Problem.SAVE_SENT_MAIL_FAILED:
handle_outbox_failure(StatusBar.Message.OUTBOX_SAVE_SENT_MAIL_FAILED);
break;
case Geary.Account.Problem.CONNECTION_FAILURE:
ErrorDialog dialog = new ErrorDialog(main_window,
_("Error connecting to the server"),
_("Geary encountered an error while connecting to the server. Please try again in a few moments."));
dialog.run();
break;
2013-06-07 16:23:45 -07:00
default:
assert_not_reached();
}
}
private void handle_outbox_failure(StatusBar.Message message) {
bool activate_message = false;
try {
// Due to a timing hole where it's possible to delete a message
// from the outbox after the SMTP queue has picked it up and is
// in the process of sending it, we only want to display a message
// telling the user there's a problem if there are any other
// messages waiting to be sent on any account.
foreach (Geary.AccountInformation info in Geary.Engine.instance.get_accounts().values) {
Geary.Account account = Geary.Engine.instance.get_account_instance(info);
if (account.is_open()) {
Geary.Folder? outbox = account.get_special_folder(Geary.SpecialFolderType.OUTBOX);
if (outbox != null && outbox.properties.email_total > 0) {
activate_message = true;
break;
}
}
}
} catch (Error e) {
debug("Error determining whether any outbox has messages: %s", e.message);
activate_message = true;
}
if (activate_message) {
if (!main_window.status_bar.is_message_active(message))
main_window.status_bar.activate_message(message);
switch (message) {
case StatusBar.Message.OUTBOX_SEND_FAILURE:
libnotify.set_error_notification(_("Error sending email"),
_("Geary encountered an error sending an email. If the problem persists, please manually delete the email from your Outbox folder."));
break;
case StatusBar.Message.OUTBOX_SAVE_SENT_MAIL_FAILED:
libnotify.set_error_notification(_("Error saving sent mail"),
_("Geary encountered an error saving a sent message to Sent Mail. The message will stay in your Outbox folder until you delete it."));
break;
default:
assert_not_reached();
}
}
}
private void on_account_email_removed(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier> ids) {
if (folder.special_folder_type == Geary.SpecialFolderType.OUTBOX) {
main_window.status_bar.deactivate_message(StatusBar.Message.OUTBOX_SEND_FAILURE);
main_window.status_bar.deactivate_message(StatusBar.Message.OUTBOX_SAVE_SENT_MAIL_FAILED);
libnotify.clear_error_notification();
}
}
private void on_sending_started() {
main_window.status_bar.activate_message(StatusBar.Message.OUTBOX_SENDING);
}
private void on_sending_finished() {
main_window.status_bar.deactivate_message(StatusBar.Message.OUTBOX_SENDING);
}
2013-06-07 16:23:45 -07:00
// Removes an existing account.
public async void remove_account_async(Geary.AccountInformation account,
Cancellable? cancellable = null) {
try {
yield get_account_instance(account).close_async(cancellable);
2013-07-08 17:56:30 -07:00
yield Geary.Engine.instance.remove_account_async(account, cancellable);
2013-06-07 16:23:45 -07:00
} catch (Error e) {
message("Error removing account: %s", e.message);
}
}
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
public async void connect_account_async(Geary.Account account, Cancellable? cancellable = null) {
account.folders_available_unavailable.connect(on_folders_available_unavailable);
account.sending_monitor.start.connect(on_sending_started);
account.sending_monitor.finish.connect(on_sending_finished);
2013-06-07 16:23:45 -07:00
bool retry = false;
do {
try {
account.set_data(PROP_ATTEMPT_OPEN_ACCOUNT, true);
yield account.open_async(cancellable);
retry = false;
} catch (Error open_err) {
debug("Unable to open account %s: %s", account.to_string(), open_err.message);
if (open_err is Geary.EngineError.CORRUPT)
retry = yield account_database_error_async(account);
else if (open_err is Geary.EngineError.PERMISSIONS)
yield account_database_perms_async(account);
else if (open_err is Geary.EngineError.VERSION)
yield account_database_version_async(account);
else
yield account_general_error_async(account);
if (!retry)
return;
}
} while (retry);
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
email_stores.set(account, new Geary.App.EmailStore(account));
inbox_cancellables.set(account, new Cancellable());
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
account.email_sent.connect(on_sent);
main_window.folder_list.set_user_folders_root_name(account, _("Labels"));
2013-07-08 14:22:23 -07:00
display_main_window_if_ready();
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
}
// Returns true if the caller should try opening the account again
private async bool account_database_error_async(Geary.Account account) {
bool retry = true;
// give the user two options: reset the Account local store, or exit Geary. A third
// could be done to leave the Account in an unopened state, but we don't currently
// have provisions for that.
QuestionDialog dialog = new QuestionDialog(main_window,
_("Unable to open the database for %s").printf(account.information.id),
_("There was an error opening the local mail database for this account. This is possibly due to corruption of the database file in this directory:\n\n%s\n\nGeary can rebuild the database and re-synchronize with the server or exit.\n\nRebuilding the database will destroy all local email and its attachments. <b>The mail on the your server will not be affected.</b>")
.printf(account.information.data_dir.get_path()),
_("_Rebuild"), _("E_xit"));
dialog.use_secondary_markup(true);
switch (dialog.run()) {
case Gtk.ResponseType.OK:
// don't use Cancellable because we don't want to interrupt this process
try {
yield account.rebuild_async();
} catch (Error err) {
ErrorDialog errdialog = new ErrorDialog(main_window,
_("Unable to rebuild database for \"%s\"").printf(account.information.id),
_("Error during rebuild:\n\n%s").printf(err.message));
errdialog.run();
retry = false;
}
break;
default:
retry = false;
break;
}
if (!retry)
this.application.exit(1);
return retry;
}
private async void account_database_perms_async(Geary.Account account) {
// some other problem opening the account ... as with other flow path, can't run
// Geary today with an account in unopened state, so have to exit
ErrorDialog dialog = new ErrorDialog(main_window,
_("Unable to open local mailbox for %s").printf(account.information.id),
_("There was an error opening the local mail database for this account. This is possibly due to a file permissions problem.\n\nPlease check that you have read/write permissions for all files in this directory:\n\n%s")
.printf(account.information.data_dir.get_path()));
dialog.run();
this.application.exit(1);
}
private async void account_database_version_async(Geary.Account account) {
ErrorDialog dialog = new ErrorDialog(main_window,
_("Unable to open local mailbox for %s").printf(account.information.id),
_("The version number of the local mail database is formatted for a newer version of Geary. Unfortunately, the database cannot be \"rolled back\" to work with this version of Geary.\n\nPlease install the latest version of Geary and try again."));
dialog.run();
this.application.exit(1);
}
private async void account_general_error_async(Geary.Account account) {
// some other problem opening the account ... as with other flow path, can't run
// Geary today with an account in unopened state, so have to exit
ErrorDialog dialog = new ErrorDialog(main_window,
_("Unable to open local mailbox for %s").printf(account.information.id),
_("There was an error opening the local account. This is probably due to connectivity issues.\n\nPlease check your network connection and restart Geary."));
dialog.run();
this.application.exit(1);
}
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
public async void disconnect_account_async(Geary.Account account, Cancellable? cancellable = null) {
cancel_inbox(account);
2013-05-14 11:52:02 -07:00
previous_non_search_folder = null;
main_window.search_bar.set_search_text(""); // Reset search.
if (current_account == account) {
cancel_folder();
switch_to_first_inbox(); // Switch folder.
}
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
account.folders_available_unavailable.disconnect(on_folders_available_unavailable);
account.sending_monitor.start.disconnect(on_sending_started);
account.sending_monitor.finish.disconnect(on_sending_finished);
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
main_window.folder_list.remove_account(account);
if (inboxes.has_key(account)) {
try {
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
yield inboxes.get(account).close_async(cancellable);
} catch (Error close_inbox_err) {
debug("Unable to close monitored inbox: %s", close_inbox_err.message);
}
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
inboxes.unset(account);
}
try {
yield account.close_async(cancellable);
} catch (Error close_err) {
debug("Unable to close account %s: %s", account.to_string(), close_err.message);
}
inbox_cancellables.unset(account);
email_stores.unset(account);
// If there are no accounts available, exit. (This can happen if the user declines to
// enter a password on their account.)
try {
if (get_num_open_accounts() == 0)
this.application.exit();
} catch (Error e) {
message("Error enumerating accounts: %s", e.message);
}
}
2013-07-08 14:22:23 -07:00
/**
* Returns true if we've attempted to open all accounts at this point.
*/
private bool did_attempt_open_all_accounts() {
try {
foreach (Geary.AccountInformation info in Geary.Engine.instance.get_accounts().values) {
Geary.Account a = Geary.Engine.instance.get_account_instance(info);
if (a.get_data<bool?>(PROP_ATTEMPT_OPEN_ACCOUNT) == null)
return false;
}
} catch(Error e) {
error("Could not open accounts: %s", e.message);
}
return true;
}
/**
* Displays the main window if we're ready. Otherwise does nothing.
*/
private void display_main_window_if_ready() {
if (did_attempt_open_all_accounts() && !upgrade_dialog.visible &&
!cancellable_open_account.is_cancelled() && !Args.hidden_startup)
2013-07-08 14:22:23 -07:00
main_window.show_all();
}
2013-06-07 16:23:45 -07:00
/**
* Returns the number of accounts that exist in Geary. Note that not all accounts may be
* open. Zero is returned on an error.
*/
public int get_num_accounts() {
try {
return Geary.Engine.instance.get_accounts().size;
} catch (Error e) {
debug("Error getting number of accounts: %s", e.message);
}
return 0; // on error
}
// Returns the number of open accounts.
private int get_num_open_accounts() throws Error {
int num = 0;
foreach (Geary.AccountInformation info in Geary.Engine.instance.get_accounts().values) {
Geary.Account a = Geary.Engine.instance.get_account_instance(info);
if (a.is_open())
num++;
}
return num;
}
// Update widgets and such to match capabilities of the current folder ... sensitivity is handled
// by other utility methods
private void update_ui() {
2013-02-22 17:54:05 -08:00
update_tooltips();
main_window.main_toolbar.update_trash_button(
current_folder_supports_trash() ||
!(current_folder is Geary.FolderSupport.Remove)
);
}
private void on_folder_selected(Geary.Folder? folder) {
debug("Folder %s selected", folder != null ? folder.to_string() : "(null)");
if (folder == null) {
this.current_folder = null;
main_window.conversation_list_view.set_model(null);
main_window.main_toolbar.folder = null;
2013-06-07 16:23:45 -07:00
folder_selected(null);
} else if (folder != this.current_folder) {
this.main_window.conversation_viewer.show_loading();
this.application.get_action(
ACTION_FIND_IN_CONVERSATION
).set_sensitive(false);
enable_message_buttons(false);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
// To prevent the user from selecting folders too quickly,
// we prevent additional selection changes to occur until
// after a timeout has expired from the last one
int64 now = get_monotonic_time();
int64 diff = now - this.next_folder_select_allowed_usec;
if (diff < SELECT_FOLDER_TIMEOUT_USEC) {
// only start timeout if another timeout is not
// running ... this means the user can click madly and
// will see the last clicked-on folder 100ms after the
// first one was clicked on
if (this.select_folder_timeout_id == 0) {
this.select_folder_timeout_id = Timeout.add(
(uint) (diff / 1000),
() => {
this.select_folder_timeout_id = 0;
this.next_folder_select_allowed_usec = 0;
if (folder != this.current_folder) {
do_select_folder.begin(
folder, on_select_folder_completed
);
}
return false;
});
}
} else {
do_select_folder.begin(folder, on_select_folder_completed);
this.next_folder_select_allowed_usec =
now + SELECT_FOLDER_TIMEOUT_USEC;
}
}
}
private async void do_select_folder(Geary.Folder folder) throws Error {
debug("Switching to %s...", folder.to_string());
closed_folder();
// This function is not reentrant. It should be, because it can be
// called reentrant-ly if you select folders quickly enough. This
// mutex lock is a bandaid solution to make the function safe to
// reenter.
int mutex_token = yield select_folder_mutex.claim_async(cancellable_folder);
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
bool current_is_inbox = inboxes.values.contains(current_folder);
Cancellable? conversation_cancellable = (current_is_inbox ?
inbox_cancellables.get(folder.account) : cancellable_folder);
// clear Revokable, as Undo is only available while a folder is selected
save_revokable(null, null);
// stop monitoring for conversations and close the folder
if (current_conversations != null) {
yield current_conversations.stop_monitoring_async(null);
current_conversations = null;
}
// re-enable copy/move to the last selected folder
if (current_folder != null) {
main_window.main_toolbar.copy_folder_menu.enable_disable_folder(current_folder, true);
main_window.main_toolbar.move_folder_menu.enable_disable_folder(current_folder, true);
}
current_folder = folder;
if (current_account != folder.account) {
current_account = folder.account;
2013-06-07 16:23:45 -07:00
account_selected(current_account);
// If we were waiting for an account to be selected before issuing mailtos, do that now.
if (pending_mailtos.size > 0) {
foreach(string mailto in pending_mailtos)
compose_mailto(mailto);
pending_mailtos.clear();
}
}
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
2013-06-07 16:23:45 -07:00
folder_selected(current_folder);
2013-05-14 11:52:02 -07:00
if (!(current_folder is Geary.SearchFolder))
previous_non_search_folder = current_folder;
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
main_window.main_toolbar.copy_folder_menu.clear();
main_window.main_toolbar.move_folder_menu.clear();
foreach(Geary.Folder f in current_folder.account.list_folders()) {
main_window.main_toolbar.copy_folder_menu.add_folder(f);
main_window.main_toolbar.move_folder_menu.add_folder(f);
}
// disable copy/move to the new folder
if (current_folder != null) {
main_window.main_toolbar.copy_folder_menu.enable_disable_folder(current_folder, false);
main_window.main_toolbar.move_folder_menu.enable_disable_folder(current_folder, false);
}
update_ui();
current_conversations = new Geary.App.ConversationMonitor(current_folder, Geary.Folder.OpenFlags.NO_DELAY,
ConversationListStore.REQUIRED_FIELDS, MIN_CONVERSATION_COUNT);
if (inboxes.values.contains(current_folder)) {
// Inbox selected, clear new messages if visible
clear_new_messages("do_select_folder (inbox)", null);
}
current_conversations.scan_error.connect(on_scan_error);
current_conversations.seed_completed.connect(on_seed_completed);
current_conversations.seed_completed.connect(on_conversation_count_changed);
current_conversations.scan_completed.connect(on_conversation_count_changed);
current_conversations.conversations_added.connect(on_conversation_count_changed);
current_conversations.conversations_removed.connect(on_conversation_count_changed);
if (!current_conversations.is_monitoring)
yield current_conversations.start_monitoring_async(conversation_cancellable);
select_folder_mutex.release(ref mutex_token);
debug("Switched to %s", folder.to_string());
}
private void on_scan_error(Error err) {
2013-07-11 12:50:19 -07:00
debug("Scan error: %s", err.message);
}
private void on_seed_completed() {
// Done scanning. Check if we have enough messages to fill the conversation list; if not,
// trigger a load_more();
if (!main_window.conversation_list_has_scrollbar()) {
debug("Not enough messages, loading more for folder %s", current_folder.to_string());
on_load_more();
}
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
private void on_conversation_count_changed() {
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
if (this.current_conversations != null) {
int count = this.current_conversations.get_conversation_count();
if (count == 0) {
// Let the user know if there's no available conversations
if (this.current_folder is Geary.SearchFolder) {
this.main_window.conversation_viewer.show_empty_search();
} else {
this.main_window.conversation_viewer.show_empty_folder();
}
enable_message_buttons(false);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
}
conversation_count_changed(count);
}
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
private void on_libnotify_invoked(Geary.Folder? folder, Geary.Email? email) {
new_messages_monitor.clear_all_new_messages();
if (folder == null || email == null || !can_switch_conversation_view())
return;
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
main_window.folder_list.select_folder(folder);
Geary.App.Conversation? conversation = current_conversations.get_conversation_for_email(email.id);
if (conversation != null)
main_window.conversation_list_view.select_conversation(conversation);
}
private void on_indicator_activated_application(uint32 timestamp) {
// When the app is started hidden, show_all() never gets
// called, do so here to prevent an empty window appearing.
main_window.show_all();
main_window.present_with_time(timestamp);
}
private void on_indicator_activated_composer(uint32 timestamp) {
on_indicator_activated_application(timestamp);
on_new_message();
}
private void on_indicator_activated_inbox(Geary.Folder folder, uint32 timestamp) {
on_indicator_activated_application(timestamp);
main_window.folder_list.select_folder(folder);
}
private void on_load_more() {
debug("on_load_more");
current_conversations.min_window_count += MIN_CONVERSATION_COUNT;
}
private void on_select_folder_completed(Object? source, AsyncResult result) {
try {
do_select_folder.end(result);
} catch (Error err) {
debug("Unable to select folder: %s", err.message);
}
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
private void on_conversations_selected(Gee.Set<Geary.App.Conversation> selected) {
this.selected_conversations = selected;
this.application.get_action(
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
ACTION_FIND_IN_CONVERSATION
).set_sensitive(false);
ConversationViewer viewer = this.main_window.conversation_viewer;
if (this.current_folder != null && !viewer.is_composer_visible) {
switch(selected.size) {
case 0:
enable_message_buttons(false);
viewer.show_none_selected();
break;
case 1:
// Cancel existing avatar loads before loading new
// convo since that will start loading more avatars
viewer.load_conversation.begin(
Geary.Collection.get_first(selected),
this.current_folder,
(obj, ret) => {
try {
viewer.load_conversation.end(ret);
enable_message_buttons(true);
this.application.get_action(
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
ACTION_FIND_IN_CONVERSATION
).set_sensitive(true);
} catch (Error err) {
debug("Unable to load conversation: %s",
err.message);
}
}
);
break;
default:
enable_multiple_message_buttons();
viewer.show_multiple_selected();
break;
}
}
}
private void on_conversation_activated(Geary.App.Conversation activated) {
2013-07-19 15:44:20 -07:00
// Currently activating a conversation is only available for drafts folders.
if (current_folder == null || current_folder.special_folder_type !=
Geary.SpecialFolderType.DRAFTS)
return;
2013-07-19 15:44:20 -07:00
// TODO: Determine how to map between conversations and drafts correctly.
Geary.Email draft = activated.get_latest_recv_email(
Geary.App.Conversation.Location.IN_FOLDER
);
create_compose_widget(
ComposerWidget.ComposeType.NEW_MESSAGE, draft, null, null, true
);
2013-07-19 15:44:20 -07:00
}
private void on_special_folder_type_changed(Geary.Folder folder, Geary.SpecialFolderType old_type,
Geary.SpecialFolderType new_type) {
main_window.folder_list.remove_folder(folder);
main_window.folder_list.add_folder(folder);
}
private void on_engine_opened() {
// Locate the first account so we can select its inbox when available.
try {
Gee.ArrayList<Geary.AccountInformation> all_accounts =
new Gee.ArrayList<Geary.AccountInformation>();
all_accounts.add_all(Geary.Engine.instance.get_accounts().values);
if (all_accounts.size == 0) {
debug("No accounts found.");
return;
}
2013-04-24 12:22:32 -07:00
all_accounts.sort(Geary.AccountInformation.compare_ascending);
account_to_select = Geary.Engine.instance.get_account_instance(all_accounts.get(0));
} catch (Error e) {
debug("Error selecting first inbox: %s", e.message);
}
}
// Meant to be called inside the available block of on_folders_available_unavailable,
// after we've located the first account.
private Geary.Folder? get_initial_selection_folder(Geary.Folder folder_being_added) {
if (folder_being_added.account == account_to_select &&
!main_window.folder_list.is_any_selected() && inboxes.has_key(account_to_select)) {
return inboxes.get(account_to_select);
} else if (account_to_select == null) {
// This is the first account being added, so select the inbox.
return inboxes.get(folder_being_added.account);
}
return null;
}
private void on_folders_available_unavailable(Gee.Collection<Geary.Folder>? available,
Gee.Collection<Geary.Folder>? unavailable) {
if (available != null && available.size > 0) {
foreach (Geary.Folder folder in available) {
main_window.folder_list.add_folder(folder);
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
if (folder.account == current_account) {
if (!main_window.main_toolbar.copy_folder_menu.has_folder(folder))
main_window.main_toolbar.copy_folder_menu.add_folder(folder);
if (!main_window.main_toolbar.move_folder_menu.has_folder(folder))
main_window.main_toolbar.move_folder_menu.add_folder(folder);
}
// monitor the Inbox for notifications
if (folder.special_folder_type == Geary.SpecialFolderType.INBOX &&
Load and display multiple accounts; fix #6230 Lots has been changed here. See the bug report <http://redmine.yorba.org/issues/6230> for some of the discussion about it. This also fixes #6274. I'll cut the list of revisions off after a while, because this branch has been outstanding for a couple weeks. Squashed commit of the following: commit ae505d89e87e63e0d8949bfd901913706a9d3b73 Merge: 81ef002 e18bef9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:16:17 2013 -0800 Merge branch 'master' into multiple-accounts commit 81ef002f5ff486b9c28f5663a0ba1e7392b8489c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 15:15:51 2013 -0800 Fix final round of code review commit 6935b1e7892b9b356bf5006b89e0b2a4e6a8ad16 Merge: c9ed434 a9dc52b Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:45:46 2013 -0800 Merge branch 'master' into multiple-accounts commit c9ed434fe936e6aed735baef222ae615364c2513 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:31:02 2013 -0800 Simplify folder comparator commit 28ac020cfd9135c6eb4ed05574c82b92f99c4a40 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 14:06:55 2013 -0800 Bump up declaration to conform to guidelines commit 0a8167bdaebd5fac1c3ca791de5f2cc233c13cb9 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 13:54:03 2013 -0800 Rename back to list_*folders commit 31457f60298052bdddba8e426db27f93d7c72529 Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 31 12:36:15 2013 -0800 Fix spacing, brevity issues commit ecd30c203d80c21c1ca1234b8911b57efcb68294 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:56:29 2013 -0800 Fix nits before review commit 85b51d71e83115991cd9a54d491b4d45b71f2f9b Merge: b29abce d538bf0 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:46:19 2013 -0800 Merge branch 'master' into multiple-accounts commit b29abceeaea84f226ab9bcd22266a511691d8005 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 17:22:28 2013 -0800 Fix notifications commit c26d975fb0859d807ddb7f7c10632605c3b6fb1c Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 13:01:03 2013 -0800 Only show current acct. folders in copy/move menus commit 9a5b57db1229a079f11f518c53f5762a3670b83f Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:48:05 2013 -0800 Fix issue where wrong mail would show in folders commit 3b05d18843584c2aff7472708eea30ce24068043 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:18:38 2013 -0800 Fix ordering of folders in side bar commit b228967b6a74c16698d593e53e65d66c69ffb974 Author: Charles Lindsay <chaz@yorba.org> Date: Wed Jan 30 11:07:32 2013 -0800 Add icon to accounts in sidebar commit dd05d2c987a46f0b6699d743c339297e06829e4f Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 19:04:52 2013 -0800 Fix Labels icon commit b5254fe8f6ef37df48d41167d0f52f3cd88d1966 Author: Charles Lindsay <chaz@yorba.org> Date: Tue Jan 29 18:43:45 2013 -0800 Initial stab at new FolderList; fix compile errors commit ff591810ee4312acce208dfa36d993069bc4c7d2 Merge: 2b9dbb9 ff5f9fa Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:42:34 2013 -0800 Merge branch 'master' into multiple-accounts commit 2b9dbb9b6963b1d52b2b90300bcea277b01d2094 Merge: 7583241 fcfb460 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 17:21:49 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-controller.vala commit 75832412cc806c956848e32ef20052af36d4f64d Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 16:37:15 2013 -0800 Fix IMAP sess. mgr. to recover from bad passwords commit 8868b4be5c3f5c97246d35c6170531c6f543abe1 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 12:06:21 2013 -0800 Typo commit 3f909054502d31ca48e11f7948fd22118afe7514 Author: Charles Lindsay <chaz@yorba.org> Date: Mon Jan 28 10:54:51 2013 -0800 Clean up interface a little commit 3bfb526fe8801f8234127944be8594a960ccf7e7 Merge: 5e84e93 e971275 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:23:52 2013 -0800 Merge branch 'master' into multiple-accounts Conflicts: src/client/geary-application.vala src/engine/api/geary-engine.vala commit 5e84e9375a655567a3bc4eb7ebaacab2d218be40 Merge: 35cc46b 9167aeb Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:17:00 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/engine/api/geary-engine.vala commit 9167aeb56be6789d49a3e7cdba2a21d2b015e40d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 16:11:20 2013 -0800 Fix for code guidelines commit 35cc46bc99f44f1597c609bfeaa72dd503333a17 Merge: 9675f47 7612a7d Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:44:18 2013 -0800 Merge branch 'pluggable-auth' into multiple-accounts Conflicts: src/client/geary-application.vala commit 7612a7ddc3df14ef207b9e74ee32fa23710e1ce9 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 15:26:48 2013 -0800 Fix code review issues commit 46635544c98df7a8b6c76f028715814907274389 Merge: 30b611e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:54:03 2013 -0800 Merge branch 'master' into pluggable-auth commit 9675f473e77d0d581cf73a33012981e6a4f44943 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:53:18 2013 -0800 Try to make Folder know about its Account commit 5d9af43e53199a616490cf6ff98bd3c613b4e5f2 Merge: 335480e 6de36ae Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:12:21 2013 -0800 Merge branch 'master' into multiple-accounts commit 335480e2dd0261c8fb82f1c6296f5b8c76f3ac02 Author: Charles Lindsay <chaz@yorba.org> Date: Fri Jan 25 12:11:18 2013 -0800 Work on multiple accounts; fix compilation errors commit 808e65d55798e3f08b4c70992718cc11befbb45c Author: Charles Lindsay <chaz@yorba.org> Date: Thu Jan 24 19:28:12 2013 -0800 Fix application logic for multiple accounts You get the idea.
2013-01-31 15:17:44 -08:00
!inboxes.has_key(folder.account)) {
inboxes.set(folder.account, folder);
Geary.Folder? select_folder = get_initial_selection_folder(folder);
if (select_folder != null) {
// First we try to select the Inboxes branch inbox if
// it's there, falling back to the main folder list.
if (!main_window.folder_list.select_inbox(select_folder.account))
main_window.folder_list.select_folder(select_folder);
}
folder.open_async.begin(Geary.Folder.OpenFlags.NONE, inbox_cancellables.get(folder.account));
new_messages_monitor.add_folder(folder, inbox_cancellables.get(folder.account));
}
folder.special_folder_type_changed.connect(on_special_folder_type_changed);
}
}
if (unavailable != null) {
foreach (Geary.Folder folder in unavailable) {
main_window.folder_list.remove_folder(folder);
if (folder.account == current_account) {
if (main_window.main_toolbar.copy_folder_menu.has_folder(folder))
main_window.main_toolbar.copy_folder_menu.remove_folder(folder);
if (main_window.main_toolbar.move_folder_menu.has_folder(folder))
main_window.main_toolbar.move_folder_menu.remove_folder(folder);
}
if (folder.special_folder_type == Geary.SpecialFolderType.INBOX &&
inboxes.has_key(folder.account)) {
inboxes.unset(folder.account);
new_messages_monitor.remove_folder(folder);
}
folder.special_folder_type_changed.disconnect(on_special_folder_type_changed);
}
}
}
private void cancel_folder() {
Cancellable old_cancellable = cancellable_folder;
cancellable_folder = new Cancellable();
old_cancellable.cancel();
}
// Like cancel_folder() but doesn't cancel outstanding operations, allowing them to complete
// in the background
private void closed_folder() {
cancellable_folder = new Cancellable();
}
private void cancel_inbox(Geary.Account account) {
if (!inbox_cancellables.has_key(account)) {
debug("Unable to cancel inbox operation for %s", account.to_string());
return;
}
Cancellable old_cancellable = inbox_cancellables.get(account);
inbox_cancellables.set(account, new Cancellable());
old_cancellable.cancel();
}
private void cancel_search() {
Cancellable old_cancellable = this.cancellable_search;
this.cancellable_search = new Cancellable();
old_cancellable.cancel();
}
private void cancel_context_dependent_buttons() {
Cancellable old_cancellable = cancellable_context_dependent_buttons;
cancellable_context_dependent_buttons = new Cancellable();
old_cancellable.cancel();
}
// We need to include the second parameter, or valac doesn't recognize the function as matching
// GearyApplication.exiting's signature.
private bool on_application_exiting(GearyApplication sender, bool panicked) {
if (close_composition_windows())
return true;
return sender.cancel_exit();
}
private void on_shift_key(bool pressed) {
if (main_window != null && main_window.main_toolbar != null
&& current_account != null && current_folder != null) {
main_window.main_toolbar.update_trash_button(
(!pressed && current_folder_supports_trash()) || !(current_folder is Geary.FolderSupport.Remove));
}
}
// this signal does not necessarily indicate that the application previously didn't have
// focus and now it does
private void on_has_toplevel_focus() {
clear_new_messages("on_has_toplevel_focus", null);
}
// latest_sent_only uses Email's Date: field, which corresponds to how they're sorted in the
// ConversationViewer
private Gee.ArrayList<Geary.EmailIdentifier> get_conversation_email_ids(
Geary.App.Conversation conversation, bool latest_sent_only,
Gee.ArrayList<Geary.EmailIdentifier> add_to) {
if (latest_sent_only) {
Geary.Email? latest = conversation.get_latest_sent_email(
Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
if (latest != null)
add_to.add(latest.id);
} else {
add_to.add_all(conversation.get_email_ids());
}
return add_to;
}
private Gee.Collection<Geary.EmailIdentifier> get_conversation_collection_email_ids(
Gee.Collection<Geary.App.Conversation> conversations, bool latest_sent_only) {
Gee.ArrayList<Geary.EmailIdentifier> ret = new Gee.ArrayList<Geary.EmailIdentifier>();
foreach(Geary.App.Conversation c in conversations)
get_conversation_email_ids(c, latest_sent_only, ret);
return ret;
}
private Gee.ArrayList<Geary.EmailIdentifier> get_selected_email_ids(bool latest_sent_only) {
Gee.ArrayList<Geary.EmailIdentifier> ids = new Gee.ArrayList<Geary.EmailIdentifier>();
foreach (Geary.App.Conversation conversation in selected_conversations)
get_conversation_email_ids(conversation, latest_sent_only, ids);
return ids;
}
private void mark_email(Gee.Collection<Geary.EmailIdentifier> ids,
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove) {
if (ids.size > 0) {
email_stores.get(current_folder.account).mark_email_async.begin(
ids, flags_to_add, flags_to_remove, cancellable_folder);
}
}
private void on_show_mark_menu() {
bool unread_selected = false;
bool read_selected = false;
bool starred_selected = false;
bool unstarred_selected = false;
foreach (Geary.App.Conversation conversation in selected_conversations) {
if (conversation.is_unread())
unread_selected = true;
// Only check the messages that "Mark as Unread" would mark, so we
// don't add the menu option and have it not do anything.
//
// Sort by Date: field to correspond with ConversationViewer ordering
Geary.Email? latest = conversation.get_latest_sent_email(
Geary.App.Conversation.Location.IN_FOLDER_OUT_OF_FOLDER);
if (latest != null && latest.email_flags != null
&& !latest.email_flags.contains(Geary.EmailFlags.UNREAD))
read_selected = true;
if (conversation.is_flagged()) {
starred_selected = true;
} else {
unstarred_selected = true;
}
}
var actions = this.application.actions;
actions.get_action(ACTION_MARK_AS_READ).set_visible(unread_selected);
actions.get_action(ACTION_MARK_AS_UNREAD).set_visible(read_selected);
actions.get_action(ACTION_MARK_AS_STARRED).set_visible(unstarred_selected);
actions.get_action(ACTION_MARK_AS_UNSTARRED).set_visible(starred_selected);
2013-02-21 14:57:59 -08:00
if (current_folder.special_folder_type != Geary.SpecialFolderType.DRAFTS &&
current_folder.special_folder_type != Geary.SpecialFolderType.OUTBOX) {
if (current_folder.special_folder_type == Geary.SpecialFolderType.SPAM) {
2013-02-21 14:57:59 -08:00
// We're in the spam folder.
actions.get_action(ACTION_MARK_AS_SPAM).sensitive = true;
actions.get_action(ACTION_MARK_AS_SPAM).label = MARK_AS_NOT_SPAM_LABEL;
} else {
// We're not in the spam folder, but we are in a folder that allows mark-as-spam.
actions.get_action(ACTION_MARK_AS_SPAM).sensitive = true;
actions.get_action(ACTION_MARK_AS_SPAM).label = MARK_AS_SPAM_LABEL;
}
} else {
// We're in Drafts/Outbox, so gray-out the option.
2013-02-21 14:57:59 -08:00
actions.get_action(ACTION_MARK_AS_SPAM).sensitive = false;
actions.get_action(ACTION_MARK_AS_SPAM).label = MARK_AS_SPAM_LABEL;
}
}
private void on_visible_conversations_changed(Gee.Set<Geary.App.Conversation> visible) {
clear_new_messages("on_visible_conversations_changed", visible);
}
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
// and don't display if main window has top-level focus
return folder != current_folder
|| main_window.conversation_list_view.vadjustment.value != 0.0
|| !main_window.has_toplevel_focus;
}
// Clears messages if conditions are true: anything in should_notify_new_messages() is
// false and the supplied visible messages are visible in the conversation list view
private void clear_new_messages(string caller, Gee.Set<Geary.App.Conversation>? supplied) {
if (current_folder == null || !new_messages_monitor.get_folders().contains(current_folder)
|| should_notify_new_messages(current_folder))
return;
Gee.Set<Geary.App.Conversation> visible =
supplied ?? main_window.conversation_list_view.get_visible_conversations();
foreach (Geary.App.Conversation conversation in visible) {
if (new_messages_monitor.are_any_new_messages(current_folder, conversation.get_email_ids())) {
debug("Clearing new messages: %s", caller);
new_messages_monitor.clear_new_messages(current_folder);
break;
}
}
}
private void on_mark_conversations(Gee.Collection<Geary.App.Conversation> conversations,
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove,
bool latest_only = false) {
mark_email(get_conversation_collection_email_ids(conversations, latest_only),
flags_to_add, flags_to_remove);
}
Reenable displaying sub-messages. Geary currently displays RFC 822 attachments inline, below the email's primary message body, using the same HTML chrome for the headers and email body as for the primary body. Taking the same approach but using GTK+ widgets meant splitting ConversationMessage up into a ConversationEmail class that manages the UI for displaying an email in its entirety, and a ConversationMessage to manage the only header widgets and webview for displaying an individual RFC 822 message, usable for both the primary body and any sub-messages. Thus, this is a big change. One behavioural change is that each sub-message with remote images now requires individual approval, rather than being dependant on the containing message's sender and/or approval. This prevents some attacks e.g. a trusted sender forwarding a spam/malware message, but does not prevent it if the message is forwarded inline, obviosuly. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): New class for managing the UI for an overall email message. This replaces the old ConversationMessage and contains much of it's code and widgets - anything from that class which does not directly support displaying headers or a message body. * src/client/conversation-viewer/conversation-message.vala: (ConversationMessage): Same class as before, but now with its scope narrowed to only display message headers and body. The draft infobar remains here rather than being put ConversationEmail where it belongs since it's bit of a pain to insert in the right place and doesn't really hurt. (::email): Moved this property and any code that depends on it to ConversationEmail. (::always_load_remote_images): New property passed in via the ctor, allowing one dependency on the old ::email property to be removed. (::inlined_content_ids): Moved to ConversationEmail, since that is the class that keeps track of attachments to display. Add the signal attachment_displayed_inline to allow ConversationEmail to be notified of inlined attachments instead. (::flag_remote_images, ::remember_remote_images): New signals to notify ConversationEmail that the user has flagged this message or the message's sender for loading remote images. This is passed through since in the former's case we may need to set flags on the email itself, the latter because it is one less use of the contact_store property, which should be removed from this class at some point. * src/client/conversation-viewer/conversation-viewer.vala: Chase API changes from the above. In general, replace use of the term "message" with "email" since this class is now mostly dealing with ConversationEmail instances, rather than ConversationMessage instances. (ConversationViewer::check_mark_read): Only consider the ConversationEmail's primary message body when checking for visibility rather than that and any submessages to keep things simple. (ConversationViewer::show_message, ::hide_message): Renamed to expand_email/collapse_email respectively since we don't ever actually hide it. Carry that change on to same methods on ConversationEmail. * src/engine/rfc822/rfc822-message.vala (Geary.RFC822.Message): Add get_primary_originator(), almost vermatim from Geary.Email, to support determining the sender for remembering remote message loading for senders of sub-emails. * src/client/components/main-window.vala (MainWindow::set_styling): Fix background transition for collapsed emails. * src/client/application/geary-controller.vala: Chase API name changes. * src/CMakeLists.txt: Include new ConversationEmail source file. * ui/conversation-email.ui: New UI for ConversationEmail, move the email action box, attachments box amd sub-messages box here from conversation-message.ui. * ui/CMakeLists.txt: Include new UI in compiled resources. * po/POTFILES.in: Add new UI for transation.
2016-04-19 16:52:34 +10:00
private void on_conversation_viewer_mark_emails(Gee.Collection<Geary.EmailIdentifier> emails,
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove) {
mark_email(emails, flags_to_add, flags_to_remove);
}
private void on_mark_as_read() {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.UNREAD);
Gee.ArrayList<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
mark_email(ids, null, flags);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox? list =
main_window.conversation_viewer.current_list;
if (list != null) {
foreach (Geary.EmailIdentifier id in ids)
list.mark_manual_read(id);
}
}
private void on_mark_as_unread() {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.UNREAD);
Gee.ArrayList<Geary.EmailIdentifier> ids = get_selected_email_ids(true);
mark_email(ids, flags, null);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox? list =
main_window.conversation_viewer.current_list;
if (list != null) {
foreach (Geary.EmailIdentifier id in ids)
list.mark_manual_unread(id);
}
}
private void on_mark_as_starred() {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.FLAGGED);
mark_email(get_selected_email_ids(true), flags, null);
}
private void on_mark_as_unstarred() {
Geary.EmailFlags flags = new Geary.EmailFlags();
flags.add(Geary.EmailFlags.FLAGGED);
mark_email(get_selected_email_ids(false), null, flags);
}
private async void mark_as_spam_async(Cancellable? cancellable) {
2013-02-21 14:57:59 -08:00
Geary.Folder? destination_folder = null;
if (current_folder.special_folder_type != Geary.SpecialFolderType.SPAM) {
2013-02-21 14:57:59 -08:00
// Move to spam folder.
try {
destination_folder = yield current_account.get_required_special_folder_async(
Geary.SpecialFolderType.SPAM, cancellable);
2013-02-21 14:57:59 -08:00
} catch (Error e) {
debug("Error getting spam folder: %s", e.message);
}
} else {
// Move out of spam folder, back to inbox.
try {
destination_folder = current_account.get_special_folder(Geary.SpecialFolderType.INBOX);
} catch (Error e) {
debug("Error getting inbox folder: %s", e.message);
}
}
if (destination_folder != null)
on_move_conversation(destination_folder);
}
private void on_mark_as_spam() {
mark_as_spam_async.begin(null);
}
private void copy_email(Gee.Collection<Geary.EmailIdentifier> ids,
Geary.FolderPath destination) {
if (ids.size > 0) {
email_stores.get(current_folder.account).copy_email_async.begin(
ids, destination, cancellable_folder);
}
}
private void on_copy_conversation(Geary.Folder destination) {
copy_email(get_selected_email_ids(false), destination.path);
}
2013-07-11 12:50:19 -07:00
private void on_move_conversation(Geary.Folder destination) {
// Nothing to do if nothing selected.
if (selected_conversations == null || selected_conversations.size == 0)
return;
Gee.List<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
if (ids.size == 0)
return;
this.main_window.conversation_list_view.set_changing_selection(true);
Geary.FolderSupport.Move? supports_move = current_folder as Geary.FolderSupport.Move;
if (supports_move != null)
move_conversation_async.begin(
supports_move, ids, destination.path, cancellable_folder,
(obj, ret) => {
move_conversation_async.end(ret);
this.main_window.conversation_list_view.set_changing_selection(false);
});
}
private async void move_conversation_async(Geary.FolderSupport.Move source_folder,
Gee.List<Geary.EmailIdentifier> ids, Geary.FolderPath destination, Cancellable? cancellable) {
try {
save_revokable(yield source_folder.move_email_async(ids, destination, cancellable),
_("Undo move (Ctrl+Z)"));
} catch (Error err) {
debug("%s: Unable to move %d emails: %s", source_folder.to_string(), ids.size,
err.message);
}
}
private void on_attachments_activated(Gee.Collection<Geary.Attachment> attachments) {
if (this.application.config.ask_open_attachment) {
QuestionDialog ask_to_open = new QuestionDialog.with_checkbox(main_window,
_("Are you sure you want to open these attachments?"),
_("Attachments may cause damage to your system if opened. Only open files from trusted sources."),
Stock._OPEN_BUTTON, Stock._CANCEL, _("Don't _ask me again"), false);
if (ask_to_open.run() != Gtk.ResponseType.OK) {
return;
}
// only save checkbox state if OK was selected
this.application.config.ask_open_attachment = !ask_to_open.is_checked;
}
foreach (Geary.Attachment attachment in attachments) {
string gio_content_type = ContentType.from_mime_type(
attachment.content_type.get_mime_type()
);
AppInfo? app = null;
if (!ContentType.can_be_executable(gio_content_type) &&
!ContentType.is_unknown(gio_content_type)) {
app = AppInfo.get_default_for_type(gio_content_type, false);
}
if (app == null) {
string content_type = attachment.content_type.get_mime_type();
Gtk.AppChooserDialog app_chooser =
new Gtk.AppChooserDialog.for_content_type(
this.main_window,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.USE_HEADER_BAR,
content_type
);
if (app_chooser.run() == Gtk.ResponseType.OK) {
app = app_chooser.get_app_info();
}
app_chooser.hide();
}
if (app != null) {
List<File> files = new List<File>();
files.append(attachment.file);
try {
app.launch(files, null);
} catch (Error error) {
warning("Failed to launch %s: %s\n",
app.get_name(), error.message);
}
}
}
}
private bool do_overwrite_confirmation(File to_overwrite) {
string primary = _("A file named \"%s\" already exists. Do you want to replace it?").printf(
to_overwrite.get_basename());
string secondary = _("The file already exists in \"%s\". Replacing it will overwrite its contents.").printf(
to_overwrite.get_parent().get_basename());
ConfirmationDialog dialog = new ConfirmationDialog(main_window, primary, secondary, _("_Replace"), "destructive-action");
return (dialog.run() == Gtk.ResponseType.OK);
}
private Gtk.FileChooserConfirmation on_confirm_overwrite(Gtk.FileChooser chooser) {
// this is only called when choosing one file
return do_overwrite_confirmation(chooser.get_file()) ? Gtk.FileChooserConfirmation.ACCEPT_FILENAME
: Gtk.FileChooserConfirmation.SELECT_AGAIN;
}
private void on_save_attachments(Gee.Collection<Geary.Attachment> attachments) {
Gtk.FileChooserAction action = (attachments.size == 1)
? Gtk.FileChooserAction.SAVE
: Gtk.FileChooserAction.SELECT_FOLDER;
#if GTK_3_20
Gtk.FileChooserNative dialog = new Gtk.FileChooserNative(null, main_window, action,
Stock._SAVE, Stock._CANCEL);
#else
Gtk.FileChooserDialog dialog = new Gtk.FileChooserDialog(null, main_window, action,
Stock._CANCEL, Gtk.ResponseType.CANCEL, Stock._SAVE, Gtk.ResponseType.ACCEPT, null);
#endif
if (last_save_directory != null)
dialog.set_current_folder(last_save_directory.get_path());
if (attachments.size == 1) {
Gee.Iterator<Geary.Attachment> it = attachments.iterator();
it.next();
Geary.Attachment attachment = it.get();
dialog.set_current_name(attachment.file.get_basename());
dialog.set_do_overwrite_confirmation(true);
// use custom overwrite confirmation so it looks consistent whether one or many
// attachments are being saved
dialog.confirm_overwrite.connect(on_confirm_overwrite);
}
dialog.set_create_folders(true);
dialog.set_local_only(false);
bool accepted = (dialog.run() == Gtk.ResponseType.ACCEPT);
string? filename = dialog.get_filename();
dialog.destroy();
if (!accepted || Geary.String.is_empty(filename))
return;
File destination = File.new_for_path(filename);
// Proceeding, save this as last destination directory
last_save_directory = (attachments.size == 1) ? destination.get_parent() : destination;
debug("Saving attachments to %s", destination.get_path());
// Save each one, checking for overwrite only if multiple attachments are being written
foreach (Geary.Attachment attachment in attachments) {
File source_file = attachment.file;
File dest_file = (attachments.size == 1) ? destination : destination.get_child(attachment.file.get_basename());
if (attachments.size > 1 && dest_file.query_exists() && !do_overwrite_confirmation(dest_file))
return;
debug("Copying %s to %s...", source_file.get_path(), dest_file.get_path());
source_file.copy_async.begin(dest_file, FileCopyFlags.OVERWRITE, Priority.DEFAULT, null,
null, on_save_completed);
}
}
private void on_save_completed(Object? source, AsyncResult result) {
try {
((File) source).copy_async.end(result);
} catch (Error error) {
message("Failed to copy attachment %s to destination: %s", ((File) source).get_path(),
error.message);
}
}
private void on_save_buffer_to_file(string? filename, Geary.Memory.Buffer buffer) {
#if GTK_3_20
Gtk.FileChooserNative dialog = new Gtk.FileChooserNative(null, main_window, Gtk.FileChooserAction.SAVE,
Stock._SAVE, Stock._CANCEL);
#else
Gtk.FileChooserDialog dialog = new Gtk.FileChooserDialog(null, main_window, Gtk.FileChooserAction.SAVE,
Stock._CANCEL, Gtk.ResponseType.CANCEL, Stock._SAVE, Gtk.ResponseType.ACCEPT, null);
#endif
if (last_save_directory != null)
dialog.set_current_folder(last_save_directory.get_path());
if (!Geary.String.is_empty(filename))
dialog.set_current_name(filename);
dialog.set_do_overwrite_confirmation(true);
dialog.confirm_overwrite.connect(on_confirm_overwrite);
dialog.set_create_folders(true);
dialog.set_local_only(false);
bool accepted = (dialog.run() == Gtk.ResponseType.ACCEPT);
string? accepted_filename = dialog.get_filename();
dialog.destroy();
if (!accepted || Geary.String.is_empty(accepted_filename))
return;
File destination = File.new_for_path(accepted_filename);
// Proceeding, save this as last destination directory
last_save_directory = destination.get_parent();
debug("Saving buffer to %s", destination.get_path());
// Create the file where the image will be saved and get the output stream.
try {
FileOutputStream outs = destination.replace(null, false, FileCreateFlags.REPLACE_DESTINATION,
null);
outs.splice_async.begin(buffer.get_input_stream(),
OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET,
Priority.DEFAULT, null, on_save_buffer_to_file_completed);
} catch (Error err) {
message("Unable to save buffer to \"%s\": %s", filename, err.message);
}
}
private void on_save_buffer_to_file_completed(Object? source, AsyncResult result) {
try {
((FileOutputStream) source).splice_async.end(result);
} catch (Error err) {
message("Failed to save buffer to file: %s", err.message);
}
}
// Opens a link in an external browser.
private bool open_uri(string _link) {
string link = _link;
// Support web URLs that ommit the protocol.
if (!link.contains(":"))
link = "http://" + link;
bool ret = false;
try {
ret = Gtk.show_uri(main_window.get_screen(), link, Gdk.CURRENT_TIME);
} catch (Error err) {
debug("Unable to open URL. %s", err.message);
}
return ret;
}
private bool close_composition_windows() {
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
Gee.List<ComposerWidget> composers_to_destroy = new Gee.ArrayList<ComposerWidget>();
2013-08-08 18:47:23 -07:00
bool quit_cancelled = false;
// If there's composer windows open, give the user a chance to save or cancel.
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
foreach(ComposerWidget cw in composer_widgets) {
2013-08-08 18:47:23 -07:00
// Check if we should close the window immediately, or if we need to wait.
ComposerWidget.CloseStatus status = cw.should_close();
if (status == ComposerWidget.CloseStatus.PENDING_CLOSE) {
// Window is currently busy saving.
waiting_to_close.add(cw);
} else if (status == ComposerWidget.CloseStatus.CANCEL_CLOSE) {
// User cancelled operation.
quit_cancelled = true;
break;
} else if (status == ComposerWidget.CloseStatus.DO_CLOSE) {
// Hide any existing composer windows for the moment; actually deleting the windows
// will result in their removal from composer_windows, which could crash this loop.
composers_to_destroy.add(cw);
2014-05-15 15:53:31 -07:00
((ComposerContainer) cw.parent).vanish();
2013-08-08 18:47:23 -07:00
}
}
2013-08-08 18:47:23 -07:00
// Safely destroy windows.
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
foreach(ComposerWidget cw in composers_to_destroy)
((ComposerContainer) cw.parent).close_container();
2013-08-08 18:47:23 -07:00
// If we cancelled the quit we can bail here.
if (quit_cancelled) {
waiting_to_close.clear();
return false;
}
// If there's still windows saving, we can't exit just yet. Hide the main window and wait.
if (waiting_to_close.size > 0) {
main_window.hide();
2013-08-08 18:47:23 -07:00
return false;
}
// If we deleted all composer windows without the user cancelling, we can exit.
return true;
}
// View contains the email from whose menu this reply or forward
// was triggered. If null, this was triggered from the headerbar
// or shortcut.
private void create_reply_forward_widget(ComposerWidget.ComposeType compose_type,
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
owned ConversationEmail? email_view) {
if (email_view == null) {
ConversationListBox? list_view =
main_window.conversation_viewer.current_list;
if (list_view != null) {
email_view = list_view.get_reply_target();
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
}
}
string? quote = null;
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
if (email_view != null) {
quote = email_view.get_selection_for_quoting();
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
create_compose_widget(compose_type, email_view.email, quote);
}
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
private void create_compose_widget(ComposerWidget.ComposeType compose_type,
Geary.Email? referred = null, string? quote = null, string? mailto = null,
bool is_draft = false) {
create_compose_widget_async.begin(compose_type, referred, quote, mailto, is_draft);
2013-07-19 15:44:20 -07:00
}
/**
* Creates a composer widget. Depending on the arguments, this can be inline in the
* conversation or as a new window.
* @param compose_type - Whether it's a new message, a reply, a forwarded mail, ...
* @param referred - The mail of which we should copy the from/to/... addresses
* @param quote - The quote after the mail body
* @param mailto - A "mailto:"-link
* @param is_draft - Whether we're starting from a draft (true) or a new mail (false)
*/
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
private async void create_compose_widget_async(ComposerWidget.ComposeType compose_type,
Geary.Email? referred = null, string? quote = null, string? mailto = null,
bool is_draft = false) {
if (current_account == null)
return;
bool inline;
if (!should_create_new_composer(compose_type, referred, quote, is_draft, out inline))
return;
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
ComposerWidget widget;
if (mailto != null) {
widget = new ComposerWidget.from_mailto(current_account, mailto, application.config);
} else {
2013-07-19 15:44:20 -07:00
Geary.Email? full = null;
if (referred != null) {
try {
full = yield email_stores.get(current_folder.account).fetch_email_async(
referred.id, Geary.ComposedEmail.REQUIRED_REPLY_FIELDS,
Geary.Folder.ListFlags.NONE, cancellable_folder);
2013-07-19 15:44:20 -07:00
} catch (Error e) {
message("Could not load full message: %s", e.message);
2013-07-19 15:44:20 -07:00
}
}
widget = new ComposerWidget(current_account, compose_type, application.config, full, quote, is_draft);
if (is_draft) {
yield widget.restore_draft_state_async(current_account);
}
2013-07-19 15:44:20 -07:00
}
widget.show_all();
// We want to keep track of the open composer windows, so we can allow the user to cancel
// an exit without losing their data.
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
composer_widgets.add(widget);
debug(@"Creating composer of type $(widget.compose_type); $(composer_widgets.size) composers total");
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
widget.destroy.connect(on_composer_widget_destroy);
if (inline) {
if (widget.state == ComposerWidget.ComposerState.NEW ||
widget.state == ComposerWidget.ComposerState.PANED) {
2016-04-11 02:52:53 +10:00
main_window.conversation_viewer.do_compose(widget);
this.application.get_action(
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
ACTION_FIND_IN_CONVERSATION
).set_sensitive(false);
} else {
main_window.conversation_viewer.do_compose_embedded(
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
widget,
referred,
is_draft
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
);
}
} else {
new ComposerWindow(widget);
widget.state = ComposerWidget.ComposerState.DETACHED;
}
Geary.EmailIdentifier? draft_id = null;
if (is_draft) {
draft_id = referred.id;
}
try {
yield widget.open_draft_manager_async(draft_id);
} catch (Error e) {
message("Could not open draft manager: %s", e.message);
}
// For accounts with large numbers of contacts, loading the
// entry completions can some time, so do it after the UI has
// been shown
yield widget.load_entry_completions();
}
private bool should_create_new_composer(ComposerWidget.ComposeType? compose_type,
Geary.Email? referred, string? quote, bool is_draft, out bool inline) {
inline = true;
// In we're replying, see whether we already have a reply for that message.
if (compose_type != null && compose_type != ComposerWidget.ComposeType.NEW_MESSAGE) {
foreach (ComposerWidget cw in composer_widgets) {
if (cw.state != ComposerWidget.ComposerState.DETACHED &&
((referred != null && cw.referred_ids.contains(referred.id)) ||
quote != null)) {
cw.change_compose_type(compose_type, referred, quote);
return false;
}
}
inline = !any_inline_composers();
return true;
}
// If there are no inline composers, go ahead!
if (!any_inline_composers())
return true;
// If we're resuming a draft with open composers, open in a new window.
if (is_draft) {
inline = false;
return true;
}
// If we're creating a new message, and there's already a new message open, focus on
// it if it hasn't been modified; otherwise open a new composer in a new window.
if (compose_type == ComposerWidget.ComposeType.NEW_MESSAGE) {
foreach (ComposerWidget cw in composer_widgets) {
if (cw.state == ComposerWidget.ComposerState.NEW) {
if (!cw.blank) {
inline = false;
return true;
} else {
cw.change_compose_type(compose_type); // To refocus
return false;
}
}
}
}
// Find out what to do with the inline composers.
// TODO: Remove this in favor of automatically saving drafts
main_window.present();
ConfirmationDialog dialog = new ConfirmationDialog(main_window, _("Close open draft messages?"),
null, Stock._CLOSE, "destructive-action");
if (dialog.run() == Gtk.ResponseType.OK) {
Gee.List<ComposerWidget> composers_to_destroy = new Gee.ArrayList<ComposerWidget>();
foreach (ComposerWidget cw in composer_widgets) {
if (cw.state != ComposerWidget.ComposerState.DETACHED)
composers_to_destroy.add(cw);
}
foreach(ComposerWidget cw in composers_to_destroy)
((ComposerContainer) cw.parent).close_container();
return true;
}
return false;
}
public bool can_switch_conversation_view() {
bool inline;
return should_create_new_composer(null, null, null, false, out inline);
}
public bool any_inline_composers() {
foreach (ComposerWidget cw in composer_widgets)
if (cw.state != ComposerWidget.ComposerState.DETACHED)
return true;
return false;
}
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
private void on_composer_widget_destroy(Gtk.Widget sender) {
composer_widgets.remove((ComposerWidget) sender);
debug(@"Destroying composer of type $(((ComposerWidget) sender).compose_type); "
+ @"$(composer_widgets.size) composers remaining");
2013-08-08 18:47:23 -07:00
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
if (waiting_to_close.remove((ComposerWidget) sender)) {
2013-08-08 18:47:23 -07:00
// If we just removed the last window in the waiting to close list, it's time to exit!
if (waiting_to_close.size == 0)
this.application.exit();
2013-08-08 18:47:23 -07:00
}
}
2012-01-17 18:42:20 -08:00
private void on_new_message() {
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
create_compose_widget(ComposerWidget.ComposeType.NEW_MESSAGE);
2012-01-17 18:42:20 -08:00
}
private void on_reply_to_message(ConversationEmail target_view) {
create_reply_forward_widget(ComposerWidget.ComposeType.REPLY, target_view);
}
private void on_reply_to_message_action() {
create_reply_forward_widget(ComposerWidget.ComposeType.REPLY, null);
}
private void on_reply_all_message(ConversationEmail target_view) {
create_reply_forward_widget(ComposerWidget.ComposeType.REPLY_ALL, target_view);
2012-01-17 18:42:20 -08:00
}
private void on_reply_all_message_action() {
create_reply_forward_widget(ComposerWidget.ComposeType.REPLY_ALL, null);
}
private void on_forward_message(ConversationEmail target_view) {
create_reply_forward_widget(ComposerWidget.ComposeType.FORWARD, target_view);
2012-01-17 18:42:20 -08:00
}
private void on_forward_message_action() {
create_reply_forward_widget(ComposerWidget.ComposeType.FORWARD, null);
2012-01-24 18:24:32 -08:00
}
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
private void on_find_in_conversation_action() {
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
this.main_window.conversation_viewer.conversation_find_bar.set_search_mode(true);
}
Reimplement in-conversation find. * src/client/application/geary-controller.vala (GearyController): Remove ACTION_FIND_NEXT_IN_CONVERSATION and ACTION_FIND_PREVIOUS_IN_CONVERSATION arctions and callbacks since they will be taken care of by the search entry & search bar buttons, and remove from accelerators.ui. Add ACTION_TOGGLE_FIND action to handle toggling find bar in the same way as the search bar. * src/client/components/main-toolbar.vala (MainToolbar): Add new button and infrastrcuture for toggling the find bar. * src/client/conversation-viewer/conversation-viewer.vala (ConversationViewer): Convert ::conversation_page to be grid, add new ::conversation_scroller property for the scrollbar, update call sites. Add props for accessing find widgets, remove old find methods and add callbacks for handling find start, change, etc. * src/client/conversation-viewer/conversation-email.vala, src/client/conversation-viewer/conversation-message.vala: Add methods for accessing selected text for find. * src/client/conversation-viewer/conversation-listbox.vala (ConversationListBox::highlight_search_terms): Updated to return a flag specifiying whether any search results were found, and to expand/collapse messsages depending on whether they have any. * src/client/conversation-viewer/conversation-message.vala (ConversationMessage::highlight_search_terms): Keep track of how many results were found, and return that. * ui/conversation-viewer.ui: Convert conversation_page to be a grid, add a search bar and search widgets to it, and move conversation ScrolledWindow to it.
2016-08-22 11:42:54 +10:00
private void on_archive_message() {
archive_or_delete_selection_async.begin(true, false, cancellable_folder,
on_archive_or_delete_selection_finished);
}
private void on_trash_message() {
archive_or_delete_selection_async.begin(false, true, cancellable_folder,
on_archive_or_delete_selection_finished);
}
2011-12-15 16:16:27 -08:00
private void on_delete_message() {
archive_or_delete_selection_async.begin(false, false, cancellable_folder,
on_archive_or_delete_selection_finished);
}
private void on_empty_spam() {
on_empty_trash_or_spam(Geary.SpecialFolderType.SPAM);
}
private void on_empty_trash() {
on_empty_trash_or_spam(Geary.SpecialFolderType.TRASH);
}
private void on_empty_trash_or_spam(Geary.SpecialFolderType special_folder_type) {
// Account must be in place, must have the specified special folder type, and that folder
// must support Empty in order for this command to proceed
if (current_account == null)
return;
Geary.Folder? folder = null;
try {
folder = current_account.get_special_folder(special_folder_type);
} catch (Error err) {
debug("%s: Unable to get special folder %s: %s", current_account.to_string(),
special_folder_type.to_string(), err.message);
// fall through
}
if (folder == null)
return;
Geary.FolderSupport.Empty? emptyable = folder as Geary.FolderSupport.Empty;
if (emptyable == null) {
debug("%s: Special folder %s (%s) does not support emptying", current_account.to_string(),
folder.path.to_string(), special_folder_type.to_string());
return;
}
ConfirmationDialog dialog = new ConfirmationDialog(main_window,
_("Empty all email from your %s folder?").printf(special_folder_type.get_display_name()),
_("This removes the email from Geary and your email server.")
+ " <b>" + _("This cannot be undone.") + "</b>",
_("Empty %s").printf(special_folder_type.get_display_name()), "destructive-action");
dialog.use_secondary_markup(true);
dialog.set_focus_response(Gtk.ResponseType.CANCEL);
if (dialog.run() == Gtk.ResponseType.OK)
empty_folder_async.begin(emptyable, cancellable_folder);
}
private async void empty_folder_async(Geary.FolderSupport.Empty emptyable, Cancellable? cancellable) {
try {
yield do_empty_folder_async(emptyable, cancellable);
} catch (Error err) {
// don't report to user if cancelled
if (cancellable is IOError.CANCELLED)
return;
ErrorDialog dialog = new ErrorDialog(main_window,
_("Error emptying %s").printf(emptyable.get_display_name()), err.message);
dialog.run();
}
}
private async void do_empty_folder_async(Geary.FolderSupport.Empty emptyable, Cancellable? cancellable)
throws Error {
yield emptyable.open_async(Geary.Folder.OpenFlags.NONE, cancellable);
// be sure to close in all code paths
try {
yield emptyable.empty_folder_async(cancellable);
} finally {
try {
yield emptyable.close_async(null);
} catch (Error err) {
// ignored
}
}
}
private bool current_folder_supports_trash() {
return (current_folder != null && current_folder.special_folder_type != Geary.SpecialFolderType.TRASH
&& !current_folder.properties.is_local_only && current_account != null
&& (current_folder as Geary.FolderSupport.Move) != null);
}
public bool confirm_delete(int num_messages) {
main_window.present();
ConfirmationDialog dialog = new ConfirmationDialog(main_window, ngettext(
"Do you want to permanently delete this message?",
"Do you want to permanently delete these messages?", num_messages),
null, _("Delete"), "destructive-action");
return (dialog.run() == Gtk.ResponseType.OK);
}
private async void archive_or_delete_selection_async(bool archive, bool trash,
Cancellable? cancellable) throws Error {
if (!can_switch_conversation_view())
return;
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox list_view =
main_window.conversation_viewer.current_list;
if (list_view != null &&
list_view.conversation == last_deleted_conversation) {
debug("Not archiving/trashing/deleting; viewed conversation is last deleted conversation");
return;
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
last_deleted_conversation = selected_conversations.size > 0
? Geary.traverse<Geary.App.Conversation>(selected_conversations).first() : null;
this.main_window.conversation_list_view.set_changing_selection(true);
Gee.List<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
if (archive) {
debug("Archiving selected messages");
Geary.FolderSupport.Archive? supports_archive = current_folder as Geary.FolderSupport.Archive;
if (supports_archive == null) {
debug("Folder %s doesn't support archive", current_folder.to_string());
} else {
save_revokable(yield supports_archive.archive_email_async(ids, cancellable),
_("Undo archive (Ctrl+Z)"));
}
return;
}
if (trash) {
debug("Trashing selected messages");
if (current_folder_supports_trash()) {
Geary.FolderPath trash_path = (yield current_account.get_required_special_folder_async(
Geary.SpecialFolderType.TRASH, cancellable)).path;
Geary.FolderSupport.Move? supports_move = current_folder as Geary.FolderSupport.Move;
if (supports_move != null) {
save_revokable(yield supports_move.move_email_async(ids, trash_path, cancellable),
_("Undo trash (Ctrl+Z)"));
return;
}
}
debug("Folder %s doesn't support move or account %s doesn't have a trash folder",
current_folder.to_string(), current_account.to_string());
return;
}
debug("Deleting selected messages");
Geary.FolderSupport.Remove? supports_remove = current_folder as Geary.FolderSupport.Remove;
if (supports_remove == null) {
debug("Folder %s doesn't support remove", current_folder.to_string());
} else {
if (confirm_delete(ids.size))
yield supports_remove.remove_email_async(ids, cancellable);
else
last_deleted_conversation = null;
}
2011-12-15 16:16:27 -08:00
}
private void on_archive_or_delete_selection_finished(Object? source, AsyncResult result) {
try {
archive_or_delete_selection_async.end(result);
} catch (Error e) {
debug("Unable to archive/trash/delete messages: %s", e.message);
}
this.main_window.conversation_list_view.set_changing_selection(false);
}
2011-12-15 16:16:27 -08:00
private void save_revokable(Geary.Revokable? new_revokable, string? description) {
// disconnect old revokable & blindly commit it
if (revokable != null) {
revokable.notify[Geary.Revokable.PROP_VALID].disconnect(on_revokable_valid_changed);
revokable.notify[Geary.Revokable.PROP_IN_PROCESS].disconnect(update_revokable_action);
revokable.committed.disconnect(on_revokable_committed);
revokable.commit_async.begin();
}
// store new revokable
revokable = new_revokable;
// connect to new revokable
if (revokable != null) {
revokable.notify[Geary.Revokable.PROP_VALID].connect(on_revokable_valid_changed);
revokable.notify[Geary.Revokable.PROP_IN_PROCESS].connect(update_revokable_action);
revokable.committed.connect(on_revokable_committed);
}
Gtk.Action undo_action = this.application.get_action(ACTION_UNDO);
undo_action.tooltip = (revokable != null && description != null) ? description : _("Undo (Ctrl+Z)");
update_revokable_action();
}
private void update_revokable_action() {
Gtk.Action undo_action = this.application.get_action(ACTION_UNDO);
undo_action.sensitive = revokable != null && revokable.valid && !revokable.in_process;
}
private void on_revokable_valid_changed() {
// remove revokable if it goes invalid
if (revokable != null && !revokable.valid)
save_revokable(null, null);
}
private void on_revokable_committed(Geary.Revokable? committed_revokable) {
if (committed_revokable == null)
return;
// use existing description
Gtk.Action undo_action = this.application.get_action(ACTION_UNDO);
save_revokable(committed_revokable, undo_action.tooltip);
}
private void on_revoke() {
if (revokable != null && revokable.valid)
revokable.revoke_async.begin(null, on_revoke_completed);
}
private void on_revoke_completed(Object? object, AsyncResult result) {
// Don't use the "revokable" instance because it might have gone null before this callback
// was reached
Geary.Revokable? origin = object as Geary.Revokable;
if (origin == null)
return;
try {
origin.revoke_async.end(result);
} catch (Error err) {
debug("Unable to revoke operation: %s", err.message);
}
}
2016-07-10 21:56:55 +10:00
private void on_zoom_in() {
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox? view =
main_window.conversation_viewer.current_list;
if (view != null) {
view.zoom_in();
}
}
private void on_zoom_out() {
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox? view =
main_window.conversation_viewer.current_list;
if (view != null) {
view.zoom_out();
}
}
private void on_zoom_normal() {
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
ConversationListBox? view =
main_window.conversation_viewer.current_list;
if (view != null) {
view.zoom_reset();
}
}
2016-07-10 21:56:55 +10:00
private void on_conversation_list() {
this.main_window.conversation_list_view.grab_focus();
}
private void on_sent(Geary.RFC822.Message rfc822) {
Libnotify.play_sound("message-sent-email");
}
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
private void on_conversation_view_added(ConversationListBox list) {
list.email_added.connect(on_conversation_viewer_email_added);
list.mark_emails.connect(on_conversation_viewer_mark_emails);
}
private void on_conversation_viewer_email_added(ConversationEmail view) {
view.attachments_activated.connect(on_attachments_activated);
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
view.reply_to_message.connect(on_reply_to_message);
view.reply_all_message.connect(on_reply_all_message);
view.forward_message.connect(on_forward_message);
view.edit_draft.connect((draft_view) => {
create_compose_widget(
ComposerWidget.ComposeType.NEW_MESSAGE,
draft_view.email, null, null, true
);
});
view.message_view_iterator().foreach((mview) => {
mview.link_activated.connect((link) => {
if (link.down().has_prefix(
Geary.ComposedEmail.MAILTO_SCHEME)) {
compose_mailto(link);
} else {
open_uri(link);
}
});
mview.save_image.connect(on_save_buffer_to_file);
mview.search_activated.connect((op, value) => {
string search = op + ":" + value;
show_search_bar(search);
});
return true;
});
Break out ListBox used to display conversations into standalone widget. The conversation viewer's ListBox is sufficiently complex to warrant its own widget. Use empty placeholders for the list per the HIG, and correctly fix mamagement of empty folder vs no conversations selected this time. * src/client/application/geary-controller.vala (GearyController): Directly manage secondary parts of the conversation viewer, since the controller since it has a better and more timely idea of when a conversation change is due to folder loading status or from the user selecting conversations, and so the viwer doesn't need to hook back into the controller. Remove the now-unused conversations_selected signal and its callers. * src/client/conversation-viewer/conversation-listbox.vala: New widget for displaying the list of emails for a conversation. Moved relevant code from ConversationViewer here. Made adding emails async to get better UI responsiveness. Don't implement anything to handle conversation changes or emptying the list. * src/client/conversation-viewer/conversation-viewer.vala: Replace user messages - empty folder/search & no/multiple messages selected with new EmptyPlaceholder. Remove a lot of the state manage code needed when managing the email listbox. Add a new ConversationListBox for every new conversation and just throw away. * src/client/conversation-list/conversation-list-view.vala (ConversationListView): Clean up firing the conversations_selected signal - don't actually emit it when the model is clearing, and don't bother delaying the check either. * src/client/components/empty-placeholder.vala: New widget for displaying empty list and grid placeholders per the HIG. * src/client/conversation-viewer/conversation-email.vala (ConversationEmail): Make manually read a property, since it effectively is one. * src/CMakeLists.txt: Include new source files. * po/POTFILES.in: Include new source and UI files, and some missing ones. * ui/CMakeLists.txt: Include new UI files. * ui/conversation-viewer.ui: Replace user message and splash page with placeholders for the new empty placeholders(!). * ui/empty-placeholder.ui: UI def for new widget class. * ui/geary.css: Chase widget name/class changes, style new empty placeholder UI.
2016-07-25 10:33:42 +10:00
view.save_attachments.connect(on_save_attachments);
view.view_source.connect(on_view_source);
}
private void on_view_source(ConversationEmail email_view) {
string source = (email_view.email.header.buffer.to_string() +
email_view.email.body.buffer.to_string());
string temporary_filename;
try {
int temporary_handle = FileUtils.open_tmp("geary-message-XXXXXX.txt",
out temporary_filename);
FileUtils.set_contents(temporary_filename, source);
FileUtils.close(temporary_handle);
// ensure this file is only readable by the user ... this
// needs to be done after the file is closed
FileUtils.chmod(temporary_filename, (int) (Posix.S_IRUSR | Posix.S_IWUSR));
string temporary_uri = Filename.to_uri(temporary_filename, null);
Gtk.show_uri(main_window.get_screen(), temporary_uri, Gdk.CURRENT_TIME);
} catch (Error error) {
ErrorDialog dialog = new ErrorDialog(
main_window,
_("Failed to open default text editor."),
error.message
);
dialog.run();
}
}
// Disables all single-message buttons and enables all multi-message buttons.
public void enable_multiple_message_buttons() {
2013-02-22 17:54:05 -08:00
update_tooltips();
// Single message only buttons.
this.application.actions.get_action(ACTION_REPLY_TO_MESSAGE).sensitive = false;
this.application.actions.get_action(ACTION_REPLY_ALL_MESSAGE).sensitive = false;
this.application.actions.get_action(ACTION_FORWARD_MESSAGE).sensitive = false;
// Mutliple message buttons.
this.application.actions.get_action(ACTION_MOVE_MENU).sensitive =
(current_folder is Geary.FolderSupport.Move);
this.application.actions.get_action(ACTION_ARCHIVE_MESSAGE).sensitive =
(current_folder is Geary.FolderSupport.Archive);
this.application.actions.get_action(ACTION_TRASH_MESSAGE).sensitive =
current_folder_supports_trash();
this.application.actions.get_action(ACTION_DELETE_MESSAGE).sensitive =
(current_folder is Geary.FolderSupport.Remove);
cancel_context_dependent_buttons();
enable_context_dependent_buttons_async.begin(true, cancellable_context_dependent_buttons);
}
// Enables or disables the message buttons on the toolbar.
public void enable_message_buttons(bool sensitive) {
2013-02-22 17:54:05 -08:00
update_tooltips();
2013-07-19 15:44:20 -07:00
// No reply/forward in drafts folder.
bool respond_sensitive = sensitive;
if (current_folder != null && current_folder.special_folder_type == Geary.SpecialFolderType.DRAFTS)
respond_sensitive = false;
this.application.actions.get_action(ACTION_REPLY_TO_MESSAGE).sensitive = respond_sensitive;
this.application.actions.get_action(ACTION_REPLY_ALL_MESSAGE).sensitive = respond_sensitive;
this.application.actions.get_action(ACTION_FORWARD_MESSAGE).sensitive = respond_sensitive;
this.application.actions.get_action(ACTION_MOVE_MENU).sensitive =
sensitive && (current_folder is Geary.FolderSupport.Move);
this.application.actions.get_action(ACTION_ARCHIVE_MESSAGE).sensitive = sensitive
&& (current_folder is Geary.FolderSupport.Archive);
this.application.actions.get_action(ACTION_TRASH_MESSAGE).sensitive = sensitive
&& current_folder_supports_trash();
this.application.actions.get_action(ACTION_DELETE_MESSAGE).sensitive = sensitive
&& (current_folder is Geary.FolderSupport.Remove);
cancel_context_dependent_buttons();
enable_context_dependent_buttons_async.begin(sensitive, cancellable_context_dependent_buttons);
}
private async void enable_context_dependent_buttons_async(bool sensitive, Cancellable? cancellable) {
Gee.MultiMap<Geary.EmailIdentifier, Type>? selected_operations = null;
try {
if (current_folder != null) {
Geary.App.EmailStore? store = email_stores.get(current_folder.account);
if (store != null) {
selected_operations = yield store
.get_supported_operations_async(get_selected_email_ids(false), cancellable);
}
}
} catch (Error e) {
debug("Error checking for what operations are supported in the selected conversations: %s",
e.message);
}
// Exit here if the user has cancelled.
if (cancellable != null && cancellable.is_cancelled())
return;
Gee.HashSet<Type> supported_operations = new Gee.HashSet<Type>();
if (selected_operations != null)
supported_operations.add_all(selected_operations.get_values());
this.application.actions.get_action(ACTION_MARK_AS_MENU).sensitive =
sensitive && (supported_operations.contains(typeof(Geary.FolderSupport.Mark)));
this.application.actions.get_action(ACTION_COPY_MENU).sensitive =
sensitive && (supported_operations.contains(typeof(Geary.FolderSupport.Copy)));
}
2013-02-22 17:54:05 -08:00
// Updates tooltip text depending on number of conversations selected.
private void update_tooltips() {
bool single = selected_conversations.size == 1;
this.application.actions.get_action(ACTION_MARK_AS_MENU).tooltip = single ?
2013-02-22 17:54:05 -08:00
MARK_MESSAGE_MENU_TOOLTIP_SINGLE : MARK_MESSAGE_MENU_TOOLTIP_MULTIPLE;
this.application.actions.get_action(ACTION_COPY_MENU).tooltip = single ?
2013-02-22 17:54:05 -08:00
LABEL_MESSAGE_TOOLTIP_SINGLE : LABEL_MESSAGE_TOOLTIP_MULTIPLE;
this.application.actions.get_action(ACTION_MOVE_MENU).tooltip = single ?
2013-02-22 17:54:05 -08:00
MOVE_MESSAGE_TOOLTIP_SINGLE : MOVE_MESSAGE_TOOLTIP_MULTIPLE;
this.application.actions.get_action(ACTION_ARCHIVE_MESSAGE).tooltip = single ?
ARCHIVE_MESSAGE_TOOLTIP_SINGLE : ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE;
this.application.actions.get_action(ACTION_TRASH_MESSAGE).tooltip = single ?
TRASH_MESSAGE_TOOLTIP_SINGLE : TRASH_MESSAGE_TOOLTIP_MULTIPLE;
this.application.actions.get_action(ACTION_DELETE_MESSAGE).tooltip = single ?
DELETE_MESSAGE_TOOLTIP_SINGLE : DELETE_MESSAGE_TOOLTIP_MULTIPLE;
2013-02-22 17:54:05 -08:00
}
// Returns a list of composer windows for an account, or null if none.
Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Separate composer widget from composer window In anticipation of inline composition, we need the composer widget to be separate from the window in which it lives. We introduce a new interface, ComposerContainer, that the thing that holds to ComposerWidget must implement. Basic inline composition Many of the details don't work, or don't work well, but the basics are in place. Allow only a single inline composition at a time With this, we introduce a dialog when you would try to add another. We also use this when changing the selected conversation with a composer open. Compose new messages inline, with no conversation selected Hook up composer accelerators only when focus is in composer editor It would be nice to only activate these accelerators when the composer has focus generally, but that doesn't seem to be easy to detect. Only disconnect accelerators if they're connected Maintain focus when composer is popped out The selection isn't, though. Fix Tab focus for embedded composer There are two things that needed to be fixed: The tab key doesn't usually advance focus for embedded widgets (huh?), so we handle tab presses by hand for ComposerWidgets. Also, the EmailEntrys do their own tab handling, which needs to know about the composer widget, not the toplevel widget in the embedded case. Remove close() from ComposerContainer interface I don't think it was actually doing anything, and it conflicts with the new close() method of Gtk.Window.
2014-02-11 00:26:14 -05:00
public Gee.List<ComposerWidget>? get_composer_widgets_for_account(Geary.AccountInformation account) {
Gee.LinkedList<ComposerWidget> ret = Geary.traverse<ComposerWidget>(composer_widgets)
.filter(w => w.account.information == account)
.to_linked_list();
return ret.size >= 1 ? ret : null;
}
private void show_search_bar(string? text = null) {
main_window.search_bar.give_search_focus();
if (text != null) {
main_window.search_bar.set_search_text(text);
}
}
private void do_search(string search_text) {
Geary.SearchFolder? folder = null;
try {
folder = (Geary.SearchFolder) current_account.get_special_folder(
Geary.SpecialFolderType.SEARCH);
} catch (Error e) {
debug("Could not get search folder: %s", e.message);
return;
}
2013-05-14 11:52:02 -07:00
if (search_text == "") {
if (previous_non_search_folder != null && current_folder is Geary.SearchFolder)
main_window.folder_list.select_folder(previous_non_search_folder);
main_window.folder_list.remove_search();
search_text_changed("");
folder.clear();
2013-05-14 11:52:02 -07:00
return;
}
if (current_account == null)
return;
cancel_search(); // Stop any search in progress.
folder.search(search_text, this.application.config.get_search_strategy(),
this.cancellable_search);
2013-05-14 11:52:02 -07:00
main_window.folder_list.set_search(folder);
search_text_changed(main_window.search_bar.search_text);
2013-05-14 11:52:02 -07:00
}
/**
* Returns a read-only set of currently selected conversations.
*/
public Gee.Set<Geary.App.Conversation> get_selected_conversations() {
return selected_conversations.read_only_view;
}
// Find the first inbox we know about and switch to it.
private void switch_to_first_inbox() {
try {
if (Geary.Engine.instance.get_accounts().values.size == 0)
return; // No account!
// Look through our accounts, grab the first inbox we can find.
Geary.Folder? first_inbox = null;
foreach(Geary.AccountInformation info in Geary.Engine.instance.get_accounts().values) {
first_inbox = get_account_instance(info).get_special_folder(Geary.SpecialFolderType.INBOX);
if (first_inbox != null)
break;
}
if (first_inbox == null)
return;
// Attempt the selection. Try the inboxes branch first.
if (!main_window.folder_list.select_inbox(first_inbox.account))
main_window.folder_list.select_folder(first_inbox);
} catch (Error e) {
debug("Could not locate inbox: %s", e.message);
}
}
}