Allow creation of empty filtered decks (#2788)

* Add new button to UI

* Add bool to allow creating empty filtered in back end

* Implement logic into front end for passing on bool

* Hide option on old decks

* Show option again if any settings are changed

* Revert "Show option again if any settings are changed"

This reverts commit 094acd9c65936823fa206594da5c1f3e4eb09248.

* Revert "Hide option on old decks"

This reverts commit d20a9a240b4fd85d080e8cc52d94318416ca753f.

* Update string

* Update ftl/core/decks.ftl

---------

Co-authored-by: Damien Elmes <dae@users.noreply.github.com>
This commit is contained in:
Gustaf-C 2023-11-05 10:23:14 +08:00 committed by GitHub
parent e7436a2b23
commit e071fb471b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 21 additions and 1 deletions

View File

@ -2,6 +2,7 @@ decks-add-new-deck-ctrlandn = Add New Deck (Ctrl+N)
decks-build = Build
decks-cards-selected-by = cards selected by
decks-create-deck = Create Deck
decks_create_even_if_empty = Create/update this deck even if empty
decks-custom-steps-in-minutes = Custom steps (in minutes)
decks-deck = Deck
decks-decreasing-intervals = Decreasing intervals

View File

@ -212,4 +212,5 @@ message FilteredDeckForUpdate {
int64 id = 1;
string name = 2;
Deck.Filtered config = 3;
bool allow_empty = 4;
}

View File

@ -79,6 +79,8 @@ class FilteredDeckConfigDialog(QDialog):
self.form.order.addItems(order_labels)
self.form.order_2.addItems(order_labels)
qconnect(self.form.allow_empty.stateChanged, self._on_allow_empty_toggled)
qconnect(self.form.resched.stateChanged, self._onReschedToggled)
qconnect(self.form.search_button.clicked, self.on_search_button)
@ -233,6 +235,9 @@ class FilteredDeckConfigDialog(QDialog):
def _onReschedToggled(self, _state: int) -> None:
self.form.previewDelayWidget.setVisible(not self.form.resched.isChecked())
def _on_allow_empty_toggled(self) -> None:
self.deck.allow_empty = self.form.allow_empty.isChecked()
def _update_deck(self) -> bool:
"""Update our stored deck with the details from the GUI.
If false, abort adding."""

View File

@ -255,6 +255,13 @@
</property>
</widget>
</item>
<item row="5" column="0" alignment="Qt::AlignLeft">
<widget class="QCheckBox" name="allow_empty">
<property name="text">
<string>decks_create_even_if_empty</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -251,6 +251,7 @@ impl From<FilteredDeckForUpdate> for anki_proto::decks::FilteredDeckForUpdate {
id: deck.id.into(),
name: deck.human_name,
config: Some(deck.config),
allow_empty: deck.allow_empty,
}
}
}
@ -261,6 +262,7 @@ impl From<anki_proto::decks::FilteredDeckForUpdate> for FilteredDeckForUpdate {
id: deck.id.into(),
human_name: deck.name,
config: deck.config.unwrap_or_default(),
allow_empty: deck.allow_empty,
}
}
}

View File

@ -184,6 +184,7 @@ impl Collection {
id,
human_name,
config,
allow_empty: false,
};
self.add_or_update_filtered_deck_inner(deck)

View File

@ -21,6 +21,7 @@ pub struct FilteredDeckForUpdate {
pub id: DeckId,
pub human_name: String,
pub config: FilteredDeck,
pub allow_empty: bool,
}
pub(crate) struct DeckFilterContext<'a> {
@ -144,6 +145,7 @@ impl Collection {
mut update: FilteredDeckForUpdate,
) -> Result<DeckId> {
let usn = self.usn()?;
let allow_empty = update.allow_empty;
// check the searches are valid, and normalize them
for term in &mut update.config.search_terms {
@ -167,7 +169,7 @@ impl Collection {
let count = self.rebuild_filtered_deck_inner(&deck, usn)?;
// if it failed to match any cards, we revert the changes
if count == 0 {
if count == 0 && !allow_empty {
Err(FilteredDeckError::SearchReturnedNoCards.into())
} else {
// update current deck and return id
@ -233,6 +235,7 @@ impl TryFrom<Deck> for FilteredDeckForUpdate {
id: value.id,
human_name,
config: filtered,
allow_empty: false,
}),
_ => invalid_input!("not filtered"),
}