Add initial replacement account editor pane.

This commit is contained in:
Michael James Gratton 2018-06-03 19:28:02 +10:00
parent 05be1c1014
commit 2f0a7b9c18
10 changed files with 577 additions and 60 deletions

View file

@ -18,6 +18,8 @@ src/client/accounts/account-dialogs.vala
src/client/accounts/account-manager.vala
src/client/accounts/account-spinner-page.vala
src/client/accounts/accounts-editor.vala
src/client/accounts/accounts-editor-edit-pane.vala
src/client/accounts/accounts-editor-row.vala
src/client/accounts/add-edit-page.vala
src/client/accounts/editor.vala
src/client/accounts/goa-service-information.vala
@ -408,6 +410,7 @@ ui/account_cannot_remove.glade
ui/account_list.glade
ui/account_spinner.glade
ui/accounts_editor.ui
ui/accounts_editor_edit_pane.ui
ui/certificate_warning_dialog.glade
ui/composer-headerbar.ui
ui/composer-link-popover.ui

View file

@ -0,0 +1,161 @@
/*
* Copyright 2018 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* The main account editor window.
*/
[GtkTemplate (ui = "/org/gnome/Geary/accounts_editor_edit_pane.ui")]
public class Accounts.EditorEditPane : Gtk.Grid {
private Geary.AccountInformation account;
[GtkChild]
private Gtk.ListBox details_list;
[GtkChild]
private Gtk.ListBox addresses_list;
[GtkChild]
private Gtk.ScrolledWindow signature_scrolled;
private ClientWebView signature_preview;
[GtkChild]
private Gtk.ListBox settings_list;
public EditorEditPane(GearyApplication application,
Geary.AccountInformation account) {
this.account = account;
PropertyRow nickname_row = new PropertyRow(
account,
"nickname",
// Translators: This label in the account editor is for
// the user's name for an account.
_("Account name")
);
nickname_row.set_dim_label(true);
this.details_list.set_header_func(Editor.seperator_headers);
this.details_list.add(nickname_row);
this.addresses_list.set_header_func(Editor.seperator_headers);
this.addresses_list.add(
new AddressRow(account.primary_mailbox, get_login_session_name())
);
string? default_name = account.primary_mailbox.name;
if (Geary.String.is_empty_or_whitespace(default_name)) {
default_name = null;
}
if (account.alternate_mailboxes != null) {
foreach (Geary.RFC822.MailboxAddress alt
in account.alternate_mailboxes) {
this.addresses_list.add(new AddressRow(alt, default_name));
}
}
this.addresses_list.add(new AddRow());
this.signature_preview = new ClientWebView(application.config);
this.signature_preview.load_html(account.email_signature);
this.signature_preview.show();
this.signature_scrolled.add(this.signature_preview);
this.settings_list.set_header_func(Editor.seperator_headers);
// No settings to show at the moment, so hide the list and its
// frame until we do.
this.settings_list.get_parent().hide();
}
private string? get_login_session_name() {
string? name = Environment.get_real_name();
if (Geary.String.is_empty(name) || name == "Unknown") {
name = null;
}
return name;
}
}
private class Accounts.PropertyRow : LabelledEditorRow {
private GLib.Object object;
private string property_name;
private Gtk.Label value = new Gtk.Label("");
public PropertyRow(Object object,
string property_name,
string label) {
base(label);
this.object = object;
this.property_name = property_name;
this.value.show();
this.layout.add(this.value);
update();
}
public void update() {
string? value = null;
this.object.get(this.property_name, ref value);
if (value != null) {
this.value.set_text(value);
}
}
}
private class Accounts.AddressRow : LabelledEditorRow {
private Geary.RFC822.MailboxAddress address;
private string? fallback_name;
private Gtk.Label value = new Gtk.Label("");
public AddressRow(Geary.RFC822.MailboxAddress address,
string? fallback_name) {
base("");
this.address = address;
this.fallback_name = fallback_name;
this.value.show();
this.layout.add(this.value);
update();
}
public void update() {
string? name = Geary.String.is_empty_or_whitespace(this.address.name)
? this.fallback_name
: this.address.name;
if (Geary.String.is_empty_or_whitespace(name)) {
name = _("No name set");
set_dim_label(true);
} else {
set_dim_label(false);
}
this.label.set_text(name);
this.value.set_text(this.address.address.strip());
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2018 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
internal class Accounts.EditorRow : Gtk.ListBoxRow {
protected Gtk.Grid layout { get; private set; default = new Gtk.Grid(); }
public EditorRow() {
get_style_context().add_class("geary-settings");
this.layout.orientation = Gtk.Orientation.HORIZONTAL;
this.layout.show();
add(this.layout);
this.show();
}
}
internal class Accounts.LabelledEditorRow : EditorRow {
protected Gtk.Label label { get; private set; default = new Gtk.Label(""); }
public LabelledEditorRow(string label) {
this.label.set_text(label);
this.label.set_hexpand(true);
this.label.halign = Gtk.Align.START;
this.label.show();
this.layout.add(this.label);
}
public void set_dim_label(bool is_dim) {
if (is_dim) {
this.label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
} else {
this.label.get_style_context().remove_class(Gtk.STYLE_CLASS_DIM_LABEL);
}
}
}
internal class Accounts.AddRow : EditorRow {
public AddRow() {
Gtk.Image add_icon = new Gtk.Image.from_icon_name(
"list-add-symbolic", Gtk.IconSize.BUTTON
);
add_icon.set_hexpand(true);
add_icon.show();
this.layout.add(add_icon);
}
}

View file

@ -12,6 +12,15 @@
public class Accounts.Editor : Gtk.Dialog {
internal static void seperator_headers(Gtk.ListBoxRow row,
Gtk.ListBoxRow? first) {
if (first == null) {
row.set_header(null);
} else if (row.get_header() == null) {
row.set_header(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
}
}
private static int ordinal_sort(Gtk.ListBoxRow a, Gtk.ListBoxRow b) {
AccountRow? account_a = a as AccountRow;
AccountRow? account_b = b as AccountRow;
@ -27,25 +36,46 @@ public class Accounts.Editor : Gtk.Dialog {
);
}
private static void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? first) {
if (first == null) {
row.set_header(null);
} else if (row.get_header() == null) {
row.set_header(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
}
}
/**
* The current application instance.
*
* Note this hides the {@link GtkWindow.application} property
* since we don't want the application to know about this dialog -
* it should not prevent the app from closing.
*/
internal new GearyApplication application { get; private set; }
private AccountManager accounts;
[GtkChild]
private Gtk.HeaderBar default_header;
[GtkChild]
private Gtk.Stack editor_panes;
[GtkChild]
private Gtk.Button back_button;
[GtkChild]
private Gtk.Grid list_pane;
[GtkChild]
private Gtk.ListBox accounts_list;
public Editor(AccountManager accounts, Gtk.Window parent) {
this.accounts = accounts;
set_transient_for(parent);
public Editor(GearyApplication application, Gtk.Window parent) {
this.application = application;
this.accounts = application.controller.account_manager;
this.accounts_list.set_header_func(update_header);
set_titlebar(this.default_header);
set_transient_for(parent);
set_modal(true);
// XXX Glade 3.22 won't let us set this
get_content_area().border_width = 2;
this.accounts_list.set_header_func(seperator_headers);
this.accounts_list.set_sort_func(ordinal_sort);
foreach (Geary.AccountInformation account in accounts.iterable()) {
@ -70,6 +100,15 @@ public class Accounts.Editor : Gtk.Dialog {
this.accounts_list.add(new AccountRow(account, status));
}
private void show_account(Geary.AccountInformation account) {
EditorEditPane account_pane = new EditorEditPane(
(GearyApplication) this.application,account
);
this.editor_panes.add(account_pane);
this.editor_panes.set_visible_child(account_pane);
this.back_button.show();
}
private AccountRow? get_account_row(Geary.AccountInformation account) {
AccountRow? row = null;
this.accounts_list.foreach((child) => {
@ -101,12 +140,30 @@ public class Accounts.Editor : Gtk.Dialog {
}
}
[GtkCallback]
private void on_accounts_list_row_activated(Gtk.ListBoxRow activated) {
AccountRow? row = activated as AccountRow;
if (row != null) {
show_account(row.account);
}
}
[GtkCallback]
private void on_back_button_clicked() {
Gtk.Widget visible_pane = this.editor_panes.get_visible_child();
if (visible_pane != list_pane) {
this.editor_panes.remove(visible_pane);
} else {
this.back_button.hide();
}
}
}
private class Accounts.AccountRow : Gtk.ListBoxRow {
private class Accounts.AccountRow : EditorRow {
public Geary.AccountInformation account;
internal Geary.AccountInformation account;
private Gtk.Image unavailable_icon = new Gtk.Image.from_icon_name(
"dialog-warning-symbolic", Gtk.IconSize.BUTTON
@ -118,20 +175,16 @@ private class Accounts.AccountRow : Gtk.ListBoxRow {
public AccountRow(Geary.AccountInformation account,
AccountManager.Status status) {
this.account = account;
get_style_context().add_class("geary-settings");
this.unavailable_icon.no_show_all = true;
this.account_name.show();
this.account_name.set_hexpand(true);
this.account_name.halign = Gtk.Align.START;
Gtk.Grid layout = new Gtk.Grid();
layout.orientation = Gtk.Orientation.HORIZONTAL;
layout.add(this.unavailable_icon);
layout.add(this.account_name);
layout.add(this.account_details);
this.account_details.show();
add(layout);
this.layout.add(this.unavailable_icon);
this.layout.add(this.account_name);
this.layout.add(this.account_details);
update(status);
}
@ -187,25 +240,3 @@ private class Accounts.AccountRow : Gtk.ListBoxRow {
}
}
private class Accounts.AddRow : Gtk.ListBoxRow {
public AddRow() {
get_style_context().add_class("geary-settings");
Gtk.Image add_icon = new Gtk.Image.from_icon_name(
"list-add-symbolic", Gtk.IconSize.BUTTON
);
add_icon.set_hexpand(true);
Gtk.Grid layout = new Gtk.Grid();
layout.orientation = Gtk.Orientation.HORIZONTAL;
layout.add(add_icon);
add(layout);
}
}

View file

@ -422,10 +422,7 @@ public class GearyApplication : Gtk.Application {
}
private void on_activate_accounts() {
Accounts.Editor editor = new Accounts.Editor(
this.controller.account_manager, get_active_window()
);
editor.show_all();
Accounts.Editor editor = new Accounts.Editor(this, get_active_window());
editor.run();
editor.destroy();
}

View file

@ -20,6 +20,8 @@ geary_client_vala_sources = files(
'accounts/account-manager.vala',
'accounts/account-spinner-page.vala',
'accounts/accounts-editor.vala',
'accounts/accounts-editor-edit-pane.vala',
'accounts/accounts-editor-row.vala',
'accounts/add-edit-page.vala',
'accounts/goa-service-information.vala',
'accounts/local-service-information.vala',

View file

@ -13,7 +13,6 @@
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
@ -32,11 +31,12 @@
</packing>
</child>
<child>
<object class="GtkStack">
<object class="GtkStack" id="editor_panes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">slide-left-right</property>
<child>
<object class="GtkGrid">
<object class="GtkGrid" id="list_pane">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
@ -59,8 +59,8 @@
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
@ -69,6 +69,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_accounts_list_row_activated" swapped="no"/>
</object>
</child>
<child type="label_item">
@ -107,13 +108,43 @@
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<placeholder/>
</child>
<style>
<class name="geary-accounts-editor"/>
</style>
</template>
<object class="GtkHeaderBar" id="default_header">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Accounts</property>
<property name="has_subtitle">False</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Accounts</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton" id="back_button">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_back_button_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="icon_name">go-previous-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
</child>
</template>
</object>
</interface>

View file

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="AccountsEditorEditPane" parent="GtkGrid">
<property name="name">1</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="min_content_height">400</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="details_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Email addresses</property>
<style>
<class name="geary-settings-heading"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="addresses_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Signature</property>
<style>
<class name="geary-settings-heading"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="settings_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkButtonBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes" comments="This is a button in the account settings to show server settings.">Server Settings</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes" comments="This is the remove account button in the account settings.">Remove Account</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Remove this account from Geary</property>
<style>
<class name="destructive-action"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
<property name="secondary">True</property>
</packing>
</child>
<style>
<class name="geary-settings"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</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="GtkScrolledWindow" id="signature_scrolled">
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="vscrollbar_policy">never</property>
<property name="min_content_height">40</property>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<style>
<class name="geary-account-view"/>
</style>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</template>
</interface>

View file

@ -194,6 +194,16 @@ grid.geary-account-view image:dir(rtl) {
margin-left: 6px;
}
row.geary-settings {
padding: 16px;
label.geary-settings-heading {
font-weight: bold;
margin-top: 24px;
margin-bottom: 12px;
}
row.geary-settings {
padding: 18px;
}
buttonbox.geary-settings {
margin-top: 36px;
}

View file

@ -5,6 +5,7 @@
<file compressed="true" preprocess="xml-stripblanks">account_list.glade</file>
<file compressed="true" preprocess="xml-stripblanks">account_spinner.glade</file>
<file compressed="true" preprocess="xml-stripblanks">accounts_editor.ui</file>
<file compressed="true" preprocess="xml-stripblanks">accounts_editor_edit_pane.ui</file>
<file compressed="true" preprocess="xml-stripblanks">certificate_warning_dialog.glade</file>
<file compressed="true">client-web-view.js</file>
<file compressed="true">client-web-view-allow-remote-images.js</file>