mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
add a separate 'rename deck' method
This commit is contained in:
parent
4bd120cc4b
commit
984e2c2666
7 changed files with 84 additions and 43 deletions
|
@ -250,11 +250,13 @@ class DeckManager:
|
||||||
deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
|
deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
|
||||||
)
|
)
|
||||||
|
|
||||||
def rename(self, g: Deck, newName: str) -> None:
|
def rename(self, deck: Union[Deck, int], new_name: str) -> None:
|
||||||
"Rename deck prefix to NAME if not exists. Updates children."
|
"Rename deck prefix to NAME if not exists. Updates children."
|
||||||
g["name"] = newName
|
if isinstance(deck, int):
|
||||||
self.update(g, preserve_usn=False)
|
deck_id = deck
|
||||||
return
|
else:
|
||||||
|
deck_id = deck["id"]
|
||||||
|
self.col._backend.rename_deck(deck_id=deck_id, new_name=new_name)
|
||||||
|
|
||||||
# Drag/drop
|
# Drag/drop
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
|
@ -132,6 +132,7 @@ service DecksService {
|
||||||
rpc NewDeckLegacy(Bool) returns (Json);
|
rpc NewDeckLegacy(Bool) returns (Json);
|
||||||
rpc RemoveDeck(DeckID) returns (Empty);
|
rpc RemoveDeck(DeckID) returns (Empty);
|
||||||
rpc DragDropDecks(DragDropDecksIn) returns (Empty);
|
rpc DragDropDecks(DragDropDecksIn) returns (Empty);
|
||||||
|
rpc RenameDeck(RenameDeckIn) returns (Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
service NotesService {
|
service NotesService {
|
||||||
|
@ -1448,3 +1449,8 @@ message DeckAndNotetype {
|
||||||
int64 deck_id = 1;
|
int64 deck_id = 1;
|
||||||
int64 notetype_id = 2;
|
int64 notetype_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message RenameDeckIn {
|
||||||
|
int64 deck_id = 1;
|
||||||
|
string new_name = 2;
|
||||||
|
}
|
|
@ -124,4 +124,21 @@ impl DecksService for Backend {
|
||||||
self.with_col(|col| col.drag_drop_decks(&source_dids, target_did))
|
self.with_col(|col| col.drag_drop_decks(&source_dids, target_did))
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rename_deck(&self, input: pb::RenameDeckIn) -> Result<pb::Empty> {
|
||||||
|
self.with_col(|col| col.rename_deck(input.deck_id.into(), &input.new_name))
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<pb::DeckId> for DeckID {
|
||||||
|
fn from(did: pb::DeckId) -> Self {
|
||||||
|
DeckID(did.did)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DeckID> for pb::DeckId {
|
||||||
|
fn from(did: DeckID) -> Self {
|
||||||
|
pb::DeckId { did: did.0 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,18 +63,6 @@ impl From<pb::NoteTypeId> for NoteTypeID {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<pb::DeckId> for DeckID {
|
|
||||||
fn from(did: pb::DeckId) -> Self {
|
|
||||||
DeckID(did.did)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DeckID> for pb::DeckId {
|
|
||||||
fn from(did: DeckID) -> Self {
|
|
||||||
pb::DeckId { did: did.0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<pb::DeckConfigId> for DeckConfID {
|
impl From<pb::DeckConfigId> for DeckConfID {
|
||||||
fn from(dcid: pb::DeckConfigId) -> Self {
|
fn from(dcid: pb::DeckConfigId) -> Self {
|
||||||
DeckConfID(dcid.dcid)
|
DeckConfID(dcid.dcid)
|
||||||
|
|
|
@ -292,30 +292,39 @@ impl Collection {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_deck(&mut self, deck: &mut Deck) -> Result<()> {
|
pub fn update_deck(&mut self, deck: &mut Deck) -> Result<()> {
|
||||||
self.transact(Some(UndoableOpKind::UpdateDeck), |col| {
|
self.transact(Some(UndoableOpKind::UpdateDeck), |col| {
|
||||||
let usn = col.usn()?;
|
let existing_deck = col.storage.get_deck(deck.id)?.ok_or(AnkiError::NotFound)?;
|
||||||
col.prepare_deck_for_update(deck, usn)?;
|
col.update_deck_inner(deck, existing_deck, col.usn()?)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rename_deck(&mut self, did: DeckID, new_human_name: &str) -> Result<()> {
|
||||||
|
self.transact(Some(UndoableOpKind::RenameDeck), |col| {
|
||||||
|
let existing_deck = col.storage.get_deck(did)?.ok_or(AnkiError::NotFound)?;
|
||||||
|
let mut deck = existing_deck.clone();
|
||||||
|
deck.name = human_deck_name_to_native(new_human_name);
|
||||||
|
col.update_deck_inner(&mut deck, existing_deck, col.usn()?)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_deck_inner(&mut self, deck: &mut Deck, original: Deck, usn: Usn) -> Result<()> {
|
||||||
|
self.prepare_deck_for_update(deck, usn)?;
|
||||||
deck.set_modified(usn);
|
deck.set_modified(usn);
|
||||||
if let Some(existing_deck) = col.storage.get_deck(deck.id)? {
|
let name_changed = original.name != deck.name;
|
||||||
let name_changed = existing_deck.name != deck.name;
|
|
||||||
if name_changed {
|
if name_changed {
|
||||||
// match closest parent name
|
// match closest parent name
|
||||||
col.match_or_create_parents(deck, usn)?;
|
self.match_or_create_parents(deck, usn)?;
|
||||||
// rename children
|
// rename children
|
||||||
col.rename_child_decks(&existing_deck, &deck.name, usn)?;
|
self.rename_child_decks(&original, &deck.name, usn)?;
|
||||||
}
|
}
|
||||||
col.update_single_deck_undoable(deck, &existing_deck)?;
|
self.update_single_deck_undoable(deck, original)?;
|
||||||
if name_changed {
|
if name_changed {
|
||||||
// after updating, we need to ensure all grandparents exist, which may not be the case
|
// after updating, we need to ensure all grandparents exist, which may not be the case
|
||||||
// in the parent->child case
|
// in the parent->child case
|
||||||
col.create_missing_parents(&deck.name, usn)?;
|
self.create_missing_parents(&deck.name, usn)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
|
||||||
Err(AnkiError::invalid_input("updating non-existent deck"))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add/update a single deck when syncing/importing. Ensures name is unique
|
/// Add/update a single deck when syncing/importing. Ensures name is unique
|
||||||
|
@ -377,7 +386,7 @@ impl Collection {
|
||||||
let new_name = format!("{}\x1f{}", new_name, child_only.join("\x1f"));
|
let new_name = format!("{}\x1f{}", new_name, child_only.join("\x1f"));
|
||||||
child.name = new_name;
|
child.name = new_name;
|
||||||
child.set_modified(usn);
|
child.set_modified(usn);
|
||||||
self.update_single_deck_undoable(&mut child, &original)?;
|
self.update_single_deck_undoable(&mut child, original)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -600,7 +609,7 @@ impl Collection {
|
||||||
deck.reset_stats_if_day_changed(today);
|
deck.reset_stats_if_day_changed(today);
|
||||||
mutator(&mut deck.common);
|
mutator(&mut deck.common);
|
||||||
deck.set_modified(usn);
|
deck.set_modified(usn);
|
||||||
self.update_single_deck_undoable(deck, &original)
|
self.update_single_deck_undoable(deck, original)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drag_drop_decks(
|
pub fn drag_drop_decks(
|
||||||
|
@ -761,6 +770,23 @@ mod test {
|
||||||
col.add_or_update_deck(&mut middle)?;
|
col.add_or_update_deck(&mut middle)?;
|
||||||
assert_eq!(middle.name, "other+");
|
assert_eq!(middle.name, "other+");
|
||||||
|
|
||||||
|
// public function takes human name
|
||||||
|
col.rename_deck(middle.id, "one::two")?;
|
||||||
|
assert_eq!(
|
||||||
|
sorted_names(&col),
|
||||||
|
vec![
|
||||||
|
"Default",
|
||||||
|
"one",
|
||||||
|
"one::two",
|
||||||
|
"one::two::baz",
|
||||||
|
"one::two::baz2",
|
||||||
|
"other",
|
||||||
|
"quux",
|
||||||
|
"quux::foo",
|
||||||
|
"quux::foo::baz",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl Collection {
|
||||||
.storage
|
.storage
|
||||||
.get_deck(deck.id)?
|
.get_deck(deck.id)?
|
||||||
.ok_or_else(|| AnkiError::invalid_input("deck disappeared"))?;
|
.ok_or_else(|| AnkiError::invalid_input("deck disappeared"))?;
|
||||||
self.update_single_deck_undoable(&mut *deck, ¤t)
|
self.update_single_deck_undoable(&mut *deck, current)
|
||||||
}
|
}
|
||||||
UndoableDeckChange::Removed(deck) => self.restore_deleted_deck(*deck),
|
UndoableDeckChange::Removed(deck) => self.restore_deleted_deck(*deck),
|
||||||
UndoableDeckChange::GraveAdded(e) => self.remove_deck_grave(e.0, e.1),
|
UndoableDeckChange::GraveAdded(e) => self.remove_deck_grave(e.0, e.1),
|
||||||
|
@ -52,10 +52,10 @@ impl Collection {
|
||||||
pub(super) fn update_single_deck_undoable(
|
pub(super) fn update_single_deck_undoable(
|
||||||
&mut self,
|
&mut self,
|
||||||
deck: &mut Deck,
|
deck: &mut Deck,
|
||||||
original: &Deck,
|
original: Deck,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.state.deck_cache.clear();
|
self.state.deck_cache.clear();
|
||||||
self.save_undo(UndoableDeckChange::Updated(Box::new(original.clone())));
|
self.save_undo(UndoableDeckChange::Updated(Box::new(original)));
|
||||||
self.storage.update_deck(deck)
|
self.storage.update_deck(deck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub enum UndoableOpKind {
|
||||||
Bury,
|
Bury,
|
||||||
RemoveDeck,
|
RemoveDeck,
|
||||||
RemoveNote,
|
RemoveNote,
|
||||||
|
RenameDeck,
|
||||||
Suspend,
|
Suspend,
|
||||||
UnburyUnsuspend,
|
UnburyUnsuspend,
|
||||||
UpdateCard,
|
UpdateCard,
|
||||||
|
@ -35,6 +36,7 @@ impl Collection {
|
||||||
UndoableOpKind::Bury => TR::StudyingBury,
|
UndoableOpKind::Bury => TR::StudyingBury,
|
||||||
UndoableOpKind::RemoveDeck => TR::DecksDeleteDeck,
|
UndoableOpKind::RemoveDeck => TR::DecksDeleteDeck,
|
||||||
UndoableOpKind::RemoveNote => TR::StudyingDeleteNote,
|
UndoableOpKind::RemoveNote => TR::StudyingDeleteNote,
|
||||||
|
UndoableOpKind::RenameDeck => TR::ActionsRenameDeck,
|
||||||
UndoableOpKind::Suspend => TR::StudyingSuspend,
|
UndoableOpKind::Suspend => TR::StudyingSuspend,
|
||||||
UndoableOpKind::UnburyUnsuspend => TR::UndoUnburyUnsuspend,
|
UndoableOpKind::UnburyUnsuspend => TR::UndoUnburyUnsuspend,
|
||||||
UndoableOpKind::UpdateCard => TR::UndoUpdateCard,
|
UndoableOpKind::UpdateCard => TR::UndoUpdateCard,
|
||||||
|
|
Loading…
Reference in a new issue