Merge pull request #1104 from RumovZ/column-enum
Column enum for backend
This commit is contained in:
commit
42942a521e
@ -681,7 +681,7 @@ class Collection:
|
||||
else:
|
||||
return SearchNode.Group.Joiner.OR
|
||||
|
||||
# Browser rows
|
||||
# Browser Table
|
||||
##########################################################################
|
||||
|
||||
def browser_row_for_id(
|
||||
@ -695,6 +695,30 @@ class Collection:
|
||||
row.font_size,
|
||||
)
|
||||
|
||||
def load_browser_card_columns(self) -> List[str]:
|
||||
"""Return the stored card column names and ensure the backend columns are set and in sync."""
|
||||
columns = self.get_config(
|
||||
"activeCols", ["noteFld", "template", "cardDue", "deck"]
|
||||
)
|
||||
self._backend.set_desktop_browser_card_columns(columns)
|
||||
return columns
|
||||
|
||||
def set_browser_card_columns(self, columns: List[str]) -> None:
|
||||
self.set_config("activeCols", columns)
|
||||
self._backend.set_desktop_browser_card_columns(columns)
|
||||
|
||||
def load_browser_note_columns(self) -> List[str]:
|
||||
"""Return the stored note column names and ensure the backend columns are set and in sync."""
|
||||
columns = self.get_config(
|
||||
"activeNoteCols", ["noteFld", "note", "noteCards", "noteTags"]
|
||||
)
|
||||
self._backend.set_desktop_browser_note_columns(columns)
|
||||
return columns
|
||||
|
||||
def set_browser_note_columns(self, columns: List[str]) -> None:
|
||||
self.set_config("activeNoteCols", columns)
|
||||
self._backend.set_desktop_browser_note_columns(columns)
|
||||
|
||||
# Config
|
||||
##########################################################################
|
||||
|
||||
|
@ -618,7 +618,7 @@ class CardState(ItemState):
|
||||
def __init__(self, col: Collection) -> None:
|
||||
super().__init__(col)
|
||||
self._load_columns()
|
||||
self._load_active_columns()
|
||||
self._active_columns = self.col.load_browser_card_columns()
|
||||
self._sort_column = self.col.get_config("sortType")
|
||||
self._sort_backwards = self.col.get_config_bool(
|
||||
Config.Bool.BROWSER_SORT_BACKWARDS
|
||||
@ -644,11 +644,6 @@ class CardState(ItemState):
|
||||
]
|
||||
self._columns.sort(key=itemgetter(1))
|
||||
|
||||
def _load_active_columns(self) -> None:
|
||||
self._active_columns = self.col.get_config(
|
||||
"activeCols", ["noteFld", "template", "cardDue", "deck"]
|
||||
)
|
||||
|
||||
@property
|
||||
def columns(self) -> List[Tuple[str, str]]:
|
||||
return self._columns
|
||||
@ -662,7 +657,7 @@ class CardState(ItemState):
|
||||
self._active_columns.remove(column)
|
||||
else:
|
||||
self._active_columns.append(column)
|
||||
self.col.set_config("activeCols", self._active_columns)
|
||||
self.col.set_browser_card_columns(self._active_columns)
|
||||
|
||||
@property
|
||||
def sort_column(self) -> str:
|
||||
@ -711,7 +706,7 @@ class NoteState(ItemState):
|
||||
def __init__(self, col: Collection) -> None:
|
||||
super().__init__(col)
|
||||
self._load_columns()
|
||||
self._load_active_columns()
|
||||
self._active_columns = self.col.load_browser_note_columns()
|
||||
self._sort_column = self.col.get_config("noteSortType")
|
||||
self._sort_backwards = self.col.get_config_bool(
|
||||
Config.Bool.BROWSER_NOTE_SORT_BACKWARDS
|
||||
@ -731,11 +726,6 @@ class NoteState(ItemState):
|
||||
]
|
||||
self._columns.sort(key=itemgetter(1))
|
||||
|
||||
def _load_active_columns(self) -> None:
|
||||
self._active_columns = self.col.get_config(
|
||||
"activeNoteCols", ["noteFld", "note", "noteTags", "noteMod"]
|
||||
)
|
||||
|
||||
@property
|
||||
def columns(self) -> List[Tuple[str, str]]:
|
||||
return self._columns
|
||||
@ -749,7 +739,7 @@ class NoteState(ItemState):
|
||||
self._active_columns.remove(column)
|
||||
else:
|
||||
self._active_columns.append(column)
|
||||
self.col.set_config("activeNoteCols", self._active_columns)
|
||||
self.col.set_browser_note_columns(self._active_columns)
|
||||
|
||||
@property
|
||||
def sort_column(self) -> str:
|
||||
|
@ -243,6 +243,8 @@ service SearchService {
|
||||
rpc ReplaceSearchNode(ReplaceSearchNodeIn) returns (String);
|
||||
rpc FindAndReplace(FindAndReplaceIn) returns (OpChangesWithCount);
|
||||
rpc BrowserRowForId(Int64) returns (BrowserRow);
|
||||
rpc SetDesktopBrowserCardColumns(StringList) returns (Empty);
|
||||
rpc SetDesktopBrowserNoteColumns(StringList) returns (Empty);
|
||||
}
|
||||
|
||||
service StatsService {
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::{backend_proto as pb, browser_rows};
|
||||
|
||||
impl From<browser_rows::Row> for pb::BrowserRow {
|
||||
fn from(row: browser_rows::Row) -> Self {
|
||||
pb::BrowserRow {
|
||||
cells: row.cells.into_iter().map(Into::into).collect(),
|
||||
color: row.color.into(),
|
||||
font_name: row.font.name,
|
||||
font_size: row.font.size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<browser_rows::Cell> for pb::browser_row::Cell {
|
||||
fn from(cell: browser_rows::Cell) -> Self {
|
||||
pb::browser_row::Cell {
|
||||
text: cell.text,
|
||||
is_rtl: cell.is_rtl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<browser_rows::Color> for i32 {
|
||||
fn from(color: browser_rows::Color) -> Self {
|
||||
match color {
|
||||
browser_rows::Color::Default => pb::browser_row::Color::Default as i32,
|
||||
browser_rows::Color::Marked => pb::browser_row::Color::Marked as i32,
|
||||
browser_rows::Color::Suspended => pb::browser_row::Color::Suspended as i32,
|
||||
browser_rows::Color::FlagRed => pb::browser_row::Color::FlagRed as i32,
|
||||
browser_rows::Color::FlagOrange => pb::browser_row::Color::FlagOrange as i32,
|
||||
browser_rows::Color::FlagGreen => pb::browser_row::Color::FlagGreen as i32,
|
||||
browser_rows::Color::FlagBlue => pb::browser_row::Color::FlagBlue as i32,
|
||||
}
|
||||
}
|
||||
}
|
71
rslib/src/backend/search/browser_table.rs
Normal file
71
rslib/src/backend/search/browser_table.rs
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::{backend_proto as pb, browser_table};
|
||||
|
||||
impl From<pb::StringList> for Vec<browser_table::Column> {
|
||||
fn from(input: pb::StringList) -> Self {
|
||||
input.vals.into_iter().map(Into::into).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for browser_table::Column {
|
||||
fn from(text: String) -> Self {
|
||||
match text.as_str() {
|
||||
"question" => browser_table::Column::Question,
|
||||
"answer" => browser_table::Column::Answer,
|
||||
"deck" => browser_table::Column::CardDeck,
|
||||
"cardDue" => browser_table::Column::CardDue,
|
||||
"cardEase" => browser_table::Column::CardEase,
|
||||
"cardLapses" => browser_table::Column::CardLapses,
|
||||
"cardIvl" => browser_table::Column::CardInterval,
|
||||
"cardMod" => browser_table::Column::CardMod,
|
||||
"cardReps" => browser_table::Column::CardReps,
|
||||
"template" => browser_table::Column::CardTemplate,
|
||||
"noteCards" => browser_table::Column::NoteCards,
|
||||
"noteCrt" => browser_table::Column::NoteCreation,
|
||||
"noteEase" => browser_table::Column::NoteEase,
|
||||
"noteFld" => browser_table::Column::NoteField,
|
||||
"noteLapses" => browser_table::Column::NoteLapses,
|
||||
"noteMod" => browser_table::Column::NoteMod,
|
||||
"noteReps" => browser_table::Column::NoteReps,
|
||||
"noteTags" => browser_table::Column::NoteTags,
|
||||
"note" => browser_table::Column::Notetype,
|
||||
_ => browser_table::Column::Custom,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<browser_table::Row> for pb::BrowserRow {
|
||||
fn from(row: browser_table::Row) -> Self {
|
||||
pb::BrowserRow {
|
||||
cells: row.cells.into_iter().map(Into::into).collect(),
|
||||
color: row.color.into(),
|
||||
font_name: row.font.name,
|
||||
font_size: row.font.size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<browser_table::Cell> for pb::browser_row::Cell {
|
||||
fn from(cell: browser_table::Cell) -> Self {
|
||||
pb::browser_row::Cell {
|
||||
text: cell.text,
|
||||
is_rtl: cell.is_rtl,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<browser_table::Color> for i32 {
|
||||
fn from(color: browser_table::Color) -> Self {
|
||||
match color {
|
||||
browser_table::Color::Default => pb::browser_row::Color::Default as i32,
|
||||
browser_table::Color::Marked => pb::browser_row::Color::Marked as i32,
|
||||
browser_table::Color::Suspended => pb::browser_row::Color::Suspended as i32,
|
||||
browser_table::Color::FlagRed => pb::browser_row::Color::FlagRed as i32,
|
||||
browser_table::Color::FlagOrange => pb::browser_row::Color::FlagOrange as i32,
|
||||
browser_table::Color::FlagGreen => pb::browser_row::Color::FlagGreen as i32,
|
||||
browser_table::Color::FlagBlue => pb::browser_row::Color::FlagBlue as i32,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
mod browser_row;
|
||||
mod browser_table;
|
||||
mod search_node;
|
||||
|
||||
use std::convert::TryInto;
|
||||
@ -92,6 +92,16 @@ impl SearchService for Backend {
|
||||
fn browser_row_for_id(&self, input: pb::Int64) -> Result<pb::BrowserRow> {
|
||||
self.with_col(|col| col.browser_row_for_id(input.val).map(Into::into))
|
||||
}
|
||||
|
||||
fn set_desktop_browser_card_columns(&self, input: pb::StringList) -> Result<pb::Empty> {
|
||||
self.with_col(|col| col.set_desktop_browser_card_columns(input.into()))?;
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
fn set_desktop_browser_note_columns(&self, input: pb::StringList) -> Result<pb::Empty> {
|
||||
self.with_col(|col| col.set_desktop_browser_note_columns(input.into()))?;
|
||||
Ok(().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SortKindProto> for SortKind {
|
||||
|
@ -4,6 +4,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
use crate::err::{AnkiError, Result};
|
||||
use crate::i18n::I18n;
|
||||
@ -20,7 +21,30 @@ use crate::{
|
||||
timestamp::{TimestampMillis, TimestampSecs},
|
||||
};
|
||||
|
||||
const CARD_RENDER_COLUMNS: [&str; 2] = ["question", "answer"];
|
||||
#[derive(Serialize_repr, Deserialize_repr, Debug, PartialEq, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum Column {
|
||||
Custom = 0,
|
||||
Question = 1,
|
||||
Answer = 2,
|
||||
CardDeck = 3,
|
||||
CardDue = 4,
|
||||
CardEase = 5,
|
||||
CardLapses = 6,
|
||||
CardInterval = 7,
|
||||
CardMod = 8,
|
||||
CardReps = 9,
|
||||
CardTemplate = 10,
|
||||
NoteCards = 11,
|
||||
NoteCreation = 12,
|
||||
NoteEase = 13,
|
||||
NoteField = 14,
|
||||
NoteLapses = 15,
|
||||
NoteMod = 16,
|
||||
NoteReps = 17,
|
||||
NoteTags = 18,
|
||||
Notetype = 19,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Row {
|
||||
@ -53,13 +77,13 @@ pub struct Font {
|
||||
}
|
||||
|
||||
trait RowContext {
|
||||
fn get_cell_text(&mut self, column: &str) -> Result<String>;
|
||||
fn get_cell_text(&mut self, column: &Column) -> Result<String>;
|
||||
fn get_row_color(&self) -> Color;
|
||||
fn get_row_font(&self) -> Result<Font>;
|
||||
fn note(&self) -> &Note;
|
||||
fn notetype(&self) -> &Notetype;
|
||||
|
||||
fn get_cell(&mut self, column: &str) -> Result<Cell> {
|
||||
fn get_cell(&mut self, column: &Column) -> Result<Cell> {
|
||||
Ok(Cell {
|
||||
text: self.get_cell_text(column)?,
|
||||
is_rtl: self.get_is_rtl(column),
|
||||
@ -77,9 +101,9 @@ trait RowContext {
|
||||
html_to_text_line(&self.note().fields()[index]).into()
|
||||
}
|
||||
|
||||
fn get_is_rtl(&self, column: &str) -> bool {
|
||||
fn get_is_rtl(&self, column: &Column) -> bool {
|
||||
match column {
|
||||
"noteFld" => {
|
||||
Column::NoteField => {
|
||||
let index = self.notetype().config.sort_field_idx as usize;
|
||||
self.notetype().fields[index].config.rtl
|
||||
}
|
||||
@ -87,7 +111,7 @@ trait RowContext {
|
||||
}
|
||||
}
|
||||
|
||||
fn browser_row_for_id(&mut self, columns: &[String]) -> Result<Row> {
|
||||
fn browser_row_for_id(&mut self, columns: &[Column]) -> Result<Row> {
|
||||
Ok(Row {
|
||||
cells: columns
|
||||
.iter()
|
||||
@ -125,20 +149,27 @@ struct NoteRowContext<'a> {
|
||||
tr: &'a I18n,
|
||||
}
|
||||
|
||||
fn card_render_required(columns: &[String]) -> bool {
|
||||
fn card_render_required(columns: &[Column]) -> bool {
|
||||
columns
|
||||
.iter()
|
||||
.any(|c| CARD_RENDER_COLUMNS.contains(&c.as_str()))
|
||||
.any(|c| matches!(c, Column::Question | Column::Answer))
|
||||
}
|
||||
|
||||
impl Collection {
|
||||
pub fn browser_row_for_id(&mut self, id: i64) -> Result<Row> {
|
||||
if self.get_bool(BoolKey::BrowserTableShowNotesMode) {
|
||||
let columns = self.get_desktop_browser_note_columns();
|
||||
let columns =
|
||||
self.get_desktop_browser_note_columns()
|
||||
.ok_or(AnkiError::InvalidInput {
|
||||
info: "Note columns not set.".into(),
|
||||
})?;
|
||||
NoteRowContext::new(self, id)?.browser_row_for_id(&columns)
|
||||
} else {
|
||||
// this is inefficient; we may want to use an enum in the future
|
||||
let columns = self.get_desktop_browser_card_columns();
|
||||
let columns =
|
||||
self.get_desktop_browser_card_columns()
|
||||
.ok_or(AnkiError::InvalidInput {
|
||||
info: "Card columns not set.".into(),
|
||||
})?;
|
||||
CardRowContext::new(self, id, card_render_required(&columns))?
|
||||
.browser_row_for_id(&columns)
|
||||
}
|
||||
@ -329,23 +360,23 @@ impl<'a> CardRowContext<'a> {
|
||||
}
|
||||
|
||||
impl RowContext for CardRowContext<'_> {
|
||||
fn get_cell_text(&mut self, column: &str) -> Result<String> {
|
||||
fn get_cell_text(&mut self, column: &Column) -> Result<String> {
|
||||
Ok(match column {
|
||||
"answer" => self.answer_str(),
|
||||
"cardDue" => self.card_due_str(),
|
||||
"cardEase" => self.card_ease_str(),
|
||||
"cardIvl" => self.card_interval_str(),
|
||||
"cardLapses" => self.card.lapses.to_string(),
|
||||
"cardMod" => self.card.mtime.date_string(),
|
||||
"cardReps" => self.card.reps.to_string(),
|
||||
"deck" => self.deck_str()?,
|
||||
"note" => self.notetype.name.to_owned(),
|
||||
"noteCrt" => self.note_creation_str(),
|
||||
"noteFld" => self.note_field_str(),
|
||||
"noteMod" => self.note.mtime.date_string(),
|
||||
"noteTags" => self.note.tags.join(" "),
|
||||
"question" => self.question_str(),
|
||||
"template" => self.template_str()?,
|
||||
Column::Question => self.question_str(),
|
||||
Column::Answer => self.answer_str(),
|
||||
Column::CardDeck => self.deck_str()?,
|
||||
Column::CardDue => self.card_due_str(),
|
||||
Column::CardEase => self.card_ease_str(),
|
||||
Column::CardInterval => self.card_interval_str(),
|
||||
Column::CardLapses => self.card.lapses.to_string(),
|
||||
Column::CardMod => self.card.mtime.date_string(),
|
||||
Column::CardReps => self.card.reps.to_string(),
|
||||
Column::CardTemplate => self.template_str()?,
|
||||
Column::NoteCreation => self.note_creation_str(),
|
||||
Column::NoteField => self.note_field_str(),
|
||||
Column::NoteMod => self.note.mtime.date_string(),
|
||||
Column::NoteTags => self.note.tags.join(" "),
|
||||
Column::Notetype => self.notetype.name.to_owned(),
|
||||
_ => "".to_string(),
|
||||
})
|
||||
}
|
||||
@ -421,17 +452,17 @@ impl<'a> NoteRowContext<'a> {
|
||||
}
|
||||
|
||||
impl RowContext for NoteRowContext<'_> {
|
||||
fn get_cell_text(&mut self, column: &str) -> Result<String> {
|
||||
fn get_cell_text(&mut self, column: &Column) -> Result<String> {
|
||||
Ok(match column {
|
||||
"note" => self.notetype.name.to_owned(),
|
||||
"noteCards" => self.cards.len().to_string(),
|
||||
"noteCrt" => self.note_creation_str(),
|
||||
"noteEase" => self.note_ease_str(),
|
||||
"noteFld" => self.note_field_str(),
|
||||
"noteLapses" => self.cards.iter().map(|c| c.lapses).sum::<u32>().to_string(),
|
||||
"noteMod" => self.note.mtime.date_string(),
|
||||
"noteReps" => self.cards.iter().map(|c| c.reps).sum::<u32>().to_string(),
|
||||
"noteTags" => self.note.tags.join(" "),
|
||||
Column::NoteCards => self.cards.len().to_string(),
|
||||
Column::NoteCreation => self.note_creation_str(),
|
||||
Column::NoteEase => self.note_ease_str(),
|
||||
Column::NoteField => self.note_field_str(),
|
||||
Column::NoteLapses => self.cards.iter().map(|c| c.lapses).sum::<u32>().to_string(),
|
||||
Column::NoteMod => self.note.mtime.date_string(),
|
||||
Column::NoteReps => self.cards.iter().map(|c| c.reps).sum::<u32>().to_string(),
|
||||
Column::NoteTags => self.note.tags.join(" "),
|
||||
Column::Notetype => self.notetype.name.to_owned(),
|
||||
_ => "".to_string(),
|
||||
})
|
||||
}
|
@ -9,6 +9,7 @@ mod string;
|
||||
pub(crate) mod undo;
|
||||
|
||||
pub use self::{bool::BoolKey, string::StringKey};
|
||||
use crate::browser_table;
|
||||
use crate::prelude::*;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use serde_derive::Deserialize;
|
||||
@ -65,9 +66,7 @@ pub(crate) enum ConfigKey {
|
||||
#[strum(to_string = "schedVer")]
|
||||
SchedulerVersion,
|
||||
|
||||
#[strum(to_string = "activeCols")]
|
||||
DesktopBrowserCardColumns,
|
||||
#[strum(to_string = "activeNoteCols")]
|
||||
DesktopBrowserNoteColumns,
|
||||
}
|
||||
|
||||
@ -140,28 +139,26 @@ impl Collection {
|
||||
self.get_config_default(ConfigKey::BrowserNoteSortKind)
|
||||
}
|
||||
|
||||
pub(crate) fn get_desktop_browser_card_columns(&self) -> Vec<String> {
|
||||
pub(crate) fn get_desktop_browser_card_columns(&self) -> Option<Vec<browser_table::Column>> {
|
||||
self.get_config_optional(ConfigKey::DesktopBrowserCardColumns)
|
||||
.unwrap_or_else(|| {
|
||||
vec![
|
||||
"noteFld".to_string(),
|
||||
"template".to_string(),
|
||||
"cardDue".to_string(),
|
||||
"deck".to_string(),
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_desktop_browser_note_columns(&self) -> Vec<String> {
|
||||
pub(crate) fn set_desktop_browser_card_columns(
|
||||
&mut self,
|
||||
columns: Vec<browser_table::Column>,
|
||||
) -> Result<()> {
|
||||
self.set_config(ConfigKey::DesktopBrowserCardColumns, &columns)
|
||||
}
|
||||
|
||||
pub(crate) fn get_desktop_browser_note_columns(&self) -> Option<Vec<browser_table::Column>> {
|
||||
self.get_config_optional(ConfigKey::DesktopBrowserNoteColumns)
|
||||
.unwrap_or_else(|| {
|
||||
vec![
|
||||
"noteFld".to_string(),
|
||||
"note".to_string(),
|
||||
"noteTags".to_string(),
|
||||
"noteMod".to_string(),
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_desktop_browser_note_columns(
|
||||
&mut self,
|
||||
columns: Vec<browser_table::Column>,
|
||||
) -> Result<()> {
|
||||
self.set_config(ConfigKey::DesktopBrowserNoteColumns, &columns)
|
||||
}
|
||||
|
||||
pub(crate) fn get_creation_utc_offset(&self) -> Option<i32> {
|
||||
|
@ -6,7 +6,7 @@
|
||||
pub mod adding;
|
||||
pub mod backend;
|
||||
mod backend_proto;
|
||||
pub mod browser_rows;
|
||||
pub mod browser_table;
|
||||
pub mod card;
|
||||
pub mod cloze;
|
||||
pub mod collection;
|
||||
|
Loading…
Reference in New Issue
Block a user