[geary/wip/765516-gtk-widget-conversation-viewer: 57/107] Reenable and update code for attached, full pane message composer.



commit a9acc3645b80f57555e44370d60a5ddc95e85187
Author: Michael James Gratton <mike vee net>
Date:   Mon Apr 11 02:52:53 2016 +1000

    Reenable and update code for attached, full pane message composer.
    
    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/application/geary-controller.vala       |    2 +-
 src/client/composer/composer-box.vala              |   26 +---
 src/client/composer/composer-container.vala        |    9 +
 src/client/composer/composer-widget.vala           |    2 +-
 .../conversation-viewer/conversation-viewer.vala   |  173 +++++++++++---------
 ui/conversation-viewer.ui                          |   14 ++
 6 files changed, 128 insertions(+), 98 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index a194035..db8a519 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -2234,7 +2234,7 @@ public class GearyController : Geary.BaseObject {
         if (inline) {
             if (widget.state == ComposerWidget.ComposerState.NEW ||
                 widget.state == ComposerWidget.ComposerState.PANED)
-                main_window.conversation_viewer.set_paned_composer(widget);
+                main_window.conversation_viewer.do_compose(widget);
             else
                 new ComposerEmbed(widget, main_window.conversation_viewer, referred); // is_draft
         } else {
diff --git a/src/client/composer/composer-box.vala b/src/client/composer/composer-box.vala
index dd6344e..4a3b170 100644
--- a/src/client/composer/composer-box.vala
+++ b/src/client/composer/composer-box.vala
@@ -5,11 +5,13 @@
  */
 
 public class ComposerBox : Gtk.Frame, ComposerContainer {
-    
+
+
     private ComposerWidget composer;
-    private Gee.Set<Geary.App.Conversation>? prev_selection = null;
     private bool has_accel_group = false;
     
+    public signal void vanished();
+    
     public Gtk.Window top_window {
         get { return (Gtk.Window) get_toplevel(); }
     }
@@ -25,11 +27,6 @@ public class ComposerBox : Gtk.Frame, ComposerContainer {
         get_style_context().add_class("geary-composer-box");
 
         if (composer.state == ComposerWidget.ComposerState.NEW) {
-            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();
-            
             composer.free_header();
             GearyApplication.instance.controller.main_window.main_toolbar.set_conversation_header(
                 composer.header);
@@ -72,7 +69,6 @@ public class ComposerBox : Gtk.Frame, ComposerContainer {
     
     public void vanish() {
         hide();
-        parent.hide();
         if (get_style_context().has_class("geary-full-pane"))
             GearyApplication.instance.controller.main_window.main_toolbar.remove_conversation_header(
                 composer.header);
@@ -80,23 +76,13 @@ public class ComposerBox : Gtk.Frame, ComposerContainer {
         composer.state = ComposerWidget.ComposerState.DETACHED;
         composer.editor.focus_in_event.disconnect(on_focus_in);
         composer.editor.focus_out_event.disconnect(on_focus_out);
-        
-        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;
-        }
+
+        vanished();
     }
     
     public void close_container() {
         if (visible)
             vanish();
-        parent.remove(this);
     }
 }
 
diff --git a/src/client/composer/composer-container.vala b/src/client/composer/composer-container.vala
index 10366b2..57e97fd 100644
--- a/src/client/composer/composer-container.vala
+++ b/src/client/composer/composer-container.vala
@@ -5,11 +5,20 @@
  */
 
 public interface ComposerContainer {
+
     public abstract Gtk.Window top_window { get; }
     
+    // Shows the container also the composer.
     public abstract void present();
+
     public abstract unowned Gtk.Widget get_focus();
+
+    // Hides the container and hence also the composer.
     public abstract void vanish();
+
+    // Hides and destroys any resources associated with the container.
     public abstract void close_container();
+    
+    // Removes the composer from the container.
     public abstract void remove_composer();
 }
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 2308e6b..0120d95 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -1158,7 +1158,7 @@ public class ComposerWidget : Gtk.EventBox {
             return;
         container.remove_composer();
         GearyApplication.instance.controller.main_window.conversation_viewer
-            .set_paned_composer(this);
+            .do_compose(this);
         state = ComposerWidget.ComposerState.PANED;
     }
     
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index 0a27dfd..bbba767 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -27,6 +27,12 @@ public class ConversationViewer : Gtk.Stack {
     
     private const int SELECT_CONVERSATION_TIMEOUT_MSEC = 100;
 
+    private enum ViewState {
+        // Main view state
+        CONVERSATION,
+        COMPOSE;
+    }
+    
     private enum SearchState {
         // Search/find states.
         NONE,         // Not in search
@@ -92,6 +98,8 @@ public class ConversationViewer : Gtk.Stack {
     private Gtk.ScrolledWindow conversation_page;
     [GtkChild]
     private Gtk.Box user_message_page;
+    [GtkChild]
+    private Gtk.Box composer_page;
 
     // Conversation messages list
     [GtkChild]
@@ -101,9 +109,6 @@ public class ConversationViewer : Gtk.Stack {
     [GtkChild]
     private Gtk.Label user_message_label;
 
-    // Paned for holding any paned composers.
-    private Gtk.Box composer_boxes;
-    
     // List of emails in this view.
     private Gee.TreeSet<Geary.Email> messages { get; private set; default = 
         new Gee.TreeSet<Geary.Email>(Geary.Email.compare_sent_date_ascending); }
@@ -116,6 +121,7 @@ public class ConversationViewer : Gtk.Stack {
     private Geary.State.MachineDescriptor search_machine_desc = new Geary.State.MachineDescriptor(
         "ConversationViewer search", SearchState.NONE, SearchState.COUNT, SearchEvent.COUNT, null, null); 
    
+    private ViewState state = ViewState.CONVERSATION;
     private weak Geary.Folder? current_folder = null;
     private weak Geary.SearchFolder? search_folder = null;
     private Geary.App.EmailStore? email_store = null;
@@ -168,30 +174,12 @@ public class ConversationViewer : Gtk.Stack {
         //compose_overlay = new ScrollableOverlay(web_view);
         //conversation_viewer_scrolled.add(compose_overlay);
 
-        //Gtk.Paned composer_paned = new Gtk.Paned(Gtk.Orientation.VERTICAL);
-        //composer_boxes = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
-        //composer_boxes.no_show_all = true;
-        //composer_paned.pack2(composer_boxes, true, false);
-
-        //Configuration config = GearyApplication.instance.config;
-        //config.bind(Configuration.COMPOSER_PANE_POSITION_KEY, composer_paned, "position");
-
-        //composer_boxes.notify["visible"].connect(() => {
-        //    if (!composer_boxes.visible && !message_overlay.visible)
-        //        message_overlay.show();
-        //    });
-        //pack_start(composer_paned);
-        
         //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); });
         //pack_start(conversation_find_bar, false);
-    }
-    
-    public void set_paned_composer(ComposerWidget composer) {
-        ComposerBox container = new ComposerBox(composer);
-        composer_boxes.pack_start(container);
-        composer_boxes.show();
+
+        do_conversation();
     }
     
     public Geary.Email? get_last_message() {
@@ -254,6 +242,33 @@ public class ConversationViewer : Gtk.Stack {
         }
         email_to_row.get(id).show();
     }
+
+    public void do_conversation() {
+        state = ViewState.CONVERSATION;
+        set_visible_child(loading_page);
+    }
+    
+    public void do_compose(ComposerWidget composer) {
+        state = ViewState.COMPOSE;
+        ComposerBox box = new ComposerBox(composer);
+
+        // XXX move the ConversationListView management code into
+        // GearyController or somewhere more appropriate
+        ConversationListView conversation_list_view = ((MainWindow) 
GearyApplication.instance.controller.main_window).conversation_list_view;
+        Gee.Set<Geary.App.Conversation>? prev_selection = 
conversation_list_view.get_selected_conversations();
+        conversation_list_view.get_selection().unselect_all();
+        box.vanished.connect((box) => {
+                do_conversation();
+                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);
+                }
+            });
+        composer_page.pack_start(box);
+        set_visible_child(composer_page);
+    }
     
     // Removes all displayed e-mails from the view.
     private void clear() {
@@ -265,15 +280,7 @@ public class ConversationViewer : Gtk.Stack {
         current_conversation = null;
         cleared();
     }
-    
-    private void show_multiple_selected(uint selected_count) {
-        user_message_label.set_text(
-            ngettext("%u conversation selected.",
-                     "%u conversations selected.",
-                     selected_count).printf(selected_count));
-        set_visible_child(user_message_page);
-    }
-    
+
     private void on_folder_selected(Geary.Folder? folder) {
         current_folder = folder;
         have_conversations = false;
@@ -285,7 +292,9 @@ public class ConversationViewer : Gtk.Stack {
             current_account_information = null;
         }
 
-        set_visible_child(loading_page);
+        if (state == ViewState.CONVERSATION) {
+            set_visible_child(loading_page);
+        }
         
         if (current_folder is Geary.SearchFolder) {
             fsm.issue(SearchEvent.ENTER_SEARCH_FOLDER);
@@ -296,47 +305,51 @@ public class ConversationViewer : Gtk.Stack {
     }
     
     private void on_conversation_count_changed(int count) {
-        if (count != 0) {
-            have_conversations = true;
-            set_visible_child(conversation_page);
-        } else {
-            user_message_label.set_text((current_folder is Geary.SearchFolder)
-                                        ? _("No search results found.")
-                                        : _("No conversations in folder."));
-            set_visible_child(user_message_page);
+        if (state == ViewState.CONVERSATION) {
+            if (count > 0) {
+                have_conversations = true;
+                set_visible_child(conversation_page);
+            } else {
+                user_message_label.set_text(state == ViewState.CONVERSATION
+                                            ? _("No conversations in folder.")
+                                            : _("No search results found."));
+                set_visible_child(user_message_page);
+            }
         }
     }
     
     private void on_conversations_selected(Gee.Set<Geary.App.Conversation> conversations,
         Geary.Folder current_folder) {
-        cancel_load();
-
-        if (current_conversation != null) {
-            current_conversation.appended.disconnect(on_conversation_appended);
-            current_conversation.trimmed.disconnect(on_conversation_trimmed);
-            current_conversation.email_flags_changed.disconnect(update_flags);
-            current_conversation = null;
-        }
+        if (state == ViewState.CONVERSATION) {
         
-        // Disable message buttons until conversation loads.
-        GearyApplication.instance.controller.enable_message_buttons(false);
+            cancel_load();
+
+            if (current_conversation != null) {
+                current_conversation.appended.disconnect(on_conversation_appended);
+                current_conversation.trimmed.disconnect(on_conversation_trimmed);
+                current_conversation.email_flags_changed.disconnect(update_flags);
+                current_conversation = null;
+            }
         
-        if (!(current_folder is Geary.SearchFolder) &&
-            have_conversations &&
-            conversations.size == 0) {
-            set_visible_child(splash_page);
-            return;
-        }
+            // Disable message buttons until conversation loads.
+            GearyApplication.instance.controller.enable_message_buttons(false);
+
+            if (!(current_folder is Geary.SearchFolder) &&
+                have_conversations &&
+                conversations.size == 0) {
+                set_visible_child(splash_page);
+                return;
+            }
 
-        if (conversations.size == 1) {
-            clear();
-            //web_view.scroll_reset();
+            if (conversations.size == 1) {
+                clear();
+                //web_view.scroll_reset();
             
-            if (select_conversation_timeout_id != 0)
-                Source.remove(select_conversation_timeout_id);
+                if (select_conversation_timeout_id != 0)
+                    Source.remove(select_conversation_timeout_id);
             
-            // If the load is taking too long, display a spinner.
-            select_conversation_timeout_id =
+                // If the load is taking too long, display a spinner.
+                select_conversation_timeout_id =
                 Timeout.add(SELECT_CONVERSATION_TIMEOUT_MSEC, () => {
                         if (select_conversation_timeout_id != 0) {
                             set_visible_child(loading_page);
@@ -344,20 +357,20 @@ public class ConversationViewer : Gtk.Stack {
                         return false;
                     });
             
-            current_conversation = Geary.Collection.get_first(conversations);
-            
-            select_conversation_async.begin(current_conversation, current_folder,
-                on_select_conversation_completed);
-            
-            current_conversation.appended.connect(on_conversation_appended);
-            current_conversation.trimmed.connect(on_conversation_trimmed);
-            current_conversation.email_flags_changed.connect(update_flags);
+                current_conversation = Geary.Collection.get_first(conversations);
             
-            GearyApplication.instance.controller.enable_message_buttons(true);
-        } else if (conversations.size > 1) {
-            show_multiple_selected(conversations.size);
+                select_conversation_async.begin(current_conversation, current_folder,
+                                                on_select_conversation_completed);
             
-            GearyApplication.instance.controller.enable_multiple_message_buttons();
+                current_conversation.appended.connect(on_conversation_appended);
+                current_conversation.trimmed.connect(on_conversation_trimmed);
+                current_conversation.email_flags_changed.connect(update_flags);
+                
+                GearyApplication.instance.controller.enable_message_buttons(true);
+            } else if (conversations.size > 1) {
+                show_multiple_selected(conversations.size);
+                GearyApplication.instance.controller.enable_multiple_message_buttons();
+            }
         }
     }
     
@@ -397,6 +410,14 @@ public class ConversationViewer : Gtk.Stack {
         }
     }
     
+    private void show_multiple_selected(uint selected_count) {
+        user_message_label.set_text(
+            ngettext("%u conversation selected.",
+                     "%u conversations selected.",
+                     selected_count).printf(selected_count));
+        set_visible_child(user_message_page);
+    }
+    
     private void on_search_text_changed(Geary.SearchQuery? query) {
         if (query != null)
             highlight_search_terms.begin();
diff --git a/ui/conversation-viewer.ui b/ui/conversation-viewer.ui
index b08bb26..41ffa01 100644
--- a/ui/conversation-viewer.ui
+++ b/ui/conversation-viewer.ui
@@ -87,5 +87,19 @@
         <property name="position">3</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkBox" id="composer_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="name">composer_page</property>
+        <property name="position">4</property>
+      </packing>
+    </child>
   </template>
 </interface>


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