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>
This commit is contained in:
Niels De Graef 2016-08-22 11:09:25 +02:00 committed by Michael Gratton
parent 5a53da3cba
commit ebd788968b
19 changed files with 2197 additions and 2051 deletions

View file

@ -39,7 +39,6 @@ src/client/composer/composer-box.vala
src/client/composer/composer-container.vala
src/client/composer/composer-embed.vala
src/client/composer/composer-headerbar.vala
src/client/composer/composer-toolbar.vala
src/client/composer/composer-widget.vala
src/client/composer/composer-window.vala
src/client/composer/contact-entry-completion.vala
@ -384,8 +383,9 @@ src/mailer/main.vala
[type: gettext/glade]ui/account_spinner.glade
[type: gettext/glade]ui/app_menu.interface
[type: gettext/glade]ui/certificate_warning_dialog.glade
[type: gettext/glade]ui/composer_accelerators.ui
[type: gettext/glade]ui/composer.glade
[type: gettext/glade]ui/composer-headerbar.ui
[type: gettext/glade]ui/composer-menus.ui
[type: gettext/glade]ui/composer-widget.ui
[type: gettext/glade]ui/edit_alternate_emails.glade
[type: gettext/glade]ui/find_bar.glade
[type: gettext/glade]ui/login.glade

View file

@ -348,7 +348,6 @@ client/composer/composer-box.vala
client/composer/composer-container.vala
client/composer/composer-embed.vala
client/composer/composer-headerbar.vala
client/composer/composer-toolbar.vala
client/composer/composer-widget.vala
client/composer/composer-window.vala
client/composer/contact-entry-completion.vala

View file

