mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
config updates by the frontend now skip undo by default
This commit is contained in:
parent
ea20c31b53
commit
adcdb422c5
9 changed files with 78 additions and 17 deletions
|
@ -789,8 +789,17 @@ class Collection:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def set_config(self, key: str, val: Any) -> OpChanges:
|
def set_config(self, key: str, val: Any, *, undoable: bool = False) -> OpChanges:
|
||||||
return self._backend.set_config_json(key=key, value_json=to_json_bytes(val))
|
"""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:
|
def remove_config(self, key: str) -> OpChanges:
|
||||||
return self.conf.remove(key)
|
return self.conf.remove(key)
|
||||||
|
@ -802,14 +811,18 @@ class Collection:
|
||||||
def get_config_bool(self, key: Config.Bool.Key.V) -> bool:
|
def get_config_bool(self, key: Config.Bool.Key.V) -> bool:
|
||||||
return self._backend.get_config_bool(key)
|
return self._backend.get_config_bool(key)
|
||||||
|
|
||||||
def set_config_bool(self, key: Config.Bool.Key.V, value: bool) -> OpChanges:
|
def set_config_bool(
|
||||||
return self._backend.set_config_bool(key=key, value=value)
|
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:
|
def get_config_string(self, key: Config.String.Key.V) -> str:
|
||||||
return self._backend.get_config_string(key)
|
return self._backend.get_config_string(key)
|
||||||
|
|
||||||
def set_config_string(self, key: Config.String.Key.V, value: str) -> OpChanges:
|
def set_config_string(
|
||||||
return self._backend.set_config_string(key=key, value=value)
|
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
|
# Stats
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -45,7 +45,10 @@ class ConfigManager:
|
||||||
|
|
||||||
def set(self, key: str, val: Any) -> None:
|
def set(self, key: str, val: Any) -> None:
|
||||||
self.col._backend.set_config_json_no_undo(
|
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:
|
def remove(self, key: str) -> OpChanges:
|
||||||
|
|
|
@ -180,7 +180,8 @@ class Table:
|
||||||
SearchContext(search=last_search, browser=self.browser)
|
SearchContext(search=last_search, browser=self.browser)
|
||||||
)
|
)
|
||||||
self.col.set_config_bool(
|
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_header()
|
||||||
self._restore_selection(self._toggled_selection)
|
self._restore_selection(self._toggled_selection)
|
||||||
|
|
|
@ -988,6 +988,7 @@ message RenameTagsIn {
|
||||||
message SetConfigJsonIn {
|
message SetConfigJsonIn {
|
||||||
string key = 1;
|
string key = 1;
|
||||||
bytes value_json = 2;
|
bytes value_json = 2;
|
||||||
|
bool undoable = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StockNotetype {
|
message StockNotetype {
|
||||||
|
@ -1441,11 +1442,13 @@ message Config {
|
||||||
message SetConfigBoolIn {
|
message SetConfigBoolIn {
|
||||||
Config.Bool.Key key = 1;
|
Config.Bool.Key key = 1;
|
||||||
bool value = 2;
|
bool value = 2;
|
||||||
|
bool undoable = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetConfigStringIn {
|
message SetConfigStringIn {
|
||||||
Config.String.Key key = 1;
|
Config.String.Key key = 1;
|
||||||
string value = 2;
|
string value = 2;
|
||||||
|
bool undoable = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RenderMarkdownIn {
|
message RenderMarkdownIn {
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl ConfigService for Backend {
|
||||||
fn set_config_json(&self, input: pb::SetConfigJsonIn) -> Result<pb::OpChanges> {
|
fn set_config_json(&self, input: pb::SetConfigJsonIn) -> Result<pb::OpChanges> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let val: Value = serde_json::from_slice(&input.value_json)?;
|
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)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl ConfigService for Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_config_bool(&self, input: pb::SetConfigBoolIn) -> Result<pb::OpChanges> {
|
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)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ impl ConfigService for Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_config_string(&self, input: pb::SetConfigStringIn) -> Result<pb::OpChanges> {
|
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)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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| {
|
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(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,19 @@ pub enum SchedulerVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
pub fn set_config_json<T: Serialize>(&mut self, key: &str, val: &T) -> Result<OpOutput<()>> {
|
pub fn set_config_json<T: Serialize>(
|
||||||
self.transact(Op::UpdateConfig, |col| col.set_config(key, val).map(|_| ()))
|
&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<()>> {
|
pub fn remove_config(&mut self, key: &str) -> Result<OpOutput<()>> {
|
||||||
|
|
|
@ -23,9 +23,18 @@ impl Collection {
|
||||||
.unwrap_or_else(|| default.to_string())
|
.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| {
|
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(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,12 @@ impl UndoManager {
|
||||||
self.end_step();
|
self.end_step();
|
||||||
self.counter
|
self.counter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear_current_changes(&mut self) {
|
||||||
|
if let Some(op) = &mut self.current_step {
|
||||||
|
op.changes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
|
@ -255,6 +261,12 @@ impl Collection {
|
||||||
self.state.undo.save(item.into());
|
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> {
|
pub(crate) fn current_undo_op(&self) -> Option<&UndoableOp> {
|
||||||
self.state.undo.current_op()
|
self.state.undo.current_op()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue