Commit graph

23 commits

Author SHA1 Message Date
Michael Gratton
44fd56588b Clean up the Composer API
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.
2019-11-17 20:00:02 +11:00
Michael Gratton
29042bb2d8 Move composer classes into their own namespace
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.
2019-11-17 20:00:02 +11:00
Michael Gratton
9eead5d145 Replace composer keyboard shortcut with standard widget action scoping
Rather than adding and removing shortcuts when the composer's web view
gains and loses focus to avoid invoking main window shortcuts, just
rely on standard GTK action scoping rules.

This fixes editing shortcuts like Ctrl+I breaking when clicking on
toolbar buttons, a crasher because the composer left the undo button
enabled after it was closed, and allows Escape to close the composer
from anywherre.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=774651,
https://bugzilla.gnome.org/show_bug.cgi?id=785187, and
https://bugzilla.gnome.org/show_bug.cgi?id=741741
2019-02-13 23:25:58 +11:00
Michael James Gratton
b545eaedaa Don't append in-progress drafts to a conversation.
* 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.
2016-10-04 10:58:17 +11:00
Michael James Gratton
096de14831 Minor composer container cleanup. 2016-10-04 10:58:17 +11:00
Michael James Gratton
c0a9de8726 Update composer container style implementations a bit.
* 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.
2016-10-04 10:58:17 +11:00
Michael James Gratton
b5efee10b1 Fix in-window and in-comversation composers not getting cleaned up.
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?
2016-10-04 10:58:17 +11:00
Michael James Gratton
d467647153 Break out ListBox used to display conversations into standalone widget.
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.
2016-10-04 10:58:17 +11:00
Michael James Gratton
9f1854548d Scroll to a useful location when a conversation is first loaded.
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.
2016-10-04 10:58:17 +11:00
Michael James Gratton
69a53d9db9 Reenable and update code for embedded message composer.
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.
2016-10-04 10:58:17 +11:00
Michael James Gratton
5184a38fe8 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.
2016-10-04 10:58:17 +11:00
Niels De Graef
ebd788968b Use GLib.Actions in the composer. Bug 770356.
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>
2016-09-21 15:02:18 +10:00
Michael James Gratton
8491cd50bc Remove GTK+ 3.14 check when setting widget CSS, modernise it a bit.
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.
2016-05-20 16:29:35 +10:00
Adam Dingle
654e513f9c Transfer Yorba copyrights to Software Freedom Conservancy 2016-05-06 08:33:37 -04:00
Robert Schroll
72b2648248 Don't set composer title when inline new
https://bugzilla.gnome.org/show_bug.cgi?id=746134
2015-03-20 18:48:58 -04:00
Robert Schroll
cbed345d2d Clear composer header title when detaching window
Under Unity, we don't want this set when detached.  Under others, this
will be reset when we set the headerbar to be the titlebar.

https://bugzilla.gnome.org/show_bug.cgi?id=746502
2015-03-20 16:26:21 -04:00
Robert Schroll
221c196db8 Ensure the headerbar is visible for all detached composers
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
2015-03-11 21:40:29 -04:00
Robert Schroll
bfaeee6229 Call g_binding_unbind directly, since it isn't bound for Vala < 0.26
https://bugzilla.gnome.org/show_bug.cgi?id=746057
2015-03-11 21:31:01 -04:00
Robert Schroll
1fec04a014 Set title of composer headerbar segment from subject 2015-03-11 18:15:30 -04:00
Robert Schroll
32cd33a158 Use composer headerbar for main window when composing new messages 2015-03-11 18:15:30 -04:00
Robert Schroll
9ec9913a55 Set the focus on a composer detached using the detach button
Also, simplify the focus discovery code.

https://bugzilla.gnome.org/show_bug.cgi?id=744077
2015-02-10 18:05:37 -05:00
Robert Schroll
787e92e731 Host new composers in ComposerBox, not in ComposerEmbed
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
2015-02-02 16:38:28 -05:00
Robert Schroll
526f6e7889 Paned composer for handling multi-replies
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
2015-01-14 15:16:08 -08:00