@ -2199,7 +2199,16 @@ public class GearyController : Geary.BaseObject {
bool is_draft = false) {
create_compose_widget_async.begin(compose_type, referred, quote, mailto, is_draft);
}
/**
* Creates a composer widget. Depending on the arguments, this can be inline in the
* conversation or as a new window.
* @param compose_type - Whether it's a new message, a reply, a forwarded mail, ...
* @param referred - The mail of which we should copy the from/to/... addresses
* @param quote - The quote after the mail body
* @param mailto - A "mailto:"-link
* @param is_draft - Whether we're starting from a draft (true) or a new mail (false)
*/
private async void create_compose_widget_async(ComposerWidget.ComposeType compose_type,
Geary.Email? referred = null, string? quote = null, string? mailto = null,
bool is_draft = false) {

View file

@ -156,19 +156,6 @@ public class PillHeaderbar : Gtk.HeaderBar, PillBar {
public PillHeaderbar(Gtk.ActionGroup toolbar_action_group) {
initialize(toolbar_action_group);
}
public bool close_button_at_end() {
string layout;
bool at_end = false;
layout = Gtk.Settings.get_default().gtk_decoration_layout;
// Based on logic of close_button_at_end in gtkheaderbar.c: Close button appears
// at end iff "close" follows a colon in the layout string.
if (layout != null) {
int colon_ind = layout.index_of(":");
at_end = (colon_ind >= 0 && layout.index_of("close", colon_ind) >= 0);
}
return at_end;
}
}
/**

View file

@ -4,95 +4,78 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* A ComposerBox is a ComposerContainer that is used to compose mails in the main-window
* (i.e. not-detached), yet separate from a conversation.
*/
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 Gtk.Window top_window {
get { return (Gtk.Window) get_toplevel(); }
protected ComposerWidget composer { get; set; }
protected Gee.MultiMap<string, string>? old_accelerators { get; set; }
public Gtk.ApplicationWindow top_window {
get { return (Gtk.ApplicationWindow) get_toplevel(); }
}
public ComposerBox(ComposerWidget composer) {
this.composer = composer;
add(composer);
composer.editor.focus_in_event.connect(on_focus_in);
composer.editor.focus_out_event.connect(on_focus_out);
add(this.composer);
this.composer.editor.focus_in_event.connect(on_focus_in);
this.composer.editor.focus_out_event.connect(on_focus_out);
show();
get_style_context().add_class("geary-composer-box");
if (composer.state == ComposerWidget.ComposerState.NEW) {
if (this.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();
this.prev_selection = conversation_list_view.get_selected_conversations();
conversation_list_view.get_selection().unselect_all();
composer.free_header();
this.composer.free_header();
GearyApplication.instance.controller.main_window.main_toolbar.set_conversation_header(
composer.header);
get_style_context().add_class("geary-full-pane");
}
}
public void remove_composer() {
if (composer.editor.has_focus)
if (this.composer.editor.has_focus)
on_focus_out();
composer.editor.focus_in_event.disconnect(on_focus_in);
composer.editor.focus_out_event.disconnect(on_focus_out);
remove(composer);
this.composer.editor.focus_in_event.disconnect(on_focus_in);
this.composer.editor.focus_out_event.disconnect(on_focus_out);
remove(this.composer);
close_container();
}
private bool on_focus_in() {
// For some reason, on_focus_in gets called a bunch upon construction.
if (!has_accel_group)
top_window.add_accel_group(composer.ui.get_accel_group());
has_accel_group = true;
return false;
}
private bool on_focus_out() {
top_window.remove_accel_group(composer.ui.get_accel_group());
has_accel_group = false;
return false;
}
public void present() {
top_window.present();
}
public unowned Gtk.Widget get_focus() {
return top_window.get_focus();
}
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);
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) {
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);
if (this.prev_selection != null) {
ConversationListView conversation_list_view = ((MainWindow) GearyApplication.
instance.controller.main_window).conversation_list_view;
if (prev_selection.is_empty)
if (this.prev_selection.is_empty)
// Need to trigger "No messages selected"
conversation_list_view.conversations_selected(prev_selection);
conversation_list_view.conversations_selected(this.prev_selection);
else
conversation_list_view.select_conversations(prev_selection);
prev_selection = null;
conversation_list_view.select_conversations(this.prev_selection);
this.prev_selection = null;
}
}
public void close_container() {
if (visible)
vanish();

View file

@ -4,12 +4,129 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* A generic interface for widgets that have a single ComposerWidget-child.
*/
public interface ComposerContainer {
public abstract Gtk.Window top_window { get; }
public abstract void present();
public abstract unowned Gtk.Widget get_focus();
public abstract void vanish();
// The ComposerWidget-child.
protected abstract ComposerWidget composer { get; set; }
// Workaround to retrieve all Gtk.Actions with conflicting accelerators
protected const string[] conflicting_actions = {
GearyController.ACTION_MARK_AS_UNREAD,
GearyController.ACTION_FORWARD_MESSAGE
};
// We use old_accelerators to keep track of the accelerators we temporarily disabled.
protected abstract Gee.MultiMap<string, string>? old_accelerators { get; set; }
// The toplevel window for the container. Note that it needs to be a GtkApplicationWindow.
public abstract Gtk.ApplicationWindow top_window { get; }
public virtual void present() {
this.top_window.present();
}
public virtual unowned Gtk.Widget get_focus() {
return this.top_window.get_focus();
}
public abstract void close_container();
/**
* Hides the widget (and possibly its parent). Usecase is when you don't want to close just yet
* but the composer should not be visible any longer (e.g. when you're still saving a draft).
*/
public abstract void vanish();
/**
* Removes the composer from this ComposerContainer (e.g. when detaching)
*/
public abstract void remove_composer();
protected virtual bool on_focus_in() {
if (this.old_accelerators == null) {
this.old_accelerators = new Gee.HashMultiMap<string, string>();
add_accelerators();
}
return false;
}
protected virtual bool on_focus_out() {
if (this.old_accelerators != null) {
remove_accelerators();
this.old_accelerators = null;
}
return false;
}
/**
* Adds the accelerators for the child composer, and temporarily removes conflicting
* accelerators from existing actions.
*/
protected virtual void add_accelerators() {
GearyApplication app = GearyApplication.instance;
// Check for actions with conflicting accelerators
foreach (string action in ComposerWidget.action_accelerators.get_keys()) {
foreach (string accelerator in ComposerWidget.action_accelerators[action]) {
string[] actions = app.get_actions_for_accel(accelerator);
foreach (string conflicting_action in actions) {
remove_conflicting_accelerator(conflicting_action, accelerator);
this.old_accelerators[conflicting_action] = accelerator;
}
}
}
// Very stupid workaround while we still use Gtk.Actions in the GearyController
foreach (string conflicting_action in conflicting_actions)
app.actions.get_action(conflicting_action).disconnect_accelerator();
// Now add our actions to the window and their accelerators
foreach (string action in ComposerWidget.action_accelerators.get_keys()) {
this.top_window.add_action(composer.get_action(action));
app.set_accels_for_action("win." + action,
ComposerWidget.action_accelerators[action].to_array());
}
}
/**
* Removes the accelerators for the child composer, and restores previously removed accelerators.
*/
protected virtual void remove_accelerators() {
foreach (string action in ComposerWidget.action_accelerators.get_keys())
GearyApplication.instance.set_accels_for_action("win." + action, {});
// Very stupid workaround while we still use Gtk.Actions in the GearyController
foreach (string conflicting_action in conflicting_actions)
GearyApplication.instance.actions.get_action(conflicting_action).connect_accelerator();
foreach (string action in old_accelerators.get_keys())
foreach (string accelerator in this.old_accelerators[action])
restore_conflicting_accelerator(action, accelerator);
}
// Helper method. Removes the given conflicting accelerator from the action's accelerators.
private void remove_conflicting_accelerator(string action, string accelerator) {
GearyApplication app = GearyApplication.instance;
string[] accelerators = app.get_accels_for_action(action);
if (accelerators.length == 0)
return;
string[] without_accel = new string[accelerators.length - 1];
foreach (string a in accelerators)
if (a != accelerator)
without_accel += a;
app.set_accels_for_action(action, without_accel);
}
// Helper method. Adds the given accelerator back to the action's accelerators.
private void restore_conflicting_accelerator(string action, string accelerator) {
GearyApplication app = GearyApplication.instance;
string[] accelerators = app.get_accels_for_action(action);
accelerators += accelerator;
app.set_accels_for_action(action, accelerators);
}
}

View file

@ -4,41 +4,49 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* A ComposerEmbed is a widget that is used to compose emails that are inlined into a
* conversation view, e.g. for reply or forward mails.
*/
public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
private const int MIN_EDITOR_HEIGHT = 200;
private ComposerWidget composer;
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;
private bool has_accel_group = false;
public Gtk.Window top_window {
get { return (Gtk.Window) get_toplevel(); }
protected ComposerWidget composer { get; set; }
protected Gee.MultiMap<string, string>? old_accelerators { get; set; }
public Gtk.ApplicationWindow top_window {
get { return (Gtk.ApplicationWindow) get_toplevel(); }
}
public ComposerEmbed(ComposerWidget composer, ConversationViewer conversation_viewer,
Geary.Email referred) {
this.composer = composer;
this.conversation_viewer = conversation_viewer;
halign = Gtk.Align.FILL;
valign = Gtk.Align.FILL;
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";
this.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",
@"<div id='$embed_id' class='composer_embed'></div>");
@ -46,30 +54,30 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
debug("Error creating embed element: %s", error.message);
return;
}
add(composer);
realize.connect(on_realize);
composer.editor.focus_in_event.connect(on_focus_in);
composer.editor.focus_out_event.connect(on_focus_out);
composer.editor.document_load_finished.connect(on_loaded);
conversation_viewer.compose_overlay.add_overlay(this);
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() {
update_style();
Gtk.ScrolledWindow win = (Gtk.ScrolledWindow) composer.editor.parent;
Gtk.ScrolledWindow win = (Gtk.ScrolledWindow) this.composer.editor.parent;
win.get_vscrollbar().hide();
composer.editor.vadjustment.value_changed.connect(on_inner_scroll);
composer.editor.vadjustment.changed.connect(on_adjust_changed);
composer.editor.user_changed_contents.connect(on_inner_size_changed);
this.composer.editor.vadjustment.value_changed.connect(on_inner_scroll);
this.composer.editor.vadjustment.changed.connect(on_adjust_changed);
this.composer.editor.user_changed_contents.connect(on_inner_size_changed);
reroute_scroll_handling(this);
}
private void on_loaded() {
try {
composer.editor.get_dom_document().body.get_class_list().add("embedded");
@ -82,7 +90,7 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
return false;
});
}
private void reroute_scroll_handling(Gtk.Widget widget) {
widget.add_events(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK);
widget.scroll_event.connect(on_inner_scroll_event);
@ -92,7 +100,7 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
reroute_scroll_handling(child);
}
}
private void disable_scroll_reroute(Gtk.Widget widget) {
widget.scroll_event.disconnect(on_inner_scroll_event);
Gtk.Container? container = widget as Gtk.Container;
@ -101,44 +109,47 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
disable_scroll_reroute(child);
}
}
private void update_style() {
Gdk.RGBA window_background = top_window.get_style_context()
.get_background_color(Gtk.StateFlags.NORMAL);
Gdk.RGBA background = get_style_context().get_background_color(Gtk.StateFlags.NORMAL);
if (background == window_background)
return;
get_style_context().changed.disconnect(update_style);
override_background_color(Gtk.StateFlags.NORMAL, window_background);
get_style_context().changed.connect(update_style);
}
public void remove_composer() {
if (composer.editor.has_focus)
if (this.composer.editor.has_focus)
on_focus_out();
composer.editor.focus_in_event.disconnect(on_focus_in);
composer.editor.focus_out_event.disconnect(on_focus_out);
composer.editor.vadjustment.value_changed.disconnect(on_inner_scroll);
composer.editor.user_changed_contents.disconnect(on_inner_size_changed);
this.composer.editor.focus_in_event.disconnect(on_focus_in);
this.composer.editor.focus_out_event.disconnect(on_focus_out);
this.composer.editor.vadjustment.value_changed.disconnect(on_inner_scroll);
this.composer.editor.user_changed_contents.disconnect(on_inner_size_changed);
disable_scroll_reroute(this);
Gtk.ScrolledWindow win = (Gtk.ScrolledWindow) composer.editor.parent;
win.get_vscrollbar().show();
try {
composer.editor.get_dom_document().body.get_class_list().remove("embedded");
this.composer.editor.get_dom_document().body.get_class_list().remove("embedded");
} catch (Error error) {
debug("Error setting class of editor: %s", error.message);
}
remove(composer);
close_container();
}
public bool set_position(ref Gdk.Rectangle allocation, double hscroll, double vscroll,
int view_height) {
WebKit.DOM.Element embed = conversation_viewer.web_view.get_dom_document().get_element_by_id(embed_id);
WebKit.DOM.Element embed = this.conversation_viewer.web_view.get_dom_document()
.get_element_by_id(this.embed_id);
if (embed == null)
return false;
@ -162,76 +173,62 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
}
allocation.x = (int) (embed.offset_left + embed.client_left) - (int) hscroll;
allocation.width = (int) embed.client_width;
// Work out adjustment of composer web view
setting_inner_scroll = true;
composer.editor.vadjustment.set_value(allocation.y - y_top);
setting_inner_scroll = false;
this.setting_inner_scroll = true;
this.composer.editor.vadjustment.set_value(allocation.y - y_top);
this.setting_inner_scroll = false;
// This sets the scroll before the widget gets resized. Although the adjustment
// may be scrolled to the bottom right now, the current value may not do that
// once the widget is shrunk; for example, while scrolling down the page past
// the bottom of the editor. So if we're at the bottom, record that fact. When
// the limits of the adjustment are changed (watched by on_adjust_changed), we
// can keep it at the bottom.
scrolled_to_bottom = (y_top <= 0 && available_height < view_height);
this.scrolled_to_bottom = (y_top <= 0 && available_height < view_height);
return true;
}
private bool on_focus_in() {
// For some reason, on_focus_in gets called a bunch upon construction.
if (!has_accel_group)
top_window.add_accel_group(composer.ui.get_accel_group());
has_accel_group = true;
return false;
}
private bool on_focus_out() {
top_window.remove_accel_group(composer.ui.get_accel_group());
has_accel_group = false;
return false;
}
private void on_inner_scroll(Gtk.Adjustment adj) {
double delta = adj.value - inner_scroll_adj_value;
inner_scroll_adj_value = adj.value;
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 = conversation_viewer.web_view.vadjustment;
Gtk.Adjustment outer_adj = this.conversation_viewer.web_view.vadjustment;
outer_adj.set_value(outer_adj.value + delta);
}
}
private void on_adjust_changed(Gtk.Adjustment adj) {
if (scrolled_to_bottom) {
setting_inner_scroll = true;
if (this.scrolled_to_bottom) {
this.setting_inner_scroll = true;
adj.set_value(adj.upper);
setting_inner_scroll = false;
this.setting_inner_scroll = false;
}
}
private void on_inner_size_changed() {
scrolled_to_bottom = false; // The inserted character may cause a desired scroll
this.scrolled_to_bottom = false; // The inserted character may cause a desired scroll
Idle.add(recalc_height); // So that this runs after the character has been inserted
}
private bool recalc_height() {
int view_height,
base_height = get_allocated_height() - composer.editor.get_allocated_height();
base_height = get_allocated_height() - this.composer.editor.get_allocated_height();
try {
view_height = (int) composer.editor.get_dom_document()
view_height = (int) this.composer.editor.get_dom_document()
.query_selector("#message-body").offset_height;
} catch (Error error) {
debug("Error getting height of editor: %s", error.message);
return false;
}
if (view_height != inner_view_height || min_height != base_height + MIN_EDITOR_HEIGHT) {
inner_view_height = 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 = conversation_viewer.web_view
.get_dom_document().get_element_by_id(embed_id);
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", "");
@ -242,40 +239,37 @@ public class ComposerEmbed : Gtk.EventBox, ComposerContainer {
}
return false;
}
private bool on_inner_scroll_event(Gdk.EventScroll event) {
conversation_viewer.web_view.scroll_event(event);
this.conversation_viewer.web_view.scroll_event(event);
return true;
}
public void present() {
top_window.present();
conversation_viewer.web_view.get_dom_document().get_element_by_id(embed_id)
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);
}
public unowned Gtk.Widget get_focus() {
return top_window.get_focus();
}
public void vanish() {
hide();
composer.state = ComposerWidget.ComposerState.DETACHED;
composer.editor.focus_in_event.disconnect(on_focus_in);
composer.editor.focus_out_event.disconnect(on_focus_out);
WebKit.DOM.Element embed = conversation_viewer.web_view.get_dom_document().get_element_by_id(embed_id);
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);
}
}
public void close_container() {
if (visible)
vanish();
conversation_viewer.compose_overlay.remove(this);
this.conversation_viewer.compose_overlay.remove(this);
}
}

