Anki/rslib/src/decks/reparent.rs
Kris Cherven 52781aaab8
Fix superfluous message when a deck is dragged to its parent (#3859)
* Move the solution to the Rust layer

* CONTRIBUTORS fix (1)

* CONTRIBUTORS fix (2)

* Fix CI issues

* Simplify reparenting solution

* Fix reparenting message with tags

* Revert "Fix reparenting message with tags"

This reverts commit 199958c1c5.

* tags: Return None in reparented_name when the name is unchanged
2025-03-31 16:47:56 +07:00

62 lines
2.1 KiB
Rust

// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::error::FilteredDeckError;
use crate::prelude::*;
impl Collection {
pub fn reparent_decks(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<OpOutput<usize>> {
self.transact(Op::ReparentDeck, |col| {
col.reparent_decks_inner(deck_ids, new_parent)
})
}
pub fn reparent_decks_inner(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<usize> {
let usn = self.usn()?;
let target_deck;
let mut target_name = None;
if let Some(target) = new_parent {
if let Some(target) = self.storage.get_deck(target)? {
if target.is_filtered() {
return Err(FilteredDeckError::MustBeLeafNode.into());
}
target_deck = target;
target_name = Some(&target_deck.name);
}
}
let mut count = 0;
for deck in deck_ids {
if let Some(mut deck) = self.storage.get_deck(*deck)? {
if let Some(new_name) = deck.name.reparented_name(target_name) {
if new_name == deck.name {
continue;
}
count += 1;
let orig = deck.clone();
// this is basically update_deck_inner(), except:
// - we skip the normalization in prepare_for_update()
// - we skip the match_or_create_parents() step
// - we skip the final create_missing_parents(), as we don't allow parent->child
// renames
deck.set_modified(usn);
deck.name = new_name;
self.ensure_deck_name_unique(&mut deck, usn)?;
self.rename_child_decks(&orig, &deck.name, usn)?;
self.update_single_deck_undoable(&mut deck, orig)?;
}
}
}
Ok(count)
}
}