parent
e5b0ff4fe2
commit
48e7a493a9
|
@ -488,6 +488,15 @@ to
|
||||||
.It Cm printenv Ar KEY
|
.It Cm printenv Ar KEY
|
||||||
print environment variable
|
print environment variable
|
||||||
.Ar KEY
|
.Ar KEY
|
||||||
|
.It Cm quit
|
||||||
|
Quits
|
||||||
|
.Nm Ns
|
||||||
|
\&.
|
||||||
|
.It Cm reload-config
|
||||||
|
Reloads configuration but only if account configuration is unchanged.
|
||||||
|
Useful if you want to reload some settings without restarting
|
||||||
|
.Nm Ns
|
||||||
|
\&.
|
||||||
.El
|
.El
|
||||||
.Sh SHORTCUTS
|
.Sh SHORTCUTS
|
||||||
See
|
See
|
||||||
|
|
|
@ -790,6 +790,17 @@ Alternatives(&[to_stream!(One(Literal("add-attachment")), One(Filepath)), to_str
|
||||||
Ok((input, Quit))
|
Ok((input, Quit))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{ tags: ["reload-config"],
|
||||||
|
desc: "reload configuration file",
|
||||||
|
tokens: &[One(Literal("reload-config"))],
|
||||||
|
parser:(
|
||||||
|
fn reload_config(input: &[u8]) -> IResult<&[u8], Action> {
|
||||||
|
let (input, _) = tag("reload-config")(input.trim())?;
|
||||||
|
let (input, _) = eof(input.trim())?;
|
||||||
|
Ok((input, ReloadConfiguration))
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -883,6 +894,7 @@ pub fn parse_command(input: &[u8]) -> Result<Action, MeliError> {
|
||||||
account_action,
|
account_action,
|
||||||
print_setting,
|
print_setting,
|
||||||
toggle_mouse,
|
toggle_mouse,
|
||||||
|
reload_config,
|
||||||
quit,
|
quit,
|
||||||
))(input)
|
))(input)
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
|
|
|
@ -121,6 +121,7 @@ pub enum Action {
|
||||||
Mailbox(AccountName, MailboxOperation),
|
Mailbox(AccountName, MailboxOperation),
|
||||||
AccountAction(AccountName, AccountAction),
|
AccountAction(AccountName, AccountAction),
|
||||||
PrintSetting(String),
|
PrintSetting(String),
|
||||||
|
ReloadConfiguration,
|
||||||
ToggleMouse,
|
ToggleMouse,
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
@ -143,6 +144,7 @@ impl Action {
|
||||||
Action::PrintSetting(_) => false,
|
Action::PrintSetting(_) => false,
|
||||||
Action::ToggleMouse => false,
|
Action::ToggleMouse => false,
|
||||||
Action::Quit => true,
|
Action::Quit => true,
|
||||||
|
Action::ReloadConfiguration => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,13 +59,6 @@ impl fmt::Display for ContactManager {
|
||||||
impl ContactManager {
|
impl ContactManager {
|
||||||
fn new(context: &Context) -> Self {
|
fn new(context: &Context) -> Self {
|
||||||
let theme_default: ThemeAttribute = crate::conf::value(context, "theme_default");
|
let theme_default: ThemeAttribute = crate::conf::value(context, "theme_default");
|
||||||
let default_cell = {
|
|
||||||
let mut ret = Cell::with_char(' ');
|
|
||||||
ret.set_fg(theme_default.fg)
|
|
||||||
.set_bg(theme_default.bg)
|
|
||||||
.set_attrs(theme_default.attrs);
|
|
||||||
ret
|
|
||||||
};
|
|
||||||
ContactManager {
|
ContactManager {
|
||||||
id: Uuid::nil(),
|
id: Uuid::nil(),
|
||||||
parent_id: Uuid::nil(),
|
parent_id: Uuid::nil(),
|
||||||
|
@ -73,7 +66,7 @@ impl ContactManager {
|
||||||
mode: ViewMode::Edit,
|
mode: ViewMode::Edit,
|
||||||
form: FormWidget::default(),
|
form: FormWidget::default(),
|
||||||
account_pos: 0,
|
account_pos: 0,
|
||||||
content: CellBuffer::new(100, 1, default_cell),
|
content: CellBuffer::new_with_context(100, 1, None, context),
|
||||||
theme_default,
|
theme_default,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
has_changes: false,
|
has_changes: false,
|
||||||
|
@ -189,6 +182,15 @@ impl Component for ContactManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
match event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
self.content = CellBuffer::new_with_context(100, 1, None, context);
|
||||||
|
self.initialized = false;
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
match self.mode {
|
match self.mode {
|
||||||
ViewMode::Discard(ref mut selector) => {
|
ViewMode::Discard(ref mut selector) => {
|
||||||
if selector.process_event(event, context) {
|
if selector.process_event(event, context) {
|
||||||
|
|
|
@ -596,6 +596,14 @@ impl Component for ContactList {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
if let UIEvent::ConfigReload { old_settings: _ } = event {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
self.initialized = false;
|
||||||
|
self.sidebar_divider = context.settings.listing.sidebar_divider;
|
||||||
|
self.sidebar_divider_theme = conf::value(context, "mail.sidebar_divider");
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ref mut v) = self.view {
|
if let Some(ref mut v) = self.view {
|
||||||
if v.process_event(event, context) {
|
if v.process_event(event, context) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1177,6 +1177,9 @@ impl Component for Composer {
|
||||||
}
|
}
|
||||||
|
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Resize => {
|
UIEvent::Resize => {
|
||||||
self.set_dirty(true);
|
self.set_dirty(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -613,6 +613,15 @@ impl Component for Listing {
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
match event {
|
match event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
||||||
|
self.sidebar_divider =
|
||||||
|
*account_settings!(context[account_hash].listing.sidebar_divider);
|
||||||
|
self.sidebar_divider_theme = conf::value(context, "mail.sidebar_divider");
|
||||||
|
self.menu_content = CellBuffer::new_with_context(0, 0, None, context);
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Timer(n) if *n == self.menu_scrollbar_show_timer.id() => {
|
UIEvent::Timer(n) if *n == self.menu_scrollbar_show_timer.id() => {
|
||||||
if self.show_menu_scrollbar == ShowMenuScrollbar::True {
|
if self.show_menu_scrollbar == ShowMenuScrollbar::True {
|
||||||
self.show_menu_scrollbar = ShowMenuScrollbar::False;
|
self.show_menu_scrollbar = ShowMenuScrollbar::False;
|
||||||
|
|
|
@ -1691,6 +1691,43 @@ impl Component for CompactListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.color_cache = ColorCache {
|
||||||
|
even_unseen: crate::conf::value(context, "mail.listing.compact.even_unseen"),
|
||||||
|
even_selected: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.compact.even_selected",
|
||||||
|
),
|
||||||
|
even_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.compact.even_highlighted",
|
||||||
|
),
|
||||||
|
odd_unseen: crate::conf::value(context, "mail.listing.compact.odd_unseen"),
|
||||||
|
odd_selected: crate::conf::value(context, "mail.listing.compact.odd_selected"),
|
||||||
|
odd_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.compact.odd_highlighted",
|
||||||
|
),
|
||||||
|
even: crate::conf::value(context, "mail.listing.compact.even"),
|
||||||
|
odd: crate::conf::value(context, "mail.listing.compact.odd"),
|
||||||
|
attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
|
||||||
|
thread_snooze_flag: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.thread_snooze_flag",
|
||||||
|
),
|
||||||
|
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
|
||||||
|
theme_default: crate::conf::value(context, "theme_default"),
|
||||||
|
..self.color_cache
|
||||||
|
};
|
||||||
|
if !context.settings.terminal.use_color() {
|
||||||
|
self.color_cache.highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.tag_default.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.even_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.odd_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
}
|
||||||
|
self.refresh_mailbox(context, true);
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
||||||
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1616,6 +1616,34 @@ impl Component for ConversationsListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.color_cache = ColorCache {
|
||||||
|
theme_default: crate::conf::value(context, "mail.listing.conversations"),
|
||||||
|
subject: crate::conf::value(context, "mail.listing.conversations.subject"),
|
||||||
|
from: crate::conf::value(context, "mail.listing.conversations.from"),
|
||||||
|
date: crate::conf::value(context, "mail.listing.conversations.date"),
|
||||||
|
selected: crate::conf::value(context, "mail.listing.conversations.selected"),
|
||||||
|
unseen: crate::conf::value(context, "mail.listing.conversations.unseen"),
|
||||||
|
highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.conversations.highlighted",
|
||||||
|
),
|
||||||
|
attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
|
||||||
|
thread_snooze_flag: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.thread_snooze_flag",
|
||||||
|
),
|
||||||
|
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
|
||||||
|
..self.color_cache
|
||||||
|
};
|
||||||
|
|
||||||
|
if !context.settings.terminal.use_color() {
|
||||||
|
self.color_cache.highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.tag_default.attrs |= Attr::REVERSE;
|
||||||
|
}
|
||||||
|
self.refresh_mailbox(context, true);
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
||||||
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1215,6 +1215,41 @@ impl Component for PlainListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.color_cache = ColorCache {
|
||||||
|
even: crate::conf::value(context, "mail.listing.plain.even"),
|
||||||
|
odd: crate::conf::value(context, "mail.listing.plain.odd"),
|
||||||
|
even_unseen: crate::conf::value(context, "mail.listing.plain.even_unseen"),
|
||||||
|
odd_unseen: crate::conf::value(context, "mail.listing.plain.odd_unseen"),
|
||||||
|
even_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.plain.even_highlighted",
|
||||||
|
),
|
||||||
|
odd_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.plain.odd_highlighted",
|
||||||
|
),
|
||||||
|
even_selected: crate::conf::value(context, "mail.listing.plain.even_selected"),
|
||||||
|
odd_selected: crate::conf::value(context, "mail.listing.plain.odd_selected"),
|
||||||
|
attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
|
||||||
|
thread_snooze_flag: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.thread_snooze_flag",
|
||||||
|
),
|
||||||
|
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
|
||||||
|
theme_default: crate::conf::value(context, "theme_default"),
|
||||||
|
..self.color_cache
|
||||||
|
};
|
||||||
|
if !context.settings.terminal.use_color() {
|
||||||
|
self.color_cache.highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.tag_default.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.even_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.odd_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.refresh_mailbox(context, true);
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
UIEvent::MailboxUpdate((ref idxa, ref idxf))
|
||||||
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
if (*idxa, *idxf) == (self.new_cursor_pos.0, self.cursor_pos.1) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1184,6 +1184,39 @@ impl Component for ThreadListing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.color_cache = ColorCache {
|
||||||
|
even_unseen: crate::conf::value(context, "mail.listing.plain.even_unseen"),
|
||||||
|
even_selected: crate::conf::value(context, "mail.listing.plain.even_selected"),
|
||||||
|
even_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.plain.even_highlighted",
|
||||||
|
),
|
||||||
|
odd_unseen: crate::conf::value(context, "mail.listing.plain.odd_unseen"),
|
||||||
|
odd_selected: crate::conf::value(context, "mail.listing.plain.odd_selected"),
|
||||||
|
odd_highlighted: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.plain.odd_highlighted",
|
||||||
|
),
|
||||||
|
even: crate::conf::value(context, "mail.listing.plain.even"),
|
||||||
|
odd: crate::conf::value(context, "mail.listing.plain.odd"),
|
||||||
|
attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
|
||||||
|
thread_snooze_flag: crate::conf::value(
|
||||||
|
context,
|
||||||
|
"mail.listing.thread_snooze_flag",
|
||||||
|
),
|
||||||
|
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
|
||||||
|
theme_default: crate::conf::value(context, "theme_default"),
|
||||||
|
..self.color_cache
|
||||||
|
};
|
||||||
|
if !context.settings.terminal.use_color() {
|
||||||
|
self.color_cache.highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.tag_default.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.even_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
self.color_cache.odd_highlighted.attrs |= Attr::REVERSE;
|
||||||
|
}
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Input(Key::Char('\n')) if !self.unfocused => {
|
UIEvent::Input(Key::Char('\n')) if !self.unfocused => {
|
||||||
self.unfocused = true;
|
self.unfocused = true;
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
|
|
@ -403,6 +403,10 @@ impl Component for AccountStatus {
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
let shortcuts = self.get_shortcuts(context);
|
let shortcuts = self.get_shortcuts(context);
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Resize => {
|
UIEvent::Resize => {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1763,6 +1763,10 @@ impl Component for MailView {
|
||||||
|
|
||||||
let shortcuts = &self.get_shortcuts(context);
|
let shortcuts = &self.get_shortcuts(context);
|
||||||
match *event {
|
match *event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Input(ref key)
|
UIEvent::Input(ref key)
|
||||||
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["reply"]) =>
|
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["reply"]) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -442,6 +442,25 @@ impl Component for StatusBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
let mut progress_spinner = ProgressSpinner::new(19, context);
|
||||||
|
match context.settings.terminal.progress_spinner_sequence.as_ref() {
|
||||||
|
Some(conf::terminal::ProgressSpinnerSequence::Integer(k)) => {
|
||||||
|
progress_spinner.set_kind(*k);
|
||||||
|
}
|
||||||
|
Some(conf::terminal::ProgressSpinnerSequence::Custom(ref s)) => {
|
||||||
|
progress_spinner.set_custom_kind(s.clone());
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
if self.progress_spinner.is_active() {
|
||||||
|
progress_spinner.start();
|
||||||
|
}
|
||||||
|
self.progress_spinner = progress_spinner;
|
||||||
|
self.mouse = context.settings.terminal.use_mouse.is_true();
|
||||||
|
self.set_dirty(true);
|
||||||
|
self.container.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::ChangeMode(m) => {
|
UIEvent::ChangeMode(m) => {
|
||||||
let offset = self.status.find('|').unwrap_or_else(|| self.status.len());
|
let offset = self.status.find('|').unwrap_or_else(|| self.status.len());
|
||||||
self.status.replace_range(
|
self.status.replace_range(
|
||||||
|
@ -1194,6 +1213,10 @@ impl Component for Tabbed {
|
||||||
fn process_event(&mut self, mut event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, mut event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
let shortcuts = &self.help_curr_views;
|
let shortcuts = &self.help_curr_views;
|
||||||
match &mut event {
|
match &mut event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Input(Key::Alt(no)) if *no >= '1' && *no <= '9' => {
|
UIEvent::Input(Key::Alt(no)) if *no >= '1' && *no <= '9' => {
|
||||||
let no = *no as usize - '1' as usize;
|
let no = *no as usize - '1' as usize;
|
||||||
if no < self.children.len() {
|
if no < self.children.len() {
|
||||||
|
|
|
@ -49,6 +49,7 @@ pub struct Selector<T: 'static + PartialEq + Debug + Clone + Sync + Send, F: 'st
|
||||||
/// allow only one selection
|
/// allow only one selection
|
||||||
single_only: bool,
|
single_only: bool,
|
||||||
entries: Vec<(T, bool)>,
|
entries: Vec<(T, bool)>,
|
||||||
|
entry_titles: Vec<String>,
|
||||||
pub content: CellBuffer,
|
pub content: CellBuffer,
|
||||||
theme_default: ThemeAttribute,
|
theme_default: ThemeAttribute,
|
||||||
|
|
||||||
|
@ -104,6 +105,12 @@ impl<T: 'static + PartialEq + Debug + Clone + Sync + Send> Component for UIDialo
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
if let UIEvent::ConfigReload { old_settings: _ } = event {
|
||||||
|
self.initialise(context);
|
||||||
|
self.set_dirty(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
let shortcuts = self.get_shortcuts(context);
|
let shortcuts = self.get_shortcuts(context);
|
||||||
let mut highlighted_attrs = crate::conf::value(context, "widgets.options.highlighted");
|
let mut highlighted_attrs = crate::conf::value(context, "widgets.options.highlighted");
|
||||||
|
@ -419,6 +426,12 @@ impl Component for UIConfirmationDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
if let UIEvent::ConfigReload { old_settings: _ } = event {
|
||||||
|
self.initialise(context);
|
||||||
|
self.set_dirty(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
let shortcuts = self.get_shortcuts(context);
|
let shortcuts = self.get_shortcuts(context);
|
||||||
let mut highlighted_attrs = crate::conf::value(context, "widgets.options.highlighted");
|
let mut highlighted_attrs = crate::conf::value(context, "widgets.options.highlighted");
|
||||||
|
@ -734,68 +747,15 @@ impl Component for UIConfirmationDialog {
|
||||||
impl<T: PartialEq + Debug + Clone + Sync + Send, F: 'static + Sync + Send> Selector<T, F> {
|
impl<T: PartialEq + Debug + Clone + Sync + Send, F: 'static + Sync + Send> Selector<T, F> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
title: &str,
|
title: &str,
|
||||||
entries: Vec<(T, String)>,
|
mut entries: Vec<(T, String)>,
|
||||||
single_only: bool,
|
single_only: bool,
|
||||||
done_fn: F,
|
done_fn: F,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) -> Selector<T, F> {
|
) -> Selector<T, F> {
|
||||||
let theme_default = crate::conf::value(context, "theme_default");
|
let entry_titles = entries
|
||||||
let width = std::cmp::max(
|
.iter_mut()
|
||||||
OK_CANCEL.len(),
|
.map(|(_id, ref mut title)| std::mem::replace(title, String::new()))
|
||||||
std::cmp::max(
|
.collect::<Vec<String>>();
|
||||||
entries
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|e| e.1.len())
|
|
||||||
.map(|v| v.1.len())
|
|
||||||
.unwrap_or(0),
|
|
||||||
title.len(),
|
|
||||||
),
|
|
||||||
) + 5;
|
|
||||||
let height = entries.len()
|
|
||||||
+ if single_only {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
/* Extra room for buttons Okay/Cancel */
|
|
||||||
2
|
|
||||||
};
|
|
||||||
let mut content = CellBuffer::new_with_context(width, height, None, context);
|
|
||||||
if single_only {
|
|
||||||
for (i, e) in entries.iter().enumerate() {
|
|
||||||
write_string_to_grid(
|
|
||||||
&e.1,
|
|
||||||
&mut content,
|
|
||||||
theme_default.fg,
|
|
||||||
theme_default.bg,
|
|
||||||
theme_default.attrs,
|
|
||||||
((0, i), (width - 1, i)),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (i, e) in entries.iter().enumerate() {
|
|
||||||
write_string_to_grid(
|
|
||||||
&format!("[ ] {}", e.1),
|
|
||||||
&mut content,
|
|
||||||
theme_default.fg,
|
|
||||||
theme_default.bg,
|
|
||||||
theme_default.attrs,
|
|
||||||
((0, i), (width - 1, i)),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
write_string_to_grid(
|
|
||||||
OK_CANCEL,
|
|
||||||
&mut content,
|
|
||||||
theme_default.fg,
|
|
||||||
theme_default.bg,
|
|
||||||
theme_default.attrs | Attr::BOLD,
|
|
||||||
(
|
|
||||||
((width - OK_CANCEL.len()) / 2, height - 1),
|
|
||||||
(width - 1, height - 1),
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let mut identifiers: Vec<(T, bool)> =
|
let mut identifiers: Vec<(T, bool)> =
|
||||||
entries.into_iter().map(|(id, _)| (id, false)).collect();
|
entries.into_iter().map(|(id, _)| (id, false)).collect();
|
||||||
if single_only {
|
if single_only {
|
||||||
|
@ -803,10 +763,11 @@ impl<T: PartialEq + Debug + Clone + Sync + Send, F: 'static + Sync + Send> Selec
|
||||||
identifiers[0].1 = true;
|
identifiers[0].1 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Selector {
|
let mut ret = Selector {
|
||||||
single_only,
|
single_only,
|
||||||
entries: identifiers,
|
entries: identifiers,
|
||||||
content,
|
entry_titles,
|
||||||
|
content: Default::default(),
|
||||||
cursor: SelectorCursor::Unfocused,
|
cursor: SelectorCursor::Unfocused,
|
||||||
vertical_alignment: Alignment::Center,
|
vertical_alignment: Alignment::Center,
|
||||||
horizontal_alignment: Alignment::Center,
|
horizontal_alignment: Alignment::Center,
|
||||||
|
@ -814,9 +775,72 @@ impl<T: PartialEq + Debug + Clone + Sync + Send, F: 'static + Sync + Send> Selec
|
||||||
done: false,
|
done: false,
|
||||||
done_fn,
|
done_fn,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
theme_default,
|
theme_default: Default::default(),
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
|
};
|
||||||
|
ret.initialise(context);
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initialise(&mut self, context: &Context) {
|
||||||
|
self.theme_default = crate::conf::value(context, "theme_default");
|
||||||
|
let width = std::cmp::max(
|
||||||
|
OK_CANCEL.len(),
|
||||||
|
std::cmp::max(
|
||||||
|
self.entry_titles
|
||||||
|
.iter()
|
||||||
|
.max_by_key(|e| e.len())
|
||||||
|
.map(|v| v.len())
|
||||||
|
.unwrap_or(0),
|
||||||
|
self.title.len(),
|
||||||
|
),
|
||||||
|
) + 5;
|
||||||
|
let height = self.entries.len()
|
||||||
|
+ if self.single_only {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
/* Extra room for buttons Okay/Cancel */
|
||||||
|
2
|
||||||
|
};
|
||||||
|
let mut content = CellBuffer::new_with_context(width, height, None, context);
|
||||||
|
if self.single_only {
|
||||||
|
for (i, e) in self.entry_titles.iter().enumerate() {
|
||||||
|
write_string_to_grid(
|
||||||
|
&e,
|
||||||
|
&mut content,
|
||||||
|
self.theme_default.fg,
|
||||||
|
self.theme_default.bg,
|
||||||
|
self.theme_default.attrs,
|
||||||
|
((0, i), (width - 1, i)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i, e) in self.entry_titles.iter().enumerate() {
|
||||||
|
write_string_to_grid(
|
||||||
|
&format!("[ ] {}", &e),
|
||||||
|
&mut content,
|
||||||
|
self.theme_default.fg,
|
||||||
|
self.theme_default.bg,
|
||||||
|
self.theme_default.attrs,
|
||||||
|
((0, i), (width - 1, i)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
write_string_to_grid(
|
||||||
|
OK_CANCEL,
|
||||||
|
&mut content,
|
||||||
|
self.theme_default.fg,
|
||||||
|
self.theme_default.bg,
|
||||||
|
self.theme_default.attrs | Attr::BOLD,
|
||||||
|
(
|
||||||
|
((width - OK_CANCEL.len()) / 2, height - 1),
|
||||||
|
(width - 1, height - 1),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_done(&self) -> bool {
|
pub fn is_done(&self) -> bool {
|
||||||
|
|
|
@ -609,6 +609,10 @@ impl Component for Pager {
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
let shortcuts = self.get_shortcuts(context);
|
let shortcuts = self.get_shortcuts(context);
|
||||||
match event {
|
match event {
|
||||||
|
UIEvent::ConfigReload { old_settings: _ } => {
|
||||||
|
self.set_colors(crate::conf::value(context, "theme_default"));
|
||||||
|
self.set_dirty(true);
|
||||||
|
}
|
||||||
UIEvent::Input(ref key)
|
UIEvent::Input(ref key)
|
||||||
if shortcut!(key == shortcuts[Self::DESCRIPTION]["scroll_up"]) =>
|
if shortcut!(key == shortcuts[Self::DESCRIPTION]["scroll_up"]) =>
|
||||||
{
|
{
|
||||||
|
|
33
src/state.rs
33
src/state.rs
|
@ -1075,6 +1075,39 @@ impl State {
|
||||||
})),
|
})),
|
||||||
&mut self.context,
|
&mut self.context,
|
||||||
)));
|
)));
|
||||||
|
} else if let Action::ReloadConfiguration = action {
|
||||||
|
match Settings::new().and_then(|new_settings| {
|
||||||
|
let old_accounts = self.context.settings.accounts.keys().collect::<std::collections::HashSet<&String>>();
|
||||||
|
let new_accounts = new_settings.accounts.keys().collect::<std::collections::HashSet<&String>>();
|
||||||
|
if old_accounts != new_accounts {
|
||||||
|
return Err("cannot reload account configuration changes; restart meli instead.".into());
|
||||||
|
}
|
||||||
|
for (key, acc) in new_settings.accounts.iter() {
|
||||||
|
if toml::Value::try_from(&acc) != toml::Value::try_from(&self.context.settings.accounts[key]) {
|
||||||
|
return Err("cannot reload account configuration changes; restart meli instead.".into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if toml::Value::try_from(&new_settings) == toml::Value::try_from(&self.context.settings) {
|
||||||
|
return Err("No changes detected.".into());
|
||||||
|
}
|
||||||
|
Ok(new_settings)
|
||||||
|
}) {
|
||||||
|
Ok(new_settings) => {
|
||||||
|
let old_settings = std::mem::replace(&mut self.context.settings, new_settings);
|
||||||
|
self.context.replies.push_back(UIEvent::ConfigReload {
|
||||||
|
old_settings
|
||||||
|
});
|
||||||
|
self.context.replies.push_back(UIEvent::Resize);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
self.context.replies.push_back(UIEvent::StatusEvent(
|
||||||
|
StatusEvent::DisplayMessage(format!(
|
||||||
|
"Could not load configuration: {}",
|
||||||
|
err
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.exec_command(action);
|
self.exec_command(action);
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,9 @@ pub enum UIEvent {
|
||||||
Callback(CallbackFn),
|
Callback(CallbackFn),
|
||||||
GlobalUIDialog(Box<dyn Component>),
|
GlobalUIDialog(Box<dyn Component>),
|
||||||
Timer(Uuid),
|
Timer(Uuid),
|
||||||
|
ConfigReload {
|
||||||
|
old_settings: crate::conf::Settings,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallbackFn(pub Box<dyn FnOnce(&mut crate::Context) -> () + Send + 'static>);
|
pub struct CallbackFn(pub Box<dyn FnOnce(&mut crate::Context) -> () + Send + 'static>);
|
||||||
|
|
Loading…
Reference in New Issue