View file

@ -4,89 +4,42 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
public class ComposerHeaderbar : PillHeaderbar {
[GtkTemplate (ui = "/org/gnome/Geary/composer-headerbar.ui")]
public class ComposerHeaderbar : Gtk.HeaderBar {
public ComposerWidget.ComposerState state { get; set; }
public bool show_pending_attachments { get; set; default = false; }
public bool send_enabled { get; set; default = false; }
private Gtk.Button recipients;
private Gtk.Label recipients_label;
[GtkChild]
private Gtk.Box detach_start;
[GtkChild]
private Gtk.Box detach_end;
public ComposerHeaderbar(Gtk.ActionGroup action_group) {
base(action_group);
show_close_button = false;
bool rtl = (get_direction() == Gtk.TextDirection.RTL);
// Toolbar setup.
Gee.List<Gtk.Button> insert = new Gee.ArrayList<Gtk.Button>();
// Window management.
detach_start = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
Gtk.Button detach_button = create_toolbar_button(null, ComposerWidget.ACTION_DETACH);
detach_button.set_relief(Gtk.ReliefStyle.NONE);
if (rtl)
detach_button.set_margin_start(6);
else
detach_button.set_margin_end(6);
detach_start.pack_start(detach_button);
detach_start.pack_start(new Gtk.Separator(Gtk.Orientation.VERTICAL));
detach_end = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
detach_button = create_toolbar_button(null, ComposerWidget.ACTION_DETACH);
detach_button.set_relief(Gtk.ReliefStyle.NONE);
if (rtl)
detach_button.set_margin_end(6);
else
detach_button.set_margin_start(6);
detach_end.pack_end(detach_button);
detach_end.pack_end(new Gtk.Separator(Gtk.Orientation.VERTICAL));
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_CLOSE_DISCARD));
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_CLOSE_SAVE));
Gtk.Box close_buttons = create_pill_buttons(insert, false);
insert.clear();
Gtk.Button send_button = create_toolbar_button(null, ComposerWidget.ACTION_SEND, true);
send_button.get_style_context().add_class("suggested-action");
Gtk.Box attach_buttons = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
Gtk.Button attach_only = create_toolbar_button(null, ComposerWidget.ACTION_ADD_ATTACHMENT);
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_ADD_ATTACHMENT));
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_ADD_ORIGINAL_ATTACHMENTS));
Gtk.Box attach_pending = create_pill_buttons(insert, false);
attach_buttons.pack_start(attach_only);
attach_buttons.pack_start(attach_pending);
recipients = new Gtk.Button();
recipients.set_relief(Gtk.ReliefStyle.NONE);
recipients_label = new Gtk.Label(null);
recipients_label.set_ellipsize(Pango.EllipsizeMode.END);
recipients.add(recipients_label);
recipients.clicked.connect(() => { state = ComposerWidget.ComposerState.INLINE; });
bind_property("state", recipients, "visible", BindingFlags.SYNC_CREATE,
[GtkChild]
private Gtk.Button recipients_button;
[GtkChild]
private Gtk.Label recipients_label;
[GtkChild]
private Gtk.Button new_message_attach_button;
[GtkChild]
private Gtk.Box conversation_attach_buttons;
[GtkChild]
private Gtk.Button send_button;
public ComposerHeaderbar() {
recipients_button.clicked.connect(() => { state = ComposerWidget.ComposerState.INLINE; });
send_button.image = new Gtk.Image.from_icon_name("mail-send-symbolic", Gtk.IconSize.MENU);
bind_property("state", recipients_button, "visible", BindingFlags.SYNC_CREATE,
(binding, source_value, ref target_value) => {
target_value = (state == ComposerWidget.ComposerState.INLINE_COMPACT);
return true;
});
bind_property("show-pending-attachments", attach_only, "visible",
bind_property("show-pending-attachments", new_message_attach_button, "visible",
BindingFlags.SYNC_CREATE | BindingFlags.INVERT_BOOLEAN);
bind_property("show-pending-attachments", attach_pending, "visible",
bind_property("show-pending-attachments", conversation_attach_buttons, "visible",
BindingFlags.SYNC_CREATE);
bind_property("send-enabled", send_button, "sensitive", BindingFlags.SYNC_CREATE);
add_start(detach_start);
add_start(attach_buttons);
add_start(recipients);
add_end(detach_end);
add_end(send_button);
add_end(close_buttons);
notify["decoration-layout"].connect(set_detach_button_side);
realize.connect(set_detach_button_side);
@ -97,14 +50,14 @@ public class ComposerHeaderbar : PillHeaderbar {
}
});
}
public void set_recipients(string label, string tooltip) {
recipients_label.label = label;
recipients.tooltip_text = tooltip;
recipients_button.tooltip_text = tooltip;
}
private void set_detach_button_side() {
bool at_end = close_button_at_end();
bool at_end = GtkUtil.close_button_at_end();
detach_start.visible = !at_end;
detach_end.visible = at_end;
}

View file

@ -1,58 +0,0 @@
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
public class ComposerToolbar : PillToolbar {
public string label_text { get; set; }
public Gtk.Button select_dictionary_button;
public ComposerToolbar(Gtk.ActionGroup toolbar_action_group, Gtk.Menu menu) {
base(toolbar_action_group);
Gee.List<Gtk.Button> insert = new Gee.ArrayList<Gtk.Button>();
// Font formatting.
insert.add(create_toggle_button(null, ComposerWidget.ACTION_BOLD));
insert.add(create_toggle_button(null, ComposerWidget.ACTION_ITALIC));
insert.add(create_toggle_button(null, ComposerWidget.ACTION_UNDERLINE));
insert.add(create_toggle_button(null, ComposerWidget.ACTION_STRIKETHROUGH));
add_start(create_pill_buttons(insert, false, true));
// Indent level.
insert.clear();
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_INDENT));
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_OUTDENT));
add_start(create_pill_buttons(insert, false));
// Link.
insert.clear();
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_INSERT_LINK));
add_start(create_pill_buttons(insert));
// Remove formatting.
insert.clear();
insert.add(create_toolbar_button(null, ComposerWidget.ACTION_REMOVE_FORMAT));
add_start(create_pill_buttons(insert));
// Select dictionary
insert.clear();
select_dictionary_button = create_toolbar_button(null, ComposerWidget.ACTION_SELECT_DICTIONARY);
insert.add(select_dictionary_button);
add_start(create_pill_buttons(insert));
// Menu.
insert.clear();
insert.add(create_menu_button(null, menu, ComposerWidget.ACTION_MENU));
add_end(create_pill_buttons(insert));
Gtk.Label label = new Gtk.Label(null);
label.get_style_context().add_class("dim-label");
bind_property("label-text", label, "label", BindingFlags.SYNC_CREATE);
add_end(label);
}
}

