[geary/wip/713739-inline: 5/37] Compose new messages inline, with no conversation selected



commit 71bc05aa7bc1bfe74ea86c1a50a62637ab4c2343
Author: Robert Schroll <rschroll gmail com>
Date:   Sat May 25 13:27:00 2013 -0400

    Compose new messages inline, with no conversation selected

 src/client/composer/composer-embed.vala            |   27 +++++++++++++++--
 .../conversation-list/conversation-list-view.vala  |   26 ++++++++++++++++-
 .../conversation-viewer/conversation-viewer.vala   |    5 +++
 theming/message-viewer.css                         |   30 ++++++++++++++++++-
 4 files changed, 80 insertions(+), 8 deletions(-)
---
diff --git a/src/client/composer/composer-embed.vala b/src/client/composer/composer-embed.vala
index ee3377c..f7d63e7 100644
--- a/src/client/composer/composer-embed.vala
+++ b/src/client/composer/composer-embed.vala
@@ -10,10 +10,14 @@ public class ComposerEmbed : Gtk.Box, ComposerContainer {
     
     private ComposerWidget? composer = null;
     private ConversationViewer conversation_viewer;
+    private Gee.Set<Geary.App.Conversation>? prev_selection = null;
     
     public Gtk.Window top_window {
         get { return (Gtk.Window) get_toplevel(); }
     }
+    public bool is_active {
+        get { return composer != null; }
+    }
     
     public ComposerEmbed(ConversationViewer conversation_viewer) {
         Object(orientation: Gtk.Orientation.VERTICAL);
@@ -45,15 +49,19 @@ public class ComposerEmbed : Gtk.Box, ComposerContainer {
             email_element = conversation_viewer.web_view.get_dom_document().get_element_by_id(
                 conversation_viewer.get_div_id(referred.id)) as WebKit.DOM.HTMLElement;
         if (email_element == null) {
-            // TODO: clear conversation list selection and put in alone
-            new ComposerWindow(new_composer);
-            return;
+            ConversationListView conversation_list_view = ((MainWindow) GearyApplication.
+                instance.controller.main_window).conversation_list_view;
+            prev_selection = conversation_list_view.get_selected_conversations();
+            conversation_list_view.get_selection().unselect_all();
+            email_element = conversation_viewer.web_view.get_dom_document().get_element_by_id(
+                "placeholder") as WebKit.DOM.HTMLElement;
         }
         
         try {
+            conversation_viewer.show_conversation_div();
             conversation_viewer.web_view.settings.enable_plugins = true;
             email_element.insert_adjacent_html("afterend",
-                @"<embed width='100%' height='600' type='composer' id='$embed_id' />");
+                @"<div id='$embed_id'><embed type='composer' /></div>");
         } catch (Error error) {
             debug("Error creating embed element: %s", error.message);
             return;
@@ -134,6 +142,17 @@ public class ComposerEmbed : Gtk.Box, ComposerContainer {
         } catch (Error error) {
             warning("Could not remove embed from WebView: %s", error.message);
         }
+        
+        if (prev_selection != null) {
+            ConversationListView conversation_list_view = ((MainWindow) GearyApplication.
+                instance.controller.main_window).conversation_list_view;
+            if (prev_selection.is_empty)
+                // Need to trigger "No messages selected"
+                conversation_list_view.conversations_selected(prev_selection);
+            else
+                conversation_list_view.select_conversations(prev_selection);
+            prev_selection = null;
+        }
     }
 }
 
diff --git a/src/client/conversation-list/conversation-list-view.vala 
b/src/client/conversation-list/conversation-list-view.vala
index 138762f..bf431a5 100644
--- a/src/client/conversation-list/conversation-list-view.vala
+++ b/src/client/conversation-list/conversation-list-view.vala
@@ -353,6 +353,18 @@ public class ConversationListView : Gtk.TreeView {
         return visible_conversations;
     }
     
+    public Gee.Set<Geary.App.Conversation> get_selected_conversations() {
+        Gee.HashSet<Geary.App.Conversation> selected_conversations = new 
Gee.HashSet<Geary.App.Conversation>();
+        
+        foreach (Gtk.TreePath path in get_all_selected_paths()) {
+            Geary.App.Conversation? conversation = conversation_list_store.get_conversation_at_path(path);
+            if (path != null)
+                selected_conversations.add(conversation);
+        }
+        
+        return selected_conversations;
+    }
+    
     // Always returns false, so it can be used as a one-time SourceFunc
     private bool update_visible_conversations() {
         Gee.Set<Geary.App.Conversation> visible_conversations = get_visible_conversations();
@@ -373,9 +385,10 @@ public class ConversationListView : Gtk.TreeView {
         scheduled_update_visible_conversations = Geary.Scheduler.on_idle(update_visible_conversations);
     }
     
-    // Selects the first conversation, if nothing has been selected yet.
+    // Selects the first conversation, if nothing has been selected yet and we're not composing.
     public void select_first_conversation() {
-        if (get_selected_path() == null) {
+        if (get_selected_path() == null && !((MainWindow) GearyApplication.instance.
+            controller.main_window).composer_embed.is_active) {
             set_cursor(new Gtk.TreePath.from_indices(0, -1), null, false);
         }
     }
@@ -386,6 +399,15 @@ public class ConversationListView : Gtk.TreeView {
             set_cursor(path, null, false);
     }
     
+    public void select_conversations(Gee.Set<Geary.App.Conversation> conversations) {
+        Gtk.TreeSelection selection = get_selection();
+        foreach (Geary.App.Conversation conversation in conversations) {
+            Gtk.TreePath path = conversation_list_store.get_path_for_conversation(conversation);
+            if (path != null)
+                selection.select_path(path);
+        }
+    }
+    
     private void on_row_deleted(Gtk.TreePath path) {
         // if one or more rows are deleted in the model, reset the last upper limit so scrolling to
         // the bottom will always activate a reload (this is particularly important if the model
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index ecad528..5ab0676 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -2154,5 +2154,10 @@ public class ConversationViewer : Gtk.Box {
         return current_folder != null && current_folder.special_folder_type
             == Geary.SpecialFolderType.DRAFTS;
     }
+    
+    // The Composer may need to adjust the mode back to conversation
+    public void show_conversation_div() {
+        set_mode(DisplayMode.CONVERSATION);
+    }
 }
 
diff --git a/theming/message-viewer.css b/theming/message-viewer.css
index 6df04cf..9aa6b94 100644
--- a/theming/message-viewer.css
+++ b/theming/message-viewer.css
@@ -88,7 +88,7 @@ hr {
     box-shadow: inset 0px 0px 1px rgba(0,0,0,0.05);
 }
 
-.email {
+.email, #composer_embed {
     border: 1px rgba(0,0,0,1) solid;
     background-color: white;/* recv-normal */
     color: black;
@@ -101,6 +101,30 @@ hr {
     margin-top: 16px;
 }
 
+#composer_embed {
+    position: absolute;
+    top: 0px; /* margin-top has impact here, despite absolute positioning (!?) */
+    bottom: 16px;
+    left: 16px;
+    right: 16px;
+    width: auto;
+}
+.email + #composer_embed {
+    position: relative;
+    top: auto;
+    bottom: auto;
+    left: auto;
+    right: auto;
+    width: 100%;
+    height: 600px;
+}
+/* For some reason, we can't absolutely position <embed>s or <object>s, so we wrap everything
+   it in a div and then tell the <embed> to take up all the available space. */
+#composer_embed > embed {
+    width: 100%;
+    height: 100%;
+}
+
 .email.sent {
     background-color: white;/* sent-normal */
 }
@@ -117,7 +141,7 @@ hr {
 .email.starred .unstarred {
     display: none;
 }
-.email.read, #multiple_messages .email {
+.email.read, #multiple_messages .email, #composer_embed {
     border-color: rgba(0,0,0,0.4);
     box-shadow: 0 3px 11px rgba(0,0,0,0.21);
 }
@@ -553,6 +577,8 @@ body:not(.nohide) .quote_container.controllable.show > .hider {
     left: 0;
     right: 0;
     padding: 0 15px 15px;
+    box-sizing: border-box;
+    min-height: 100%;
 }
 #multiple_messages {
     display: none;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]