config updates by the frontend now skip undo by default

This commit is contained in:
Damien Elmes 2021-05-24 14:50:46 +10:00
parent ea20c31b53
commit adcdb422c5
9 changed files with 78 additions and 17 deletions

View file

@ -789,8 +789,17 @@ class Collection:
except KeyError:
return default
def set_config(self, key: str, val: Any) -> OpChanges:
return self._backend.set_config_json(key=key, value_json=to_json_bytes(val))
def set_config(self, key: str, val: Any, *, undoable: bool = False) -> OpChanges:
"""Set a single config variable to any JSON-serializable value. The config
is currently sent on every sync, so please don't store more than a few
kilobytes in it.
By default, no undo entry will be created, but the existing undo history
will be preserved. Set `undoable=True` to allow the change to be undone;
see undo code for how you can merge multiple undo entries."""
return self._backend.set_config_json(
key=key, value_json=to_json_bytes(val), undoable=undoable
)
def remove_config(self, key: str) -> OpChanges:
return self.conf.remove(key)
@ -802,14 +811,18 @@ class Collection:
def get_config_bool(self, key: Config.Bool.Key.V) -> bool:
return self._backend.get_config_bool(key)
def set_config_bool(self, key: Config.Bool.Key.V, value: bool) -> OpChanges:
return self._backend.set_config_bool(key=key, value=value)
def set_config_bool(
self, key: Config.Bool.Key.V, value: bool, *, undoable: bool = False
) -> OpChanges:
return self._backend.set_config_bool(key=key, value=value, undoable=undoable)
def get_config_string(self, key: Config.String.Key.V) -> str:
return self._backend.get_config_string(key)
def set_config_string(self, key: Config.String.Key.V, value: str) -> OpChanges:
return self._backend.set_config_string(key=key, value=value)
def set_config_string(
self, key: Config.String.Key.V, value: str, undoable: bool = False
) -> OpChanges:
return self._backend.set_config_string(key=key, value=value, undoable=undoable)
# Stats
##########################################################################

View file

@ -45,7 +45,10 @@ class ConfigManager:
def set(self, key: str, val: Any) -> None:
self.col._backend.set_config_json_no_undo(
key=key, value_json=to_json_bytes(val)
key=key,
value_json=to_json_bytes(val),
# this argument is ignored
undoable=True,
)
def remove(self, key: str) -> OpChanges:

View file

@ -180,7 +180,8 @@ class Table:
SearchContext(search=last_search, browser=self.browser)
)
self.col.set_config_bool(
Config.Bool.BROWSER_TABLE_SHOW_NOTES_MODE, self.is_notes_mode()
Config.Bool.BROWSER_TABLE_SHOW_NOTES_MODE,
self.is_notes_mode(),
)
self._restore_header()
self._restore_selection(self._toggled_selection)

View file

@ -988,6 +988,7 @@ message RenameTagsIn {
message SetConfigJsonIn {
string key = 1;
bytes value_json = 2;
bool undoable = 3;
}
message StockNotetype {
@ -1441,11 +1442,13 @@ message Config {
message SetConfigBoolIn {
Config.Bool.Key key = 1;
bool value = 2;
bool undoable = 3;
}
message SetConfigStringIn {
Config.String.Key key = 1;
string value = 2;
bool undoable = 3;
}
message RenderMarkdownIn {

View file

@ -65,7 +65,7 @@ impl ConfigService for Backend {
fn set_config_json(&self, input: pb::SetConfigJsonIn) -> Result<pb::OpChanges> {
self.with_col(|col| {
let val: Value = serde_json::from_slice(&input.value_json)?;
col.set_config_json(input.key.as_str(), &val)
col.set_config_json(input.key.as_str(), &val, input.undoable)
})
.map(Into::into)
}
@ -100,7 +100,7 @@ impl ConfigService for Backend {
}
fn set_config_bool(&self, input: pb::SetConfigBoolIn) -> Result<pb::OpChanges> {
self.with_col(|col| col.set_config_bool(input.key().into(), input.value))
self.with_col(|col| col.set_config_bool(input.key().into(), input.value, input.undoable))
.map(Into::into)
}
@ -113,7 +113,7 @@ impl ConfigService for Backend {
}
fn set_config_string(&self, input: pb::SetConfigStringIn) -> Result<pb::OpChanges> {
self.with_col(|col| col.set_config_string(input.key().into(), &input.value))
self.with_col(|col| col.set_config_string(input.key().into(), &input.value, input.undoable))
.map(Into::into)
}

View file

@ -70,9 +70,18 @@ impl Collection {
}
}
pub fn set_config_bool(&mut self, key: BoolKey, value: bool) -> Result<OpOutput<()>> {
pub fn set_config_bool(
&mut self,
key: BoolKey,
value: bool,
undoable: bool,
) -> Result<OpOutput<()>> {
self.transact(Op::UpdateConfig, |col| {
col.set_config(key, &value).map(|_| ())
col.set_config(key, &value)?;
if !undoable {
col.clear_current_undo_step_changes();
}
Ok(())
})
}
}

View file

@ -70,8 +70,19 @@ pub enum SchedulerVersion {
}
impl Collection {
pub fn set_config_json<T: Serialize>(&mut self, key: &str, val: &T) -> Result<OpOutput<()>> {
self.transact(Op::UpdateConfig, |col| col.set_config(key, val).map(|_| ()))
pub fn set_config_json<T: Serialize>(
&mut self,
key: &str,
val: &T,
undoable: bool,
) -> Result<OpOutput<()>> {
self.transact(Op::UpdateConfig, |col| {
col.set_config(key, val)?;
if !undoable {
col.clear_current_undo_step_changes();
}
Ok(())
})
}
pub fn remove_config(&mut self, key: &str) -> Result<OpOutput<()>> {

View file

@ -23,9 +23,18 @@ impl Collection {
.unwrap_or_else(|| default.to_string())
}
pub fn set_config_string(&mut self, key: StringKey, val: &str) -> Result<OpOutput<()>> {
pub fn set_config_string(
&mut self,
key: StringKey,
val: &str,
undoable: bool,
) -> Result<OpOutput<()>> {
self.transact(Op::UpdateConfig, |col| {
col.set_config_string_inner(key, val).map(|_| ())
col.set_config_string_inner(key, val)?;
if !undoable {
col.clear_current_undo_step_changes();
}
Ok(())
})
}
}

View file

@ -182,6 +182,12 @@ impl UndoManager {
self.end_step();
self.counter
}
fn clear_current_changes(&mut self) {
if let Some(op) = &mut self.current_step {
op.changes.clear();
}
}
}
impl Collection {
@ -255,6 +261,12 @@ impl Collection {
self.state.undo.save(item.into());
}
/// Forget any recorded changes in the current transaction, allowing
/// a minor change like a config update to bypass undo.
pub(crate) fn clear_current_undo_step_changes(&mut self) {
self.state.undo.clear_current_changes()
}
pub(crate) fn current_undo_op(&self) -> Option<&UndoableOp> {
self.state.undo.current_op()
}