diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala index e12ae46c..153126d3 100644 --- a/src/client/application/geary-controller.vala +++ b/src/client/application/geary-controller.vala @@ -2166,10 +2166,11 @@ public class GearyController : Geary.BaseObject { if (inline) { if (widget.state == ComposerWidget.ComposerState.NEW || - widget.state == ComposerWidget.ComposerState.PANED) + widget.state == ComposerWidget.ComposerState.PANED) { main_window.conversation_viewer.do_compose(widget); - else - new ComposerEmbed(widget, main_window.conversation_viewer, referred); // is_draft + } else { + main_window.conversation_viewer.do_embedded_composer(widget, referred); + } } else { new ComposerWindow(widget); widget.state = ComposerWidget.ComposerState.DETACHED; diff --git a/src/client/composer/composer-box.vala b/src/client/composer/composer-box.vala index 957b939b..496c5d37 100644 --- a/src/client/composer/composer-box.vala +++ b/src/client/composer/composer-box.vala @@ -18,12 +18,8 @@ public class ComposerBox : Gtk.Frame, ComposerContainer { public Gtk.ApplicationWindow top_window { get { return (Gtk.ApplicationWindow) get_toplevel(); } - - public Gtk.Window top_window { - get { return (Gtk.Window) get_toplevel(); } } - public signal void vanished(); diff --git a/src/client/composer/composer-embed.vala b/src/client/composer/composer-embed.vala index 19acab5d..74416379 100644 --- a/src/client/composer/composer-embed.vala +++ b/src/client/composer/composer-embed.vala @@ -12,57 +12,43 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer { private const int MIN_EDITOR_HEIGHT = 200; - private ConversationViewer conversation_viewer; - - // The id of the composer HTML element - private string embed_id; - private bool setting_inner_scroll; - private bool scrolled_to_bottom = false; - //private double inner_scroll_adj_value; - private int inner_view_height; - private int min_height = MIN_EDITOR_HEIGHT; - - protected ComposerWidget composer { get; set; } - - protected Gee.MultiMap? old_accelerators { get; set; } + public Geary.Email referred { get; private set; } public Gtk.ApplicationWindow top_window { get { return (Gtk.ApplicationWindow) get_toplevel(); } } - public ComposerEmbed(ComposerWidget composer, ConversationViewer conversation_viewer, - Geary.Email referred) { + protected ComposerWidget composer { get; set; } + + protected Gee.MultiMap? old_accelerators { get; set; } + + private Gtk.ScrolledWindow outer_scroller; + private bool setting_inner_scroll; + private bool scrolled_to_bottom = false; + private double inner_scroll_adj_value; + private int inner_view_height; + private int min_height = MIN_EDITOR_HEIGHT; + + + public signal void loaded(); + public signal void vanished(); + + + public ComposerEmbed(Geary.Email referred, + ComposerWidget composer, + Gtk.ScrolledWindow outer_scroller) { + this.referred = referred; this.composer = composer; - this.conversation_viewer = conversation_viewer; + this.outer_scroller = outer_scroller; this.halign = Gtk.Align.FILL; this.valign = Gtk.Align.FILL; - WebKit.DOM.HTMLElement? email_element = null; - // email_element = conversation_viewer.web_view.get_dom_document().get_element_by_id( - // conversation_viewer.get_div_id(referred.id)) as WebKit.DOM.HTMLElement; - // embed_id = referred.id.to_string() + "_reply"; - // if (email_element == null) { - // warning("Embedded composer could not find email to follow."); - // email_element = conversation_viewer.web_view.get_dom_document().get_element_by_id( - // "placeholder") as WebKit.DOM.HTMLElement; - // } - - try { - email_element.insert_adjacent_html("afterend", - @"
"); - } catch (Error error) { - debug("Error creating embed element: %s", error.message); - return; - } - add(composer); realize.connect(on_realize); this.composer.editor.focus_in_event.connect(on_focus_in); this.composer.editor.focus_out_event.connect(on_focus_out); this.composer.editor.document_load_finished.connect(on_loaded); - this.conversation_viewer.compose_overlay.add_overlay(this); show(); - present(); } private void on_realize() { @@ -86,7 +72,7 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer { } Idle.add(() => { recalc_height(); - conversation_viewer.compose_overlay.queue_resize(); + loaded(); return false; }); } @@ -190,12 +176,12 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer { } private void on_inner_scroll(Gtk.Adjustment adj) { - // double delta = adj.value - this.inner_scroll_adj_value; - // this.inner_scroll_adj_value = adj.value; - // if (delta != 0 && !setting_inner_scroll) { - // Gtk.Adjustment outer_adj = this.conversation_viewer.web_view.vadjustment; - // outer_adj.set_value(outer_adj.value + delta); - // } + double delta = adj.value - this.inner_scroll_adj_value; + this.inner_scroll_adj_value = adj.value; + if (delta != 0 && !this.setting_inner_scroll) { + Gtk.Adjustment outer_adj = outer_scroller.vadjustment; + this.outer_adj.set_value(outer_adj.value + delta); + } } private void on_adjust_changed(Gtk.Adjustment adj) { @@ -225,30 +211,21 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer { if (view_height != inner_view_height || min_height != base_height + MIN_EDITOR_HEIGHT) { this.inner_view_height = view_height; this.min_height = base_height + MIN_EDITOR_HEIGHT; + // Calculate height widget should be to avoid scrolling in editor - // int widget_height = int.max(view_height + base_height - 2, min_height); //? about 2 - // WebKit.DOM.Element embed = this.conversation_viewer.web_view - // .get_dom_document().get_element_by_id(this.embed_id); - // if (embed != null) { - // try { - // embed.style.set_property("height", @"$widget_height", ""); - // } catch (Error error) { - // debug("Error setting height of composer widget"); - // } - // } + int widget_height = int.max(view_height + base_height - 2, min_height); //? about 2 + set_size_request(-1, widget_height); } return false; } private bool on_inner_scroll_event(Gdk.EventScroll event) { - //this.conversation_viewer.web_view.scroll_event(event); + this.outer_scroller.scroll_event(event); return true; } public void present() { - this.top_window.present(); - // this.conversation_viewer.web_view.get_dom_document().get_element_by_id(this.embed_id) - // .scroll_into_view_if_needed(false); + top_window.present(); } public void vanish() { @@ -256,20 +233,12 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer { this.composer.state = ComposerWidget.ComposerState.DETACHED; this.composer.editor.focus_in_event.disconnect(on_focus_in); this.composer.editor.focus_out_event.disconnect(on_focus_out); - - // WebKit.DOM.Element embed = this.conversation_viewer.web_view.get_dom_document(). - // get_element_by_id(this.embed_id); - // try{ - // embed.parent_element.remove_child(embed); - // } catch (Error error) { - // warning("Could not remove embed from WebView: %s", error.message); - // } + vanished(); } public void close_container() { if (visible) vanish(); - this.conversation_viewer.compose_overlay.remove(this); } } diff --git a/src/client/conversation-viewer/conversation-viewer.vala b/src/client/conversation-viewer/conversation-viewer.vala index 96cf2758..4712b649 100644 --- a/src/client/conversation-viewer/conversation-viewer.vala +++ b/src/client/conversation-viewer/conversation-viewer.vala @@ -86,9 +86,6 @@ public class ConversationViewer : Gtk.Stack { // Current conversation, or null if none. public Geary.App.Conversation? current_conversation = null; - // Overlay containing any inline composers. - public ScrollableOverlay compose_overlay; - // Stack pages [GtkChild] private Gtk.Image splash_page; @@ -135,13 +132,23 @@ public class ConversationViewer : Gtk.Stack { public ConversationViewer() { // Setup the conversation list box conversation_listbox.set_sort_func((row1, row2) => { - return Geary.Email.compare_sent_date_ascending( - ((ConversationMessage) row1.get_child()).email, - ((ConversationMessage) row2.get_child()).email - ); + // If not a ConversationMessage, will be an + // embedded composer and should always be last. + ConversationMessage? msg1 = row1.get_child() as ConversationMessage; + if (msg1 == null) { + return 1; + } + ConversationMessage? msg2 = row2.get_child() as ConversationMessage; + if (msg2 == null) { + return -1; + } + return Geary.Email.compare_sent_date_ascending(msg1.email, msg2.email); }); conversation_listbox.row_activated.connect((box, row) => { - if (email_to_row.size > 1) { + // If not a ConversationMessage, will be an + // embedded composer and should not be activated. + ConversationMessage? msg = row.get_child() as ConversationMessage; + if (email_to_row.size > 1 && msg != null) { toggle_show_message(row); } }); @@ -171,9 +178,6 @@ public class ConversationViewer : Gtk.Stack { GearyApplication.instance.controller.folder_selected.connect(on_folder_selected); GearyApplication.instance.controller.conversation_count_changed.connect(on_conversation_count_changed); - //compose_overlay = new ScrollableOverlay(web_view); - //conversation_viewer_scrolled.add(compose_overlay); - //conversation_find_bar = new ConversationFindBar(web_view); //conversation_find_bar.no_show_all = true; //conversation_find_bar.close.connect(() => { fsm.issue(SearchEvent.CLOSE_FIND_BAR); }); @@ -187,9 +191,10 @@ public class ConversationViewer : Gtk.Stack { } public Geary.Email? get_selected_message(out string? quote) { - // XXX - quote = ""; - return null; + // XXX check to see if there is a message with selected text, + // if so return that + quote = null; + return messages.is_empty ? null : messages.last(); } public void check_mark_read() { @@ -270,6 +275,30 @@ public class ConversationViewer : Gtk.Stack { set_visible_child(composer_page); } + public void do_embedded_composer(ComposerWidget composer, Geary.Email referred) { + state = ViewState.CONVERSATION; + + ComposerEmbed embed = new ComposerEmbed( + referred, composer, conversation_page + ); + embed.set_property("name", "composer_embed"); // Bug 764622 + + Gtk.ListBoxRow row = new Gtk.ListBoxRow(); + row.get_style_context().add_class("composer"); + row.get_style_context().add_class("frame"); + row.show(); + row.add(embed); + conversation_listbox.add(row); + + embed.loaded.connect((box) => { + row.grab_focus(); + }); + embed.vanished.connect((box) => { + conversation_listbox.remove(row); + }); + + } + // Removes all displayed e-mails from the view. private void clear() { foreach (Gtk.Widget child in conversation_listbox.get_children()) { diff --git a/ui/geary.css b/ui/geary.css index 5ccd07fa..5d85843b 100644 --- a/ui/geary.css +++ b/ui/geary.css @@ -58,7 +58,7 @@ row.geary-folder-popover-list-row > label { } #conversation_listbox { - padding: 18px 18px 0; + padding: 18px 18px calc(18px/2); } #conversation_listbox > row { margin: 0; @@ -67,8 +67,9 @@ row.geary-folder-popover-list-row > label { box-shadow: 0 4px 8px 1px rgba(0,0,0,0.4); transition: margin 0.1s; } -#conversation_listbox > row.show-message { - margin-bottom: 18px; +#conversation_listbox > row.show-message, +#conversation_listbox > row.composer { + margin-bottom: calc(18px/2); border-bottom-width: 1px; } @@ -81,3 +82,7 @@ row.geary-folder-popover-list-row > label { #ConversationMessage separator { margin: 12px 0; } + +#composer_embed headerbar { + border-radius: 0px; +}