Clean up MainWindow. Bug 775006.
* Use GtkTemplate to simplify layout. * Prefix instance variables with this. * Extract helper methods for clarity. Signed-off-by: Niels De Graef <nielsdegraef@gmail.com>
This commit is contained in:
parent
9f331c4639
commit
776eebd48e
4 changed files with 314 additions and 213 deletions
|
|
@ -398,6 +398,7 @@ src/mailer/main.vala
|
|||
[type: gettext/glade]ui/gtk/menus.ui
|
||||
[type: gettext/glade]ui/login.glade
|
||||
[type: gettext/glade]ui/main-toolbar.ui
|
||||
[type: gettext/glade]ui/main-window.ui
|
||||
[type: gettext/glade]ui/password-dialog.glade
|
||||
[type: gettext/glade]ui/preferences.glade
|
||||
[type: gettext/glade]ui/remove_confirm.glade
|
||||
|
|
|
|||
|
|
@ -6,52 +6,70 @@
|
|||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
[GtkTemplate (ui = "/org/gnome/Geary/main-window.ui")]
|
||||
public class MainWindow : Gtk.ApplicationWindow {
|
||||
private const int MESSAGE_LIST_WIDTH = 250;
|
||||
private const int FOLDER_LIST_WIDTH = 100;
|
||||
private const int STATUS_BAR_HEIGHT = 18;
|
||||
|
||||
/// Fired when the shift key is pressed or released.
|
||||
|
||||
/** Fired when the shift key is pressed or released. */
|
||||
public signal void on_shift_key(bool pressed);
|
||||
|
||||
public FolderList.Tree folder_list { get; private set; default = new FolderList.Tree(); }
|
||||
public MainToolbar main_toolbar { get; private set; }
|
||||
public SearchBar search_bar { get; private set; default = new SearchBar(); }
|
||||
public ConversationListView conversation_list_view { get; private set; default = new ConversationListView(); }
|
||||
public ConversationViewer conversation_viewer { get; private set; }
|
||||
public StatusBar status_bar { get; private set; default = new StatusBar(); }
|
||||
|
||||
public Geary.Folder? current_folder { get; private set; default = null; }
|
||||
public Configuration config { get; private set; }
|
||||
|
||||
|
||||
private Geary.AggregateProgressMonitor progress_monitor = new Geary.AggregateProgressMonitor();
|
||||
private Geary.ProgressMonitor? folder_progress = null;
|
||||
|
||||
// Used to save/load the window state between sessions.
|
||||
public int window_width { get; set; }
|
||||
public int window_height { get; set; }
|
||||
public bool window_maximized { get; set; }
|
||||
|
||||
private Gtk.Paned folder_paned = new Gtk.Paned(Gtk.Orientation.HORIZONTAL);
|
||||
private Gtk.Paned conversations_paned = new Gtk.Paned(Gtk.Orientation.HORIZONTAL);
|
||||
|
||||
private Gtk.ScrolledWindow conversation_list_scrolled;
|
||||
// Widget descendants
|
||||
public FolderList.Tree folder_list { get; private set; default = new FolderList.Tree(); }
|
||||
public MainToolbar main_toolbar { get; private set; }
|
||||
public SearchBar search_bar { get; private set; default = new SearchBar(); }
|
||||
public ConversationListView conversation_list_view { get; private set; default = new ConversationListView(); }
|
||||
public ConversationViewer conversation_viewer { get; private set; default = new ConversationViewer(); }
|
||||
public StatusBar status_bar { get; private set; default = new StatusBar(); }
|
||||
private MonitoredSpinner spinner = new MonitoredSpinner();
|
||||
[GtkChild]
|
||||
private Gtk.Box search_bar_box;
|
||||
[GtkChild]
|
||||
private Gtk.Paned folder_paned;
|
||||
[GtkChild]
|
||||
private Gtk.Paned conversations_paned;
|
||||
[GtkChild]
|
||||
private Gtk.Box folder_box;
|
||||
[GtkChild]
|
||||
private Gtk.ScrolledWindow folder_list_scrolled;
|
||||
[GtkChild]
|
||||
private Gtk.Box conversation_box;
|
||||
private Geary.AggregateProgressMonitor progress_monitor = new Geary.AggregateProgressMonitor();
|
||||
private Geary.ProgressMonitor? folder_progress = null;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ScrolledWindow conversation_list_scrolled;
|
||||
|
||||
public MainWindow(GearyApplication application) {
|
||||
Object(application: application);
|
||||
set_show_menubar(false);
|
||||
|
||||
add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK
|
||||
| Gdk.EventMask.FOCUS_CHANGE_MASK);
|
||||
load_config(application.config);
|
||||
restore_saved_window_state();
|
||||
|
||||
config = application.config;
|
||||
conversation_viewer = new ConversationViewer();
|
||||
add_accel_group(application.ui_manager.get_accel_group());
|
||||
|
||||
// This code both loads AND saves the pane positions with live
|
||||
// updating. This is more resilient against crashes because
|
||||
// the value in dconf changes *immediately*, and stays saved
|
||||
// in the event of a crash.
|
||||
config.bind(Configuration.MESSAGES_PANE_POSITION_KEY, conversations_paned, "position");
|
||||
application.controller.notify[GearyController.PROP_CURRENT_CONVERSATION]
|
||||
.connect(on_conversation_monitor_changed);
|
||||
application.controller.folder_selected.connect(on_folder_selected);
|
||||
Geary.Engine.instance.account_available.connect(on_account_available);
|
||||
Geary.Engine.instance.account_unavailable.connect(on_account_unavailable);
|
||||
|
||||
set_styling();
|
||||
setup_layout(application.config);
|
||||
on_change_orientation();
|
||||
}
|
||||
|
||||
private void load_config(Configuration config) {
|
||||
// This code both loads AND saves the pane positions with live updating. This is more
|
||||
// resilient against crashes because the value in dconf changes *immediately*, and
|
||||
// stays saved in the event of a crash.
|
||||
config.bind(Configuration.MESSAGES_PANE_POSITION_KEY, this.conversations_paned, "position");
|
||||
config.bind(Configuration.WINDOW_WIDTH_KEY, this, "window-width");
|
||||
config.bind(Configuration.WINDOW_HEIGHT_KEY, this, "window-height");
|
||||
config.bind(Configuration.WINDOW_MAXIMIZE_KEY, this, "window-maximized");
|
||||
|
|
@ -60,8 +78,11 @@ public class MainWindow : Gtk.ApplicationWindow {
|
|||
config.folder_list_pane_position_horizontal = config.folder_list_pane_position_old;
|
||||
config.messages_pane_position += config.folder_list_pane_position_old;
|
||||
}
|
||||
config.settings.changed[Configuration.FOLDER_LIST_PANE_HORIZONTAL_KEY]
|
||||
.connect(on_change_orientation);
|
||||
}
|
||||
|
||||
// Restore saved window state
|
||||
private void restore_saved_window_state() {
|
||||
Gdk.Screen? screen = get_screen();
|
||||
if (screen != null &&
|
||||
this.window_width <= screen.get_width() &&
|
||||
|
|
@ -71,61 +92,10 @@ public class MainWindow : Gtk.ApplicationWindow {
|
|||
if (this.window_maximized) {
|
||||
maximize();
|
||||
}
|
||||
set_position(Gtk.WindowPosition.CENTER);
|
||||
|
||||
add_accel_group(GearyApplication.instance.ui_manager.get_accel_group());
|
||||
|
||||
spinner.set_progress_monitor(progress_monitor);
|
||||
|
||||
delete_event.connect(on_delete_event);
|
||||
key_press_event.connect(on_key_press_event);
|
||||
key_release_event.connect(on_key_release_event);
|
||||
focus_in_event.connect(on_focus_event);
|
||||
GearyApplication.instance.config.settings.changed[
|
||||
Configuration.FOLDER_LIST_PANE_HORIZONTAL_KEY].connect(on_change_orientation);
|
||||
GearyApplication.instance.controller.notify[GearyController.PROP_CURRENT_CONVERSATION].
|
||||
connect(on_conversation_monitor_changed);
|
||||
GearyApplication.instance.controller.folder_selected.connect(on_folder_selected);
|
||||
Geary.Engine.instance.account_available.connect(on_account_available);
|
||||
Geary.Engine.instance.account_unavailable.connect(on_account_unavailable);
|
||||
|
||||
// Toolbar.
|
||||
main_toolbar = new MainToolbar(config);
|
||||
main_toolbar.bind_property("search-open", search_bar, "search-mode-enabled",
|
||||
BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
|
||||
main_toolbar.bind_property("find-open", conversation_viewer.conversation_find_bar, "search-mode-enabled",
|
||||
BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
|
||||
if (config.desktop_environment == Configuration.DesktopEnvironment.UNITY) {
|
||||
BindingTransformFunc title_func = (binding, source, ref target) => {
|
||||
string folder = current_folder != null ? current_folder.get_display_name() + " " : "";
|
||||
string account = main_toolbar.account != null ? "(%s)".printf(main_toolbar.account) : "";
|
||||
|
||||
target = "%s%s - %s".printf(folder, account, GearyApplication.NAME);
|
||||
|
||||
return true;
|
||||
};
|
||||
bind_property("current-folder", this, "title", BindingFlags.SYNC_CREATE, title_func);
|
||||
main_toolbar.bind_property("account", this, "title", BindingFlags.SYNC_CREATE, title_func);
|
||||
} else {
|
||||
main_toolbar.show_close_button = true;
|
||||
set_titlebar(main_toolbar);
|
||||
}
|
||||
|
||||
set_styling();
|
||||
create_layout();
|
||||
on_change_orientation();
|
||||
this.window_position = Gtk.WindowPosition.CENTER;
|
||||
}
|
||||
|
||||
private bool on_delete_event() {
|
||||
if (Args.hidden_startup || GearyApplication.instance.config.startup_notifications)
|
||||
return hide_on_delete();
|
||||
|
||||
GearyApplication.instance.exit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fired on [un]maximize and possibly others. Save maximized state
|
||||
// Called on [un]maximize and possibly others. Save maximized state
|
||||
// for the next start.
|
||||
public override bool window_state_event(Gdk.EventWindowState event) {
|
||||
if ((event.new_window_state & Gdk.WindowState.WITHDRAWN) == 0) {
|
||||
|
|
@ -139,7 +109,7 @@ public class MainWindow : Gtk.ApplicationWindow {
|
|||
return base.window_state_event(event);
|
||||
}
|
||||
|
||||
// Fired on window resize. Save window size for the next start.
|
||||
// Called on window resize. Save window size for the next start.
|
||||
public override void size_allocate(Gtk.Allocation allocation) {
|
||||
base.size_allocate(allocation);
|
||||
|
||||
|
|
@ -177,96 +147,53 @@ public class MainWindow : Gtk.ApplicationWindow {
|
|||
});
|
||||
provider.load_from_resource(@"/org/gnome/Geary/geary.css");
|
||||
}
|
||||
|
||||
private void create_layout() {
|
||||
Gtk.Box main_layout = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
||||
|
||||
// folder list
|
||||
Gtk.ScrolledWindow folder_list_scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
folder_list_scrolled.set_size_request(FOLDER_LIST_WIDTH, -1);
|
||||
folder_list_scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
folder_list_scrolled.add(folder_list);
|
||||
Gtk.Frame folder_frame = new Gtk.Frame(null);
|
||||
folder_frame.shadow_type = Gtk.ShadowType.IN;
|
||||
folder_frame.get_style_context ().add_class("geary-folder-frame");
|
||||
folder_frame.add(folder_list_scrolled);
|
||||
folder_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
||||
folder_box.pack_start(folder_frame, true, true);
|
||||
|
||||
// message list
|
||||
conversation_list_scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
conversation_list_scrolled.set_size_request(MESSAGE_LIST_WIDTH, -1);
|
||||
conversation_list_scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
|
||||
conversation_list_scrolled.add(conversation_list_view);
|
||||
Gtk.Frame conversation_frame = new Gtk.Frame(null);
|
||||
conversation_frame.shadow_type = Gtk.ShadowType.IN;
|
||||
conversation_frame.get_style_context ().add_class("geary-conversation-frame");
|
||||
conversation_frame.add(conversation_list_scrolled);
|
||||
conversation_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
||||
conversation_box.pack_start(conversation_frame, true, true);
|
||||
|
||||
// Three-pane display.
|
||||
status_bar.set_size_request(-1, STATUS_BAR_HEIGHT);
|
||||
status_bar.set_border_width(2);
|
||||
spinner.set_size_request(STATUS_BAR_HEIGHT - 2, -1);
|
||||
status_bar.add(spinner);
|
||||
|
||||
folder_paned.get_style_context().add_class("geary-sidebar-pane-separator");
|
||||
|
||||
// Folder list to the left of everything.
|
||||
folder_paned.pack1(folder_box, false, false);
|
||||
folder_paned.pack2(conversation_box, true, false);
|
||||
|
||||
Gtk.Box search_bar_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
|
||||
search_bar_box.pack_start(search_bar, false, false, 0);
|
||||
search_bar_box.pack_start(folder_paned);
|
||||
search_bar_box.get_style_context().add_class(Gtk.STYLE_CLASS_SIDEBAR);
|
||||
|
||||
// Message list left of message viewer.
|
||||
conversations_paned.pack1(search_bar_box, false, false);
|
||||
conversations_paned.pack2(conversation_viewer, true, true);
|
||||
|
||||
private void setup_layout(Configuration config) {
|
||||
// Toolbar
|
||||
this.main_toolbar = new MainToolbar(config);
|
||||
this.main_toolbar.bind_property("search-open", this.search_bar, "search-mode-enabled",
|
||||
BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
|
||||
this.main_toolbar.bind_property("find-open", this.conversation_viewer.conversation_find_bar,
|
||||
"search-mode-enabled", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
|
||||
if (config.desktop_environment == Configuration.DesktopEnvironment.UNITY) {
|
||||
main_layout.pack_start(main_toolbar, false, true, 0);
|
||||
BindingTransformFunc title_func = (binding, source, ref target) => {
|
||||
string folder = current_folder != null ? current_folder.get_display_name() + " " : "";
|
||||
string account = main_toolbar.account != null ? "(%s)".printf(main_toolbar.account) : "";
|
||||
|
||||
target = "%s%s - %s".printf(folder, account, GearyApplication.NAME);
|
||||
|
||||
return true;
|
||||
};
|
||||
bind_property("current-folder", this, "title", BindingFlags.SYNC_CREATE, title_func);
|
||||
main_toolbar.bind_property("account", this, "title", BindingFlags.SYNC_CREATE, title_func);
|
||||
} else {
|
||||
main_toolbar.show_close_button = true;
|
||||
set_titlebar(main_toolbar);
|
||||
}
|
||||
|
||||
main_layout.pack_end(conversations_paned, true, true, 0);
|
||||
|
||||
add(main_layout);
|
||||
// Search bar
|
||||
this.search_bar_box.pack_start(this.search_bar, false, false, 0);
|
||||
// Folder list
|
||||
this.folder_list_scrolled.add(this.folder_list);
|
||||
// Conversation list
|
||||
this.conversation_list_scrolled.add(this.conversation_list_view);
|
||||
// Conversation viewer
|
||||
this.conversations_paned.pack2(this.conversation_viewer, true, true);
|
||||
|
||||
// Status bar
|
||||
this.status_bar.set_size_request(-1, STATUS_BAR_HEIGHT);
|
||||
this.status_bar.set_border_width(2);
|
||||
this.spinner.set_size_request(STATUS_BAR_HEIGHT - 2, -1);
|
||||
this.spinner.set_progress_monitor(progress_monitor);
|
||||
this.status_bar.add(this.spinner);
|
||||
}
|
||||
|
||||
|
||||
// Returns true when there's a conversation list scrollbar visible, i.e. the list is tall
|
||||
// enough to need one. Otherwise returns false.
|
||||
public bool conversation_list_has_scrollbar() {
|
||||
Gtk.Scrollbar? scrollbar = conversation_list_scrolled.get_vscrollbar() as Gtk.Scrollbar;
|
||||
Gtk.Scrollbar? scrollbar = this.conversation_list_scrolled.get_vscrollbar() as Gtk.Scrollbar;
|
||||
return scrollbar != null && scrollbar.get_visible();
|
||||
}
|
||||
|
||||
private bool on_key_press_event(Gdk.EventKey event) {
|
||||
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
|
||||
&& (event.state & Gdk.ModifierType.SHIFT_MASK) == 0 && !search_bar.search_entry_has_focus)
|
||||
on_shift_key(true);
|
||||
|
||||
// Check whether the focused widget wants to handle it, if not let the accelerators kick in
|
||||
// via the default handling
|
||||
return propagate_key_event(event);
|
||||
}
|
||||
|
||||
private bool on_key_release_event(Gdk.EventKey event) {
|
||||
// FIXME: it's possible the user will press two shift keys. We want
|
||||
// the shift key to report as released when they release ALL of them.
|
||||
// There doesn't seem to be an easy way to do this in Gdk.
|
||||
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
|
||||
&& !search_bar.search_entry_has_focus)
|
||||
on_shift_key(false);
|
||||
|
||||
return propagate_key_event(event);
|
||||
}
|
||||
|
||||
private bool on_focus_event() {
|
||||
on_shift_key(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void on_conversation_monitor_changed() {
|
||||
ConversationListStore? old_model = this.conversation_list_view.get_model();
|
||||
|
|
@ -293,107 +220,147 @@ public class MainWindow : Gtk.ApplicationWindow {
|
|||
}
|
||||
|
||||
private void on_folder_selected(Geary.Folder? folder) {
|
||||
if (folder_progress != null) {
|
||||
progress_monitor.remove(folder_progress);
|
||||
folder_progress = null;
|
||||
if (this.folder_progress != null) {
|
||||
this.progress_monitor.remove(this.folder_progress);
|
||||
this.folder_progress = null;
|
||||
}
|
||||
|
||||
|
||||
if (folder != null) {
|
||||
folder_progress = folder.opening_monitor;
|
||||
progress_monitor.add(folder_progress);
|
||||
this.folder_progress = folder.opening_monitor;
|
||||
this.progress_monitor.add(this.folder_progress);
|
||||
}
|
||||
|
||||
|
||||
// disconnect from old folder
|
||||
if (current_folder != null)
|
||||
current_folder.properties.notify.disconnect(update_headerbar);
|
||||
|
||||
if (this.current_folder != null)
|
||||
this.current_folder.properties.notify.disconnect(update_headerbar);
|
||||
|
||||
// connect to new folder
|
||||
if (folder != null)
|
||||
folder.properties.notify.connect(update_headerbar);
|
||||
|
||||
|
||||
// swap it in
|
||||
current_folder = folder;
|
||||
|
||||
this.current_folder = folder;
|
||||
|
||||
update_headerbar();
|
||||
}
|
||||
|
||||
|
||||
private void on_account_available(Geary.AccountInformation account) {
|
||||
try {
|
||||
progress_monitor.add(Geary.Engine.instance.get_account_instance(account).opening_monitor);
|
||||
progress_monitor.add(Geary.Engine.instance.get_account_instance(account).sending_monitor);
|
||||
this.progress_monitor.add(Geary.Engine.instance.get_account_instance(account).opening_monitor);
|
||||
this.progress_monitor.add(Geary.Engine.instance.get_account_instance(account).sending_monitor);
|
||||
} catch (Error e) {
|
||||
debug("Could not access account progress monitors: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void on_account_unavailable(Geary.AccountInformation account) {
|
||||
try {
|
||||
progress_monitor.remove(Geary.Engine.instance.get_account_instance(account).opening_monitor);
|
||||
progress_monitor.remove(Geary.Engine.instance.get_account_instance(account).sending_monitor);
|
||||
this.progress_monitor.remove(Geary.Engine.instance.get_account_instance(account).opening_monitor);
|
||||
this.progress_monitor.remove(Geary.Engine.instance.get_account_instance(account).sending_monitor);
|
||||
} catch (Error e) {
|
||||
debug("Could not access account progress monitors: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void on_change_orientation() {
|
||||
bool horizontal = GearyApplication.instance.config.folder_list_pane_horizontal;
|
||||
bool initial = true;
|
||||
|
||||
if (status_bar.parent != null) {
|
||||
status_bar.parent.remove(status_bar);
|
||||
|
||||
if (this.status_bar.parent != null) {
|
||||
this.status_bar.parent.remove(status_bar);
|
||||
initial = false;
|
||||
}
|
||||
|
||||
GLib.Settings.unbind(folder_paned, "position");
|
||||
folder_paned.orientation = horizontal ? Gtk.Orientation.HORIZONTAL :
|
||||
|
||||
GLib.Settings.unbind(this.folder_paned, "position");
|
||||
this.folder_paned.orientation = horizontal ? Gtk.Orientation.HORIZONTAL :
|
||||
Gtk.Orientation.VERTICAL;
|
||||
|
||||
|
||||
int folder_list_width =
|
||||
GearyApplication.instance.config.folder_list_pane_position_horizontal;
|
||||
if (horizontal) {
|
||||
if (!initial)
|
||||
conversations_paned.position += folder_list_width;
|
||||
folder_box.pack_start(status_bar, false, false);
|
||||
this.conversations_paned.position += folder_list_width;
|
||||
this.folder_box.pack_start(status_bar, false, false);
|
||||
} else {
|
||||
if (!initial)
|
||||
conversations_paned.position -= folder_list_width;
|
||||
conversation_box.pack_start(status_bar, false, false);
|
||||
this.conversations_paned.position -= folder_list_width;
|
||||
this.conversation_box.pack_start(status_bar, false, false);
|
||||
}
|
||||
|
||||
|
||||
GearyApplication.instance.config.bind(
|
||||
horizontal ? Configuration.FOLDER_LIST_PANE_POSITION_HORIZONTAL_KEY
|
||||
: Configuration.FOLDER_LIST_PANE_POSITION_VERTICAL_KEY,
|
||||
folder_paned, "position");
|
||||
this.folder_paned, "position");
|
||||
}
|
||||
|
||||
|
||||
private void update_headerbar() {
|
||||
if (current_folder == null) {
|
||||
main_toolbar.account = null;
|
||||
main_toolbar.folder = null;
|
||||
|
||||
if (this.current_folder == null) {
|
||||
this.main_toolbar.account = null;
|
||||
this.main_toolbar.folder = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
main_toolbar.account = current_folder.account.information.nickname;
|
||||
|
||||
|
||||
this.main_toolbar.account = this.current_folder.account.information.nickname;
|
||||
|
||||
/// Current folder's name followed by its unread count, i.e. "Inbox (42)"
|
||||
// except for Drafts and Outbox, where we show total count
|
||||
int count;
|
||||
switch (current_folder.special_folder_type) {
|
||||
switch (this.current_folder.special_folder_type) {
|
||||
case Geary.SpecialFolderType.DRAFTS:
|
||||
case Geary.SpecialFolderType.OUTBOX:
|
||||
count = current_folder.properties.email_total;
|
||||
count = this.current_folder.properties.email_total;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
count = current_folder.properties.email_unread;
|
||||
count = this.current_folder.properties.email_unread;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (count > 0)
|
||||
main_toolbar.folder = _("%s (%d)").printf(current_folder.get_display_name(), count);
|
||||
this.main_toolbar.folder = _("%s (%d)").printf(this.current_folder.get_display_name(), count);
|
||||
else
|
||||
main_toolbar.folder = current_folder.get_display_name();
|
||||
this.main_toolbar.folder = this.current_folder.get_display_name();
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private bool on_key_press_event(Gdk.EventKey event) {
|
||||
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
|
||||
&& (event.state & Gdk.ModifierType.SHIFT_MASK) == 0
|
||||
&& !this.search_bar.search_entry_has_focus)
|
||||
on_shift_key(true);
|
||||
|
||||
// Check whether the focused widget wants to handle it, if not let the accelerators kick in
|
||||
// via the default handling
|
||||
return propagate_key_event(event);
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private bool on_key_release_event(Gdk.EventKey event) {
|
||||
// FIXME: it's possible the user will press two shift keys. We want
|
||||
// the shift key to report as released when they release ALL of them.
|
||||
// There doesn't seem to be an easy way to do this in Gdk.
|
||||
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
|
||||
&& !this.search_bar.search_entry_has_focus)
|
||||
on_shift_key(false);
|
||||
|
||||
return propagate_key_event(event);
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private bool on_focus_event() {
|
||||
on_shift_key(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private bool on_delete_event() {
|
||||
if (Args.hidden_startup || GearyApplication.instance.config.startup_notifications)
|
||||
return hide_on_delete();
|
||||
|
||||
GearyApplication.instance.exit();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ set(RESOURCE_LIST
|
|||
STRIPBLANKS "gtk/menus.ui"
|
||||
STRIPBLANKS "login.glade"
|
||||
STRIPBLANKS "main-toolbar.ui"
|
||||
STRIPBLANKS "main-window.ui"
|
||||
STRIPBLANKS "password-dialog.glade"
|
||||
STRIPBLANKS "preferences.glade"
|
||||
STRIPBLANKS "remove_confirm.glade"
|
||||
|
|
|
|||
132
ui/main-window.ui
Normal file
132
ui/main-window.ui
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.14"/>
|
||||
<template class="MainWindow" parent="GtkApplicationWindow">
|
||||
<property name="visible">False</property>
|
||||
<property name="show_menubar">False</property>
|
||||
<property name="events">GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property>
|
||||
<signal name="delete_event" handler="on_delete_event"/>
|
||||
<signal name="key_press_event" handler="on_key_press_event"/>
|
||||
<signal name="key_release_event" handler="on_key_release_event"/>
|
||||
<signal name="focus_in_event" handler="on_focus_event"/>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkPaned" id="conversations_paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="search_bar_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">0</property>
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkPaned" id="folder_paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<style>
|
||||
<class name="geary-sidebar-pane-separator"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox" id="folder_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="folder_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<style>
|
||||
<class name="geary-folder-frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="folder_list_scrolled">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="width_request">100</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="conversation_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="conversation_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<style>
|
||||
<class name="geary-conversation-frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="conversation_list_scrolled">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="width_request">250</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
Loading…
Add table
Add a link
Reference in a new issue