Since we're using the Icon View, we have some more options in terms of
user selction and the actions applicable to that. So make the attachment
signals and their handlers all apply to collections of attachments and
use the GAppInfo class for determining which app to open an attachment
with.
* src/client/application/geary-controller.vala: Chase signal changes.
(GearyController::on_attachments_activated): Handle multiple
attachments being activated at once. Use its GAppInfo for launching
each attachment, prompt the user with an GtkAppChooserDialog if the
info is unknown.
* src/client/conversation-viewer/conversation-email.vala Use the new
AttachmentInfo class to manage lists of all displayed and currently
selected attachments and their associated GAppInfo objects. Add actions
for attachment context menu items. Move attachment signals from
ConversationViewer here, make all attachment signals have a collection
of them as their param. Hook up appropriate GtkIconView callbacks to
manage selection, activation, etc. Construct AttachmentInfo instances
when loading attachments and use them in the icon view's model.
* ui/conversation-email.ui: Define needed callbacks for the icon
view. Update its model to accept a GObject for the attachment info
class.
* ui/conversation-message-menu.ui: Fix action name for save attachments
menu item.
* src/client/application/geary-controller.vala: Chase signal changes.
(GearyController::on_view_source): Moved view source code here from the
conversation viewer.
* src/client/conversation-viewer/conversation-email.vala: Add an action
group for the email for email-specific actions with the prefix
"msg". Add actions each of the items in the email menu. Move
email-specific signals here from ConversationViewer. Update actions
based on message state as needed.
* src/client/conversation-viewer/conversation-viewer.vala: Add signal
handlers for ConversationEmail's email flagging signals and forward
them on to the `mark_emails` signal, since we also want to batch up
email flag changes from here.
* ui/conversation-email.ui: Fix star/unstar action names.
* ui/conversation-message-menu.ui: Cromulify the email menu name.
* src/client/application/geary-application.vala
(GearyApplication::read_theme_file): Renamed to ::read_resource, do the
lookup on a GResource instead of from the file system.
(GearyApplication::get_ui_file): Remove unused method.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView): Chase CSS file rename and load method.
* theming/CMakeLists.txt: Removed, no longer needed.
* theming/message-viewer.css: Moved to ui/conversation-web-view.css.
* ui/CMakeLists.txt: Add conversation-web-view.css resource.
* CMakeLists.txt: Remove theming include.
* src/client/application/geary-application.vala :
Since we're no longer using the web view to display the user avatar, use
libsoup and add some additional infrastructure to support caching the
avatars. Also switches to HTTPS for accessing the Gravatar service.
* src/client/application/geary-application.vala
(GearyApplication::get_user_cache_directory): New method to return the
XDG cache directory for Geary.
* src/client/application/geary-controller.vala: Add both a Soup session
and cache for fetching avatars. Write the cache to disk on controller
close.
* src/client/conversation-viewer/conversation-email.vala
(ConversationEmail::start_loading): Trigger avatar loads when loading
the email.
* src/client/conversation-viewer/conversation-message.vala: Replace
single avatar image widget with two, so the image does not need to be
rescaled when expanded/collapsed.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::load_avatar): Queue a request for a Gravatar
avatar.
(ConversationMessage::set_avatar): Load pixbuf returned by Gravatar,
scale and set it for the preview and expanded avatar images.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::clear): Cancel any outsanding avatar loads.
* src/client/util/util-gravatar.vala (Gravatar): Construct a HTTPS URL to
avoid advertising to the NSA who we are receiving email from.
* ui/conversation-message.ui: Add the second avatar image.
* src/client/conversation-viewer/conversation-email.vala
(ConversationEmail::not_saved_infobar): Add a template widget child for
the not-saved info bar, add to ConversationMessage's infobar box and
display it when the flag is set.
* ui/conversation-email.ui: Add a warning info bar for displaying the
message.
* src/client/conversation-viewer/conversation-email.vala: Move the
draft_infobar wdiget from ConversationMessage, when the message is a
draft add it to ConversationMessage's infobar box and show it.
* ui/conversation-email.ui: Move the draft_infobar definition from
conversation-message.ui here.
* ui/conversation-message.ui: Wrap the remote messages infobar in an box
so that ConversationEmail can easily append its own in the same location.
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.
* src/client/conversation-viewer/conversation-message.vala: Load message
body from ::start_loading, pass the cancellable through so the web_view
load can be stopped. Make ::load_message_body async so the UI can be
updated before attempting the page load.
* src/client/conversation-viewer/conversation-message.vala: Remove
containing_folder, replace with contact_store (for now) since that was
the only thing current_folder was being used for. Update use and call
sites.
Use a Gtk.InfoBar for displaying the draft button.
* src/client/conversation-viewer/conversation-message.vala: Add draft
infobar template child, edit_draft signal. Remove unused draft-related
code.
(ConversationMessage::ConversationMessage): Add new is_draft ctor
param, when true show the draft infobar.
(ConversationMessage::on_draft_response): New handler for when the edit
draft button on the infobar is clicked.
* src/client/conversation-viewer/conversation-viewer.vala: Remove
edit_draft signal, make a lame attemppt to work out if a message is a
draft and pass that through to ConversationMessage.
* src/client/application/geary-controller.vala: Hook up on_edit_draft
handler to added conversation messages.
* ui/conversation-message.ui: Added draft infobar.
* src/client/conversation-viewer/conversation-message.vala: Add template
child widgets for displayed attachment UI, add signal for when user
activates an attachment.
(ConversationMessage::ConversationMessage): Ensure the attachment UI
is visible when there are displayed attachments.
(ConversationMessage::start_loading): New method for async loading of
message content, use just for attachments for now.
(ConversationMessage::on_attachments_view_activated): Handle activation
signal for specific attachments.
(ConversationMessage::load_attachments): Load attachments from the
message into the new UI.
(ConversationMessage::load_attachment_icon): Load icons for the
attachments UI from the attachment itself if an image, else from the
icon theme.
* src/client/application/geary-controller.vala: Hook up
attachment_activated signal to conversation messages.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::add_message): Ensure message loading starts after
new conversation messages are added to the window hierarchy.
* ui/conversation-message.ui: Add an attachments box, with an icon view
for displayed attachments.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::ConversationViewer): Don't think this even does
anything?
(ConversationViewer::select_conversation_async): This was breaking
being able to browse up/down the convo list using the keyboard.
Since we want GearyController to handle the effects of most user actions,
we've had to duplicate ConversationMessage's signals on
ConversationViewer and chain them down.
Instead, add a message_added & message_removed signal to
ConversationViewer and emit them as appropriate, then have
GearyController connect to those and manually manage hooking/unhooking
itself to ConversationMessage signals as instances are added/removed.
Do this to the link clicked signal to start.
* src/client/application/geary-controller.vala: Add on_message_added and
on_message_removed handlers, connect them to the main window's
ConversationViewer instance and added/remove the message's link click
hander there.
* src/client/conversation-viewer/conversation-viewer.vala: Add
message_added and message_removed signals, hook them up as messages are
added and removed. Remove link_selected signal and plumbing.
* src/client/conversation-viewer/conversation-message.vala: Rename
link_selected to link_activated to match GTK nomenclature better.
* src/client/components/main-window.vala: Adjust theme CSS style to
account for new widget classes. Fix style for last row in the convo
listbox.
* src/client/conversation-viewer/conversation-message.vala: Decouple
updating message state and updating message flags. Prefix CSS classes
with "geary_" to prevent class name clashes.
* src/client/conversation-viewer/conversation-viewer.vala: Manually
maintain a CSS class on the last row of the convo listbox to work
around Bug 764710. Prefix CSS classes with "geary_" to prevent class
name clashes.
(ConversationViewer::on_update_flags): Renamed from update_flags since
it is only ever called as a signal handler. Remove most of the work -
it is now done by ConversationMessage.
* src/client/conversation-viewer/conversation-message.vala: Keep track of
the web_view's allocation so we can work out if it is visible, and the
loading state of the web_view so we know if it should be considered or
not.
(ConversationMessage::load_message_body): Rearranged a bit so only one
web_view.load_status signal handler is needed and there isn't a race
between loading completion and showing remote images. Also set the new
is_loading_complete property.
* src/client/conversation-viewer/conversation-viewer.vala
(check_mark_read): Reimplement using widget coordinates rather than
HTML coordinates.
Having two buttons means we don't need to change the image and handler
when clicked, just manage their visbility.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage): Add both a star and unstar template child,
update their state as the message's state changes.
* ui/conversation-message.ui: Rename flag button to "star", add new
unstar button.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::ConversationMessage): Remove old "empty" theme CSS
class, just set header boxes to be visible when setting their text.
* ui/conversation-message.ui: Default header box visibility to off.
* ui/conversation-message.ui: Split out preview labels from existing
header box and create a new preview box for them.
* src/client/components/main-window.vala (MainWindow::set_styling): Use
style-defined names to allow us to specify message row backgrounds better.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage): Update GTK composite template children
properties and visible state when showing/hiding the body, set new
preview/header box label texts.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::do_embedded_composer,
ConversationViewer::add_message): Don't add 'frame' class to conversation
list rows, we're styling it explicitly now.
* src/client/conversation-viewer/conversation-viewer.vala: Replace
have_conversations with loading_conversations, update it appropriately.
(ConversationViewer::set_visible_child): Overriddent to get some debug
info out.
(on_folder_selected): Don't set the loading page here, it'll get set
when a conversation load times out.
(ConversationViewer::on_conversation_count_changed): Use current folder
as determination for the zero-message text, since both normal and
search is the same state.
(on_conversations_selected): Always clear and load conversations when
they are selected, update visual state only if we are in conversation
mode.
(select_conversation_async): Update visual state if we are in conversation
mode here since this is the only time we know we have messages to
actually display.
Use a GtkInfoBar to display to the user the message and related buttons
instead of the message-inline HTML approach. Still needs some additional
work to save per-message loading and displaying images from same sender
in convo when "Always Show" is chosen.
* src/client/conversation-viewer/conversation-message.vala: Reenable
remote image related code, remove HTML-based UI management code.
* src/client/components/main-window.vala (MainWindow::set_styling):
Add some theme CSS to style the remote images infobar.
* ui/conversation-message.ui: Add the remote images infobar.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView::get_preferred_height): Clamp reported preferred
height to something reasonable to avoid trying to allocate a stupidly
big pixmap.
* src/client/conversation-viewer/conversation-message.vala: Reenable,
update and hook up calls to unset_controllable_quotes,
on_show_quote_clicked and on_hide_quote_clicked. Remove the show/hide
dichotomy, just use hide when the quote should be hidden.
* theming/message-viewer.css: Updated to chase style changes.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::ConversationViewer): Hook up list's scrolled
window's adjustment to the list.
(ConversationViewer::select_conversation_async): Try to make last message
get scrolled to when adding messages from a new convo.
The embedded composer is now added to the the conversation list
box. Still needs some work to fix focus and scrolling issues, also to
insert the composer in the right place in the list.
* src/client/components/main-window.vala (MainWindow::set_styling):
Adjust theme CSS to make padding around embedded coposer not so
terrible. Fix style for embedded headerbar.
* src/client/composer/composer-embed.vala: Don't attempt to up-manage
it's parent's state, since the parent has a much better idea of how
best to do that. Instead of passing in a ConversationViewer, just pass
in a Gtk.ScrolledWindow that needs to be adjusted as the embededded
editor and add some signals needed by the ConversationViewer. Reenabled
some code needed to get scroll event passthrough working.
* src/client/conversation-viewer/conversation-viewer.vala: Remove old
embedded composer code. Adjust conversation_listbox callbacks to handle
the embedded composer being present.
(ConversationViewer::get_selected_message): Fixed to actually return a
message.
(ConversationViewer::do_embedded_composer): New method to set up an
embedded composer.
* src/client/application/geary-controller.vala
(GearyController::create_compose_widget_async): Call new
ConversationViewer::do_embedded_composer to let it set up a new
embedded composer when needed.
Display attached+un-embedded composer as an additional ConversationViewer
stack page, although it realy should be broken as its own top-level
widget - there's already too much state in ConversationViewer.
* src/client/conversation-viewer/conversation-viewer.vala: Remove old
composer boxes code. Add new ViewState enum, property and methods to
define and manipulate the current view state - either conversation or
composer.
(do_conversation): New method to put the viewer in conversation mode.
(do_compose): New method to put the viewer in compose mode, hook up the
composer widget, and handle ConversationListView selection management
for now.
(on_folder_selected, on_conversation_count_changed,
on_conversations_selected): Ensure these methods do the right thing
depending on the viewer's current view state.
(set_paned_composer): Replaced by ::do_compose, fixed call sites.
(show_multiple_selected): Minor code clean up - moved down to a more
appropriate location.
* src/client/composer/composer-box.vala (ComposerBox): Don't attempt to
up-manage it's parent's state, since the parent has a much better idea
of how best to do that. Likewise move code to manage previous
ConversationList selection out, provide signal so the a more
appropriate class can manage it instead.
* src/client/composer/composer-container.vala: Add some method comments.
* ui/conversation-viewer.ui: Add new page to the stack for the composer.
* src/client/conversation-viewer/conversation-message.vala: Remove
overlay-related code, enable tooltips on the body box since WebView
doesn't want to display them - even with the change to
ConversationWebView below, renable link mouseover handler and set/clear
tooltip text when mousing over one.
* src/client/conversation-viewer/conversation-web-view.vala
(query_tooltip): Removed, not sure why we don't want this but it may
well be preventing title tooltips from being displayed.
Requires GTK+ 3.12.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage::link_selected): Added to pass through successful
link clicks to the message_viewer, hook it up to the web_view.
(ConversationMessage::load_message_body): Hook up WebKit event handler
for when links are clicked, so phishing links can be intercepted.
(ConversationMessage::on_link_clicked_self): Use a popover to display
phishing warning, recursively check link's offset parent's when
calculating box position, escape link text/href before using it as
markup.
* src/client/conversation-viewer/conversation-viewer.vala
(ConversationViewer::add_message): Ensure unhandled mouse clicks o the
web_view are not used to activate the message's ListBoxRow.
* ui/conversation-message.ui: Add popover (GTK+ 3.12) for phishing links.
* src/client/conversation-viewer/conversation-message.vala
(ConversationMessage): Make sure public members appear before private
ones.
* src/client/conversation-viewer/conversation-web-view.vala (ConversationWebView):
Make sure public members appear before private ones, remove unused code.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView::ConversationWebView): Don't load message.html
since ConversationMessage now just loads the message HTML directly.
(ConversationWebView::on_load_finished): Don't load container DIV and
inline icons since GTK-based chrome has mostly replaced HTML chrome.
(conversation_icon_color, container, scroll_reset, set_icon_src,
set_attachment_src): Removed, no longer needed.
(ConversationWebView::get_preferred_size,
ConversationWebView::get_preferred_height): Added to ensure GTK gets
a useful min/preferred height for the widget.
* theming/message-viewer.css: Remove rules used for now-obsolete HTML
chrome - headers, attachments, etc. Added rules to ensure HTML and BODY
element's heights and scrollbars are appropriate for use in this
context.
* theming/message-viewer.html: Removed, no longer needed.
* src/client/conversation-viewer/conversation-viewer.vala: Convert to a
GtkStack. Use a GTK template for constructing the UI. Remove WebView
and any DOM-related code. Replace the enum DisplayMode and hence the
HTML spinner and HTML user message with widgets in the stack. Remove
all menus since they're all message specific and will need to be
re-implemented for ConversationViewer. Comment out composer related
code for the moment.
* src/client/application/geary-controller.vala
(GearyController::conversations_selected): Make both conversations and
current_folder arguments non-nullable, since it doesn't make any sense
for there not to be any and simplifies handler impls.
(GearyController::on_conversations_selected): Don't fire when there
isn't a current folder.
* src/client/components/main-window.vala (MainWindow::set_styling): Add
CSS theme code for the the conversation message list.
(MainWindow::create_layout): Remove GtkFrame, just add the
ConversationViewer instance directly.
* ui/conversation-viewer.ui: New GtkBuilder template for
ConversationViewer, implemented as a GtkStack containing widgets for
displaying the loading spinner, conversation as a GtkListBox, and label
for user messages.
* ui/CMakeLists.txt, po/POTFILES.in: Added new UI files.
The new widget is designed to be added to a ListBox like container, and
can display both a summary and the complete message, a'la the traditional
Geary ConversationView.
Most features are currently disabled, but it does handle hiding/showing
the message body using a single WebKit.WebView. All code from
ConversationViewer relating to DOM manipulation as been copied over, all
but that which was needed to display the message has been commentd out.
* src/client/conversation-viewer/conversation-message.vala: Source code
for new widget.
* src/client/components/main-window.vala: Add CSS theme code for
ConversationMessage.
* ui/conversation-message.ui: GtkBuilder template for new widget.
* ui/conversation-message-menu.ui: GtkBuilder for the message menu. This
is a separate file since GTK+ 3.10 doesn't support GtkPopoverMenu and I
can't build it using Glade otherwise.
* src/CMakeLists.txt: Added new source file.
* po/POTFILES.in, ui/CMakeLists.txt: Added new UI files.
Since drafts, replies and forwarded HTML messages may reference inline
images by CID, so ensure that any existing CIDs are retained.
Bug 712995.
* src/client/composer/composer-widget.vala
(ComposerWidget::get_composed_email): Update ComposedEmail's CID map.
(ComposerWidget::update_pending_attachments): Only keep any existing
CID for inline parts.
* src/engine/api/geary-composed-email.vala (ComposedEmail): Keep track of
CIDs we are interested in and the files they refer to.
(ComposedEmail::contains_inline_img_src): Added to allow determining if
a CID has been used in an email. Use class constants, update
::replace_inline_img_src to use them.
* src/engine/rfc822/rfc822-message.vala (Message::from_composed_email):
Include parts with CIDs in the message body, don't include inline
parts that already have a CID.
* src/client/composer/composer-widget.vala (ComposerWidget): Add mapping
of Content IDs to files, check for them when loading resources and
point them at the attahcment's file.
This merges the pending attachment add & check methods to do both at
once, so the logic for determining if a panding attachment should be
added doesn't need to be duplicated.
Also changes the behaviour of pending attachments to always include
inline attachments, even when only replying, since they should be
displayed if included in the quote.
* src/client/composer/composer-widget.vala (ComposerWidget): Add state
flag to specify which pending attachments should be included. Move all
private attachment-related fields to the same place in the
source. Combine ::add_pending_attachments and
::check_pending_attachments into new ::update_pending_attachments
method, update call sites.