File diff suppressed because it is too large Load diff

View file

@ -4,50 +4,67 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
// Window for sending messages.
public class ComposerWindow : Gtk.Window, ComposerContainer {
/**
* A ComposerWindow is a ComposerContainer that is used to compose mails in a separate window
* (i.e. detached) of its own.
*/
public class ComposerWindow : Gtk.ApplicationWindow, ComposerContainer {
private bool closing = false;
protected ComposerWidget composer { get; set; }
protected Gee.MultiMap<string, string>? old_accelerators { get; set; }
public Gtk.ApplicationWindow top_window {
get { return this; }
}
public ComposerWindow(ComposerWidget composer) {
Object(type: Gtk.WindowType.TOPLEVEL);
add(composer);
this.composer = composer;
composer.header.show_close_button = true;
composer.free_header();
set_titlebar(composer.header);
composer.bind_property("window-title", composer.header, "title",
// Make sure it gets added to the GtkApplication, to get the window-specific
// composer actions to work properly.
GearyApplication.instance.add_window(this);
add(this.composer);
focus_in_event.connect(on_focus_in);
focus_out_event.connect(on_focus_out);
this.composer.header.show_close_button = true;
this.composer.free_header();
set_titlebar(this.composer.header);
composer.bind_property("window-title", this.composer.header, "title",
BindingFlags.SYNC_CREATE);
add_accel_group(composer.ui.get_accel_group());
show();
set_position(Gtk.WindowPosition.CENTER);
}
public Gtk.Window top_window {
get { return this; }
}
public override void show() {
set_default_size(680, 600);
base.show();
}
public void close_container() {
closing = true;
on_focus_out();
this.composer.editor.focus_in_event.disconnect(on_focus_in);
this.composer.editor.focus_out_event.disconnect(on_focus_out);
this.closing = true;
destroy();
}
public override bool delete_event(Gdk.EventAny event) {
return !(closing ||
return !(this.closing ||
((ComposerWidget) get_child()).should_close() == ComposerWidget.CloseStatus.DO_CLOSE);
}
public void vanish() {
hide();
}
public void remove_composer() {
warning("Detached composer received remove");
}

View file

@ -4,10 +4,13 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
// Displays a dialog for collecting the user's login data.
// A custom entry for e-mail addresses
public class EmailEntry : Gtk.Entry {
public bool valid_or_empty { get; set; default = true; }
// Whether this entry contains a valid email address
public bool valid { get; set; default = false; }
public bool empty { get; set; default = true; }
public bool modified = false;
// null or valid addresses
@ -44,7 +47,7 @@ public class EmailEntry : Gtk.Entry {
updating = true;
addresses = null;
updating = false;
valid_or_empty = true;
valid = false;
empty = true;
return;
}
@ -56,7 +59,7 @@ public class EmailEntry : Gtk.Entry {
private void validate_addresses() {
if (addresses == null || addresses.size == 0) {
valid_or_empty = true;
valid = false;
empty = true;
return;
}
@ -64,11 +67,11 @@ public class EmailEntry : Gtk.Entry {
foreach (Geary.RFC822.MailboxAddress address in addresses) {
if (!address.is_valid()) {
valid_or_empty = false;
valid = false;
return;
}
}
valid_or_empty = true;
valid = true;
}
private bool on_key_press(Gtk.Widget widget, Gdk.EventKey event) {

View file

@ -138,4 +138,19 @@ public void set_label_xalign(Gtk.Label label, float xalign) {
label.set("xalign", xalign);
}
/**
* Returns whether the close button is at the end of the headerbar.
*/
bool close_button_at_end() {
string layout = Gtk.Settings.get_default().gtk_decoration_layout;
bool at_end = false;
// Based on logic of close_button_at_end in gtkheaderbar.c: Close button appears
// at end iff "close" follows a colon in the layout string.
if (layout != null) {
int colon_ind = layout.index_of(":");
at_end = (colon_ind >= 0 && layout.index_of("close", colon_ind) >= 0);
}
return at_end;
}
}

View file

@ -6,8 +6,9 @@ set(RESOURCE_LIST
STRIPBLANKS "account_spinner.glade"
STRIPBLANKS "app_menu.interface"
STRIPBLANKS "certificate_warning_dialog.glade"
STRIPBLANKS "composer.glade"
STRIPBLANKS "composer_accelerators.ui"
STRIPBLANKS "composer-headerbar.ui"
STRIPBLANKS "composer-menus.ui"
STRIPBLANKS "composer-widget.ui"
STRIPBLANKS "edit_alternate_emails.glade"
STRIPBLANKS "find_bar.glade"
STRIPBLANKS "folder-popover.ui"

198
ui/composer-headerbar.ui Normal file
View file

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.14"/>
<template class="ComposerHeaderbar" parent="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">False</property>
<child>
<object class="GtkBox" id="detach_start">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="detach_start_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_end">6</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="action_name">cmh.detach</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Detach (Ctrl+D)</property>
<child>
<object class="GtkImage" id="detach_start_image">
<property name="icon_name">detach-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator" id="detach_start_separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="new_message_attach_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.add-attachment</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Attach File (Ctrl+T)</property>
<child>
<object class="GtkImage" id="new_message_attach_image">
<property name="icon_name">mail-attachment-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="conversation_attach_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="conversation_attach_new_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.add-attachment</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Attach File (Ctrl+T)</property>
<child>
<object class="GtkImage" id="conversation_attach_new_image">
<property name="icon_name">mail-attachment-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="conversation_attach_original_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.add-original-attachments</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Include Original Attachments</property>
<child>
<object class="GtkImage" id="conversation_attach_original_image">
<property name="icon_name">edit-copy-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="recipients_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NONE</property>
<child>
<object class="GtkLabel" id="recipients_label">
<property name="visible">True</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="detach_end">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkSeparator" id="detach_end_separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
</object>
</child>
<child>
<object class="GtkButton" id="detach_end_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_start">6</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="action_name">cmh.detach</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Detach (Ctrl+D)</property>
<child>
<object class="GtkImage" id="detach_end_image">
<property name="icon_name">detach-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkButton" id="send_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.send</property>
<property name="always_show_image">True</property>
<property name="use_underline">True</property>
<property name="tooltip_text" translatable="yes">Send (Ctrl+Enter)</property>
<property name="label" translatable="yes">_Send</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkBox" id="close_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="discard_and_close_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.close-and-discard</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Close and Discard</property>
<child>
<object class="GtkImage" id="discard_and_close_image">
<property name="icon_name">user-trash-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="save_and_close_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">cmh.close-and-save</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Close and Save</property>
<child>
<object class="GtkImage" id="save_and_close_image">
<property name="icon_name">document-save-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</template>
</interface>

108
ui/composer-menus.ui Normal file
View file

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="html_menu_model">
<section>
<item>
<attribute name="label" translatable="yes">S_ans Serif</attribute>
<attribute name="action">cmp.font-family</attribute>
<attribute name="target">sans</attribute>
</item>
<item>
<attribute name="label" translatable="yes">S_erif</attribute>
<attribute name="action">cmp.font-family</attribute>
<attribute name="target">serif</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Fixed Width</attribute>
<attribute name="action">cmp.font-family</attribute>
<attribute name="target">monospace</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Small</attribute>
<attribute name="action">cmp.font-size</attribute>
<attribute name="target">small</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Medium</attribute>
<attribute name="action">cmp.font-size</attribute>
<attribute name="target">medium</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Lar_ge</attribute>
<attribute name="action">cmp.font-size</attribute>
<attribute name="target">large</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">C_olor</attribute>
<attribute name="action">cmp.color</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Rich Text</attribute>
<attribute name="action">cmp.compose-as-html</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Show Extended Fields</attribute>
<attribute name="action">cmp.show-extended</attribute>
</item>
</section>
</menu>
<menu id="plain_menu_model">
<section>
<item>
<attribute name="label" translatable="yes">_Rich Text</attribute>
<attribute name="action">cmp.compose-as-html</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Show Extended Fields</attribute>
<attribute name="action">cmp.show-extended</attribute>
</item>
</section>
</menu>
<menu id="context_menu_model">
<section>
<item>
<attribute name="label" translatable="yes">_Undo</attribute>
<attribute name="action">undo</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Redo</attribute>
<attribute name="action">redo</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Cu_t</attribute>
<attribute name="action">cut</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Copy</attribute>
<attribute name="action">copy</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy _Link</attribute>
<attribute name="action">copy-link</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Paste</attribute>
<attribute name="action">paste</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Paste _With Formatting</attribute>
<attribute name="action">paste-with-formatting</attribute>
</item>
</section>
</menu>
</interface>

627
ui/composer-widget.ui Normal file
View file

@ -0,0 +1,627 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.14"/>
<template class="ComposerWidget" parent="GtkEventBox">
<property name="visible">True</property>
<signal name="drag_data_received" handler="on_drag_data_received"/>
<signal name="drag_drop" handler="on_drag_drop"/>
<signal name="drag_motion" handler="on_drag_motion"/>
<signal name="drag_leave" handler="on_drag_leave"/>
<child>
<object class="GtkBox" id="composer_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkBox" id="header_area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hidden_on_attachment_drag_over">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="hidden_on_attachment_drag_over_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid" id="recipients">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="row_spacing">0</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="to_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes" comments="Address(es) e-mail is to be sent to">_To</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to_box</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="cc_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Cc</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to_box</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="to_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="cc_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="subject_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
<property name="margin_top">6</property>
<signal name="changed" handler="on_subject_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="subject_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Subject</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">subject_entry</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bcc_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Bcc</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to_box</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="bcc_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="reply_to_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Reply-To</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to_box</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="reply_to_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="from_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="use_underline">True</property>
<property name="label" translatable="yes" comments="Geary account mail will be sent from">From</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to_box</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="from_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="from_single">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="from_multiple">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="visible_on_attachment_drag_over">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="visible_on_attachment_drag_over_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Drop files here</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="label" translatable="yes">To add them as attachments</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="composer_toolbar">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox" id="font_style_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="bold_button">
<property name="visible" bind-source="bold_button" bind-property="sensitive" />
<property name="can_focus">False</property>
<property name="always_show_image">True</property>
<property name="action_name">cmp.bold</property>
<property name="tooltip_text" translatable="yes">Bold (Ctrl+B)</property>
<child>
<object class="GtkImage" id="bold_image">
<property name="icon_name">format-text-bold-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="italics_button">
<property name="visible" bind-source="italics_button" bind-property="sensitive" />
<property name="can_focus">False</property>
<property name="action_name">cmp.italic</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Italic (Ctrl+I)</property>
<child>
<object class="GtkImage" id="italics_image">
<property name="icon_name">format-text-italic-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="underline_button">
<property name="visible" bind-source="underline_button" bind-property="sensitive" />
<property name="can_focus">False</property>
<property name="action_name">cmp.underline</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Underline (Ctrl+U)</property>
<child>
<object class="GtkImage" id="underline_image">
<property name="icon_name">format-text-underline-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="strikethrough_button">
<property name="visible" bind-source="strikethrough_button" bind-property="sensitive" />
<property name="can_focus">False</property>
<property name="action_name">cmp.strikethrough</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Strikethrough (Ctrl+K)</property>
<child>
<object class="GtkImage" id="strikethrough_image">
<property name="icon_name">format-text-strikethrough-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="indentation_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="indent_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">cmp.indent</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Quote text (Ctrl+])</property>
<child>
<object class="GtkImage" id="indent_image">
<property name="icon_name">format-indent-more-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="outdent_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">cmp.outdent</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Unquote text (Ctrl+[)</property>
<child>
<object class="GtkImage" id="outdent_image">
<property name="icon_name">format-indent-less-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="link_buttons">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="insert_link_button">
<property name="visible" bind-source="insert_link_button" bind-property="sensitive" />
<property name="can_focus">False</property>
<property name="action_name">cmp.insert-link</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Link (Ctrl+L)</property>
<child>
<object class="GtkImage" id="insert_link_image">
<property name="icon_name">insert-link-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="remove_format_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="always_show_image">True</property>
<property name="action_name">cmp.remove-format</property>
<property name="tooltip_text" translatable="yes">Remove formatting (Ctrl+Space)</property>
<child>
<object class="GtkImage" id="remove_format_image">
<property name="icon_name">format-text-remove-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="select_dictionary_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">cmp.select-dictionary</property>
<property name="always_show_image">True</property>
<property name="tooltip_text" translatable="yes">Select spell checking language</property>
<child>
<object class="GtkImage" id="select_dictionary_image">
<property name="icon_name">accessories-dictionary-symbolic</property>
<property name="pixel-size">16</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton" id="menu_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="info_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkBox" id="message_area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkOverlay" id="message_overlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow" id="editor_scrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<placeholder />
</child>
</object>
</child>
<child type="overlay">
<object class="GtkLabel" id="message_overlay_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">end</property>
<property name="ellipsize">middle</property>
<signal name="realize" handler="on_message_overlay_label_realize" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
<style>
<class name="geary-composer-body"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="attachments_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View file

@ -1,649 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.14"/>
<object class="GtkActionGroup" id="compose actions">
<child>
<object class="GtkAction" id="undo">
<property name="label" translatable="yes">_Undo</property>
<property name="icon_name">undo</property>
</object>
<accelerator key="z" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="redo">
<property name="label" translatable="yes">_Redo</property>
<property name="icon_name">redo</property>
</object>
<accelerator key="z" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="cut">
<property name="label" translatable="yes">Cu_t</property>
<property name="icon_name">edit-cut</property>
</object>
<accelerator key="x" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="copy">
<property name="label" translatable="yes">_Copy</property>
<property name="icon_name">edit-copy</property>
</object>
<accelerator key="c" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="paste">
<property name="label" translatable="yes">_Paste</property>
<property name="icon_name">edit-paste</property>
</object>
<accelerator key="v" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="justifyleft">
<property name="label" translatable="yes">_Left</property>
</object>
</child>
<child>
<object class="GtkAction" id="justifyright">
<property name="label" translatable="yes">_Right</property>
</object>
</child>
<child>
<object class="GtkAction" id="justifycenter">
<property name="label" translatable="yes">_Center</property>
</object>
</child>
<child>
<object class="GtkAction" id="justifyfull">
<property name="label" translatable="yes">_Justify</property>
</object>
</child>
<child>
<object class="GtkAction" id="insertlink">
<property name="tooltip" translatable="yes">Link (Ctrl+L)</property>
<property name="icon_name">insert-link-symbolic</property>
</object>
<accelerator key="l" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="color">
<property name="label" translatable="yes">C_olor</property>
</object>
</child>
<child>
<object class="GtkAction" id="menu">
<property name="tooltip" translatable="yes">More options</property>
<property name="icon_name">go-down-symbolic</property>
</object>
</child>
<child>
<object class="GtkAction" id="indent">
<property name="tooltip" translatable="yes">Quote text (Ctrl+])</property>
<property name="icon_name">format-indent-more-symbolic</property>
</object>
<accelerator key="bracketright" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="outdent">
<property name="tooltip" translatable="yes">Unquote text (Ctrl+[)</property>
<property name="icon_name">format-indent-less-symbolic</property>
</object>
<accelerator key="bracketleft" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="removeformat">
<property name="tooltip" translatable="yes">Remove formatting (Ctrl+Space)</property>
<property name="icon_name">format-text-remove-symbolic</property>
</object>
<accelerator key="space" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="paste with formatting">
<property name="label" translatable="yes" context="Clipboard paste with rich text">Paste _With Formatting</property>
</object>
<accelerator key="v" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="copy link">
<property name="label" translatable="yes">Copy _Link</property>
</object>
</child>
<child>
<object class="GtkToggleAction" id="bold">
<property name="tooltip" translatable="yes">Bold (Ctrl+B)</property>
<property name="icon_name">format-text-bold-symbolic</property>
</object>
<accelerator key="b" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkToggleAction" id="italic">
<property name="tooltip" translatable="yes">Italic (Ctrl+I)</property>
<property name="icon_name">format-text-italic-symbolic</property>
</object>
<accelerator key="i" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkToggleAction" id="underline">
<property name="tooltip" translatable="yes">Underline (Ctrl+U)</property>
<property name="icon_name">format-text-underline-symbolic</property>
</object>
<accelerator key="u" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkToggleAction" id="strikethrough">
<property name="tooltip" translatable="yes">Strikethrough (Ctrl+K)</property>
<property name="icon_name">format-text-strikethrough-symbolic</property>
</object>
<accelerator key="k" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkToggleAction" id="compose as html">
<property name="label" translatable="yes">_Rich Text</property>
<property name="icon_name">text-html</property>
</object>
</child>
<child>
<object class="GtkToggleAction" id="show extended">
<property name="label" translatable="yes">Show Extended Fields</property>
<property name="icon_name">show-more</property>
</object>
</child>
<child>
<object class="GtkAction" id="close">
<property name="icon_name">window-close-symbolic</property>
</object>
<accelerator key="w" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="close and save">
<property name="label" translatable="yes" context="Label">Close and Save</property>
<property name="short_label" translatable="yes" context="Short Label">Close and Save</property>
<property name="tooltip" translatable="yes" context="Tooltip">Close and Save</property>
<property name="icon_name">document-save-symbolic</property>
</object>
</child>
<child>
<object class="GtkAction" id="close and discard">
<property name="label" translatable="yes" context="Label">Close and Discard</property>
<property name="short_label" translatable="yes" context="Short Label">Close and Discard</property>
<property name="tooltip" translatable="yes" context="Tooltip">Close and Discard</property>
<property name="icon_name">user-trash-symbolic</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_large">
<property name="label" translatable="yes">Lar_ge</property>
<property name="short_label" translatable="yes">Large</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_medium">
<property name="label" translatable="yes">_Medium</property>
<property name="short_label" translatable="yes">Medium</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_small">
<property name="label" translatable="yes">_Small</property>
<property name="short_label" translatable="yes">Small</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_sans">
<property name="label" translatable="yes">S_ans Serif</property>
<property name="short_label" translatable="yes">Sans Serif</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_serif">
<property name="label" translatable="yes">S_erif</property>
<property name="short_label" translatable="yes">Serif</property>
</object>
</child>
<child>
<object class="GtkAction" id="font_monospace">
<property name="label" translatable="yes">_Fixed Width</property>
<property name="short_label" translatable="yes">Fixed Width</property>
</object>
</child>
<child>
<object class="GtkAction" id="detach">
<property name="label" translatable="yes">Detach</property>
<property name="short_label" translatable="yes">Detach</property>
<property name="tooltip" translatable="yes">Detach (Ctrl+D)</property>
<property name="icon_name">detach-symbolic</property>
</object>
<accelerator key="d" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="send">
<property name="label" translatable="yes">_Send</property>
<property name="short_label" translatable="yes">Send</property>
<property name="tooltip" translatable="yes">Send (Ctrl+Enter)</property>
<property name="icon_name">mail-send-symbolic</property>
</object>
</child>
<child>
<object class="GtkAction" id="add attachment">
<property name="label" translatable="yes">_Attach File</property>
<property name="short_label" translatable="yes">Attach File</property>
<property name="tooltip" translatable="yes">Attach File (Ctrl+T)</property>
<property name="icon_name">mail-attachment-symbolic</property>
</object>
<accelerator key="t" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkAction" id="add original attachments">
<property name="label" translatable="yes">_Include Original Attachments</property>
<property name="short_label" translatable="yes">Include Original Attachments</property>
<property name="tooltip" translatable="yes">Include Original Attachments</property>
<property name="icon_name">edit-copy-symbolic</property>
</object>
</child>
<child>
<object class="GtkAction" id="select dictionary">
<property name="label" translatable="yes">Select spell checking language</property>
<property name="short_label" translatable="yes">Spelling language</property>
<property name="icon_name">accessories-dictionary-symbolic</property>
</object>
</child>
</object>
<object class="GtkBox" id="composer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkAlignment" id="header_area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="hidden_on_attachment_drag_over">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="hidden_on_attachment_drag_over_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid" id="recipients">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="row_spacing">0</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="to label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes" comments="Address(es) e-mail is to be sent to">_To</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="cc label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Cc</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="to">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="cc">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="subject">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
<property name="margin_top">6</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="subject label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Subject</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">subject</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bcc label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Bcc</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="bcc">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="reply to label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Reply-To</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to</property>
<property name="margin_top">6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="reply to">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="from label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes" comments="Geary account mail will be sent from">From</property>
<property name="justify">right</property>
<property name="mnemonic_widget">to</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="from_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="from_single">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="from_multiple">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="visible_on_attachment_drag_over">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="visible_on_attachment_drag_over_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Drop files here</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="label" translatable="yes">To add them as attachments</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="toolbar area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">6</property>
<property name="right_padding">6</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkAlignment" id="message area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
<style>
<class name="geary-composer-body"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="attachments_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
</interface>

View file

@ -1,43 +0,0 @@
<ui>
<accelerator action="undo" />
<accelerator action="redo" />
<accelerator action="add attachment" />
<accelerator action="cut" />
<accelerator action="copy" />
<accelerator action="copy link" />
<accelerator action="paste" />
<accelerator action="paste with formatting" />
<accelerator action="bold" />
<accelerator action="italic" />
<accelerator action="underline" />
<accelerator action="strikethrough" />
<accelerator action="removeformat" />
<accelerator action="compose as html" name="htmlcompose" />
<accelerator action="show extended" name="extended" />
<accelerator action="indent" />
<accelerator action="outdent" />
<accelerator action="justifyleft" />
<accelerator action="justifyright" />
<accelerator action="justifycenter" />
<accelerator action="justifyfull" />
<accelerator action="color" name="color" />
<accelerator action="insertlink" />
<accelerator action="font_small" />
<accelerator action="font_medium" />
<accelerator action="font_large" />
<accelerator action="font_sans" />
<accelerator action="font_serif" />
<accelerator action="font_monospace" />
<accelerator action="detach" />
<accelerator action="close" />
</ui>