Make ComposerWidget::close method handle a lot more common code,
allowing many handlers to be simplified. Make access for some properties
more private and add accessors as appropriate, replace some "notify is
too hard" singnals with actual notify calls. Rename a few other
properties to better indicate what they do. Reintroduce `is-draft`
argument to ::load so we can accurately determine if we are loading a
draft, and so the `draft_id` param can be removed from the ctor.
Introduce a ::set_enabled method that can be used to disable and hide
the composer before closing it. Rename ::change_compose_type to
::append_to_email and reduce its scope drastically.
Drastically simplify ComposerContainer's API and its implementing
classes, reducing the API surface down to a single method call. Ensure
its properties that could be null are nullable, update call sites.
Remove dead code in all of the above classes, add more API docs.
Rename all composer classes prefixed with "Composer" so that the prefix
is a namespace instead. This increases the compartmentalisation of the
classes, making `internal` a useful member modifier and makes them
consistent with the code style guide.
* src/client/conversation-viewer/conversation-listbox.vala
(ConversationListBox): Keep track of the draft id currently being
edited, don't add it to the conversation when appended.
* src/client/composer/composer-container.vala (ComposerContainer): Make
the container's composer internal so we can hook into its
draft_id_changed signal. Update implementing classes.
* src/client/composer/composer-box.vala,
src/client/composer/composer-embed.vala: Use vexpand so as to work
with GtkGrid, use consistent GTK CSS classes.
Calling destroy ensures the composer widget cleans up after itself, maybe
because of the signal handlers added in ConversationViewer::do_compose
and ConversationListBox::add_embedded_composer?
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.
Scrolls to the first expanded row (first unread, or last email) in the
conversation list box to the top when the convo is fully loaded. To
implement this cleanly, ConversationViewer's handling of ListBoxRows was
cleaned up significantly by introducing a custom subclass and moving
related funtionality there.
* src/client/conversation-viewer/conversation-viewer.vala (EmailRow): New
class for managing expanded and last row state, events needed to ensure
we can robustly scroll to the row after its message has been loaded.
(ConversationViewer::scroll_to_top): New method for scrolling to a
specific row.
(ConversationViewer::update_last_row): New method for correctly
updating the last_email_row property and the row's flags. Replace
existing ad-hoc methods of determining the last row and ensure that the
last_email_row is used instead.
(ConversationViewer::select_conversation_async): Find the first
expanded row in the newly loaded conversation, and wire it up so that
it is scrolled to when the email body is eventually loaded, and the
resulting size reallocations have taken place.
* src/client/conversation-viewer/conversation-web-view.vala
(ConversationWebView::is_height_valid): Allows checking if the web
view's height is considered to have been correctly calculated.
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.
Now using these instead of the old composer's actions. This led to quite
some changes:
* Use GLib.ActionEntry instead of Gtk.ActionEntry in
composer-widget.vala
* Action names can now be specified in the UI files.
* Use templates for the ComposerHeaderBar. Remove
Pillbar as superclass, since that was no longer necessary.
* Merge ComposerToolbar into ComposerWidget.
* Since actions can now be parameterized, some methods could be
merged (e.g. font size methods).
* The menu button in the composer now automatically uses a popover.
* Some methods and classes really deserved more comments.
* necessary POTFILES.in changes
Signed-off-by: Niels De Graef <nielsdegraef@gmail.com>
Bug 764812
* src/client/components/main-window.vala (MainWindow::set_styling): Merge
CSS blocks. Fix Gtk.Frame styling rules for Gtk3.20, making them also
apply to the frame's border node instead of the frame node. Remove
redundant rules. Add a prefix for CSS class names so to avoid name
collisions.
* src/client/composer/composer-box.vala (ComposerBox::ComposerBox): Add a
CSS class to the composer box, add prefix to the full-pane class.
* ui/composer.glade: Add a class to the composer's frame so that can be
styled.
It used to be that all embeded composers had the headerbar inside
themselves, so the ComposerWindow only had to remove it if necessary.
But the new new-composer state doesn't have this, so we have to be
sure. To assist in this, the ComposerWidget now has embed_header() and
free_header() methods.
https://bugzilla.gnome.org/show_bug.cgi?id=746061
This allows us to avoid messing with the state of the conversation
viewer when we're composing a new message. Instead, we hide it
completely and show only the ComposerBox.
The styling of paned composer is changed to resemble that of the inline
composers. Because of restrictions on what styles are available for
various widgets, the ComposerBox becomes a Gtk.Frame, and its border
simulates the margin while some padding and an inset shadow simulate the
border. I haven't figured out how to do an outset box-shadow.
https://bugzilla.gnome.org/show_bug.cgi?id=743670
When the user replies with a quote to a second message, the composer
moves into a paned below the conversation viewer. This makes it easy to
scroll through the conversation and select text for replies.
The Gtk.Paned acutally holds a Box, which in turn can hold many
ComposerBoxes. Only one is shown at a time, but the model used
elsewhere is that each ComposerWidget has a ComposerContainer until it
is destroyed. When a composer is closed, it hides while finishing up
asynchronous work. This allows us to hold hidden paned composers as
they finish up their work.
The logic for focus handling at detachment is moved into the
ComposerWidget from ComposerEmbed, since it may also be detached from
the paned state. ComposerContainers gain a remove_composer() method
that does the container's clean up, as well as returning the focused
widget. The ComposerWindow's remove_composer() method should never be
called.
https://bugzilla.gnome.org/show_bug.cgi?id=738188