This commit is contained in:
parent
9acb29e418
commit
28804d55d7
|
|
@ -19,7 +19,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Simplified Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "8444a3bd135d61feb6c5b559a9eb0babb50de2ebbd1d86b1e87ccb064e2d3f0b"
|
||||
sha256 = "6bed3ae5e307b0a225c49bb6a4c688911869f4bbf5df527a3bf84d0997e6baaf"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/zh-hant.tsv"
|
||||
|
|
@ -30,7 +30,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Traditional Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "8771d80405b8fba9da4a909fdd97b760f6b25a822807ca83ff20dc5cec83a73c"
|
||||
sha256 = "42c3498eac138f95ac700f71332742658ed59bec171460aa675b1cb67e97ca36"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/cs.tsv"
|
||||
|
|
@ -41,7 +41,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "bf1ab8079af725264f9c4298b9737359ba831170dcba76a6bd39228239c87e83"
|
||||
sha256 = "fb315c0c3dfbafd35d73e7dedd1260daa1da919b0b30db53d16725cbd0f0ae12"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/pt-br.tsv"
|
||||
|
|
@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "b23b03cf4ac163e7a63e49a0900a125507c05ad4fc7930468b859acf32b09ecd"
|
||||
sha256 = "20043dd4e64d6a8405dbf3167e9f315f68d4894c3d76c0b2b68e9c7e2879c06f"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/es.tsv"
|
||||
|
|
@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Spanish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "1b3371f239ca89a658e2c9b80cc070be5cd941dd1ecd3e7a247696716f25721d"
|
||||
sha256 = "4c576bf5573a127ba2565980623e92b104699e7e03ac68dc3eddf4e788c7e8a4"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/fr.tsv"
|
||||
|
|
@ -74,7 +74,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "French UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "dbf725ffc9177a435e894f4405834e87c70b6fe31a34f1be533c60c356510b97"
|
||||
sha256 = "66ea8fd85159745626643bfce304dbe7ae0f9ae45a006a5d3834c3cad181080b"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/de.tsv"
|
||||
|
|
@ -85,7 +85,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "German UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "3827d04146f65a02e9d5e69336a97efc46862a48b18a16acbbc023ee0c8b7e1b"
|
||||
sha256 = "4ba9f2bfc1cca7e819dde79d09c3b128b19a289faf7caa32f6925791683e9538"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/te.tsv"
|
||||
|
|
@ -96,7 +96,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Telugu UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "f7a5ab0bcbdb8641b1bd4ae25db54ef187757dde3e4fe372e433a9e5c0fc4f3a"
|
||||
sha256 = "2c399d16589f2d0c3659c87406cb45d27792e7286774ededaa6578a224e2fae9"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/ru.tsv"
|
||||
|
|
@ -107,7 +107,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Russian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "259f795a3cdc032aa670693d2ebff010c5dd3bcf57dda11548d5bd46e78969b8"
|
||||
sha256 = "1782bfb95566a44e9cc3e22a595ff158965c55b67936d994a8dae9b3e51975a2"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/bg.tsv"
|
||||
|
|
@ -118,7 +118,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Bulgarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "e71f683e410618200c0abe66a362a720cb8ded5bfd155bf825f92644373c54b5"
|
||||
sha256 = "eb0b3fa525198152d7cf514284460ff904bcb9af091142ddd1c09deb8461ed69"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/ja.tsv"
|
||||
|
|
@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0"
|
|||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Japanese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "cdcdba828efea9d402cb9ce8be2b52ab1d58c8f7837d75d3b9c86f2a05e7fb2e"
|
||||
sha256 = "2bfcb94d72df43a6146e45e971950433a13bb008fc18c68463c096089f715466"
|
||||
|
||||
[[asset]]
|
||||
path = "assets/icons/accessibility.svg"
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ const HELP: Option<&str> = Some("Help");
|
|||
pub const COMMANDS: &[CommandSpec] = &[
|
||||
c("file.open", "Open…", FILE, Some(Shortcut::cmd("O")), Nothing, "folder-open"),
|
||||
c("file.open_recent", "Open Recent", FILE, None, Nothing, "clock"),
|
||||
// Shown at the foot of File ▸ Open Recent and on Home, not as its own File menu item.
|
||||
c("file.clear_recent", "Clear Recent Files", None, None, Nothing, "trash-2"),
|
||||
c("file.pin_folder", "Pin folder to Home…", FILE, None, Nothing, "folder-plus"),
|
||||
c("create.blank", "New blank PDF", FILE, None, Nothing, "file-plus-2"),
|
||||
c("measure.distance", "Measure distance", None, None, Annotate, "ruler"),
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ impl PdfCraftApp {
|
|||
Some(p) => self.open_recent(&p),
|
||||
None => self.notify_tr("No recent files"),
|
||||
},
|
||||
"file.clear_recent" if self.recent.is_empty() => self.notify_tr("No recent files"),
|
||||
"file.clear_recent" => self.recent.clear(),
|
||||
"file.pin_folder" => self.pin_folder_dialog(),
|
||||
"page.combine" => self.open_combine_tab(),
|
||||
"file.save" => {
|
||||
|
|
@ -570,13 +572,15 @@ pub(crate) fn registry_menu(app: &mut PdfCraftApp, ui: &mut egui::Ui, menu: &str
|
|||
let label = commands::current_label(spec, &app.session, app.active_ids().map(|(_, id)| id));
|
||||
let label = crate::i18n::menu_label(spec.id, &label);
|
||||
// Open Recent is a submenu of the live recent list, not one action: disabled while the
|
||||
// list is empty, otherwise each entry opens its file (or focuses the tab showing it).
|
||||
// list is empty, otherwise each entry opens its file (or focuses the tab showing it), and
|
||||
// Clear Recent Files at the foot empties the list (#430).
|
||||
if spec.id == "file.open_recent" {
|
||||
if app.recent.is_empty() {
|
||||
ui.add_enabled(false, egui::Button::new(label));
|
||||
continue;
|
||||
}
|
||||
let mut open: Option<String> = None;
|
||||
let mut clear = false;
|
||||
ui.menu_button(label, |ui| {
|
||||
for r in &app.recent {
|
||||
if ui.button(&r.name).on_hover_text(&r.path).clicked() {
|
||||
|
|
@ -584,11 +588,20 @@ pub(crate) fn registry_menu(app: &mut PdfCraftApp, ui: &mut egui::Ui, menu: &str
|
|||
ui.close();
|
||||
}
|
||||
}
|
||||
ui.separator();
|
||||
if ui.button(tl!("Clear Recent Files")).clicked() {
|
||||
clear = true;
|
||||
ui.close();
|
||||
}
|
||||
});
|
||||
if let Some(p) = open {
|
||||
app.open_recent(&p);
|
||||
ui.close();
|
||||
}
|
||||
if clear {
|
||||
app.execute("file.clear_recent");
|
||||
ui.close();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let shortcut = spec.shortcut.map(|s| s.label(mac)).unwrap_or_default();
|
||||
|
|
|
|||
|
|
@ -104,17 +104,42 @@ pub fn show(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
|
|||
}
|
||||
|
||||
ui.add_space(26.0);
|
||||
ui.label(egui::RichText::new(tl!("Recent")).font(theme::semibold(17.0)));
|
||||
let mut clear = false;
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(egui::RichText::new(tl!("Recent")).font(theme::semibold(17.0)));
|
||||
if !app.recent.is_empty() {
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
let resp = widgets::ghost_button(ui, "trash-2", tl!("Clear"));
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, true, tl!("Clear Recent Files")));
|
||||
clear = resp.on_hover_text(tl!("Clear Recent Files")).clicked();
|
||||
});
|
||||
}
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
if app.recent.is_empty() {
|
||||
ui.label(egui::RichText::new(tl!("Files you open in PdfCraft appear here. Drop a PDF anywhere to open it.")).color(t.text_muted));
|
||||
}
|
||||
let mut open = None;
|
||||
let mut remove = None;
|
||||
for r in &app.recent {
|
||||
let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), 46.0), Sense::click());
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, true, &r.name));
|
||||
if resp.hovered() {
|
||||
// The row, not its response: the pointer stays "in" the row over its remove button.
|
||||
let hovered = ui.rect_contains_pointer(rect);
|
||||
if hovered {
|
||||
ui.painter().rect_filled(rect, CornerRadius::same(8), t.hover);
|
||||
// Remove just this file from the list (#430); the file itself is untouched.
|
||||
let x_rect = Rect::from_center_size(rect.right_center() - vec2(26.0, 0.0), vec2(28.0, 28.0));
|
||||
let x = ui.interact(x_rect, ui.id().with(("remove-recent", &r.path)), Sense::click());
|
||||
let label = crate::i18n::fmt(tl!("Remove {name} from Recent"), &[("name", &r.name)]);
|
||||
x.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, true, &label));
|
||||
if x.hovered() {
|
||||
ui.painter().rect_filled(x_rect, CornerRadius::same(6), t.pressed);
|
||||
}
|
||||
icons::paint(ui, x_rect.shrink(6.0), "x", 16.0, t.icon);
|
||||
if x.on_hover_text(tl!("Remove from Recent")).clicked() {
|
||||
remove = Some(r.path.clone());
|
||||
}
|
||||
}
|
||||
icons::paint(
|
||||
ui,
|
||||
|
|
@ -123,8 +148,9 @@ pub fn show(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
|
|||
22.0,
|
||||
egui::Color32::from_rgb(0xE0, 0x3E, 0x3E),
|
||||
);
|
||||
// Room on the right for the remove button.
|
||||
let detail = ui.painter().text(
|
||||
rect.right_center() - vec2(12.0, 0.0),
|
||||
rect.right_center() - vec2(48.0, 0.0),
|
||||
Align2::RIGHT_CENTER,
|
||||
format!("{} {} · {}", r.pages, tl!("pages"), human_size(r.size)),
|
||||
theme::regular(12.0),
|
||||
|
|
@ -141,6 +167,12 @@ pub fn show(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
|
|||
if let Some(p) = open {
|
||||
app.open_recent(&p);
|
||||
}
|
||||
if let Some(p) = remove {
|
||||
app.recent.retain(|r| r.path != p);
|
||||
}
|
||||
if clear {
|
||||
app.execute("file.clear_recent");
|
||||
}
|
||||
ui.add_space(20.0);
|
||||
widgets::section_title(ui, tl!("Privacy"));
|
||||
ui.label(
|
||||
|
|
|
|||
|
|
@ -2043,3 +2043,6 @@ signature pad Type Въвеждане
|
|||
action wizard Start Старт
|
||||
Margins (in) Полета (in)
|
||||
Reopen the files that were open when PdfCraft last closed Отваряй отново файловете, които бяха отворени при последното затваряне на PdfCraft
|
||||
Clear Recent Files Изчисти последно отваряните файлове
|
||||
Remove from Recent Премахни от последно отваряните
|
||||
Remove {name} from Recent Премахни {name} от последно отваряните
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 8 and column 16.
|
|
|
@ -29,6 +29,10 @@
|
|||
OK OK
|
||||
Open… Otevřít…
|
||||
Open Recent Otevřít nedávné soubory
|
||||
Clear Recent Files Vymazat nedávné soubory
|
||||
Remove from Recent Odebrat z nedávných souborů
|
||||
Remove {name} from Recent Odebrat {name} z nedávných souborů
|
||||
Clear Vymazat
|
||||
Pin folder to Home… Připnout složku na úvodní stránku…
|
||||
No recent files Žádné nedávné soubory
|
||||
New blank PDF Nový prázdný dokument PDF
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 7 and column 81.
|
|
|
@ -2045,3 +2045,6 @@ comment menu Edit Bearbeiten
|
|||
signature pad Type Tippen
|
||||
action wizard Start Starten
|
||||
Reopen the files that were open when PdfCraft last closed Beim Start die Dateien wieder öffnen, die beim letzten Beenden von PdfCraft geöffnet waren
|
||||
Clear Recent Files Liste „Zuletzt geöffnet“ leeren
|
||||
Remove from Recent Aus „Zuletzt geöffnet“ entfernen
|
||||
Remove {name} from Recent {name} aus „Zuletzt geöffnet“ entfernen
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 51.
|
|
|
@ -22,6 +22,9 @@
|
|||
Name on new comments Nombre en los comentarios nuevos
|
||||
Open… Abrir…
|
||||
Open Recent Abrir recientes
|
||||
Clear Recent Files Borrar archivos recientes
|
||||
Remove from Recent Quitar de recientes
|
||||
Remove {name} from Recent Quitar {name} de recientes
|
||||
Pin folder to Home… Anclar carpeta en Inicio…
|
||||
Folders Carpetas
|
||||
Pin a folder… Anclar una carpeta…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 60.
|
|
|
@ -2014,6 +2014,9 @@
|
|||
Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Choisissez une image PNG ou JPEG (jusqu’à 4 Mio). La transparence est conservée.
|
||||
Couldn't import the signature image: {e} Impossible d’importer l’image de la signature : {e}
|
||||
Open Recent Ouvrir un fichier récent
|
||||
Clear Recent Files Effacer les fichiers récents
|
||||
Remove from Recent Retirer des fichiers récents
|
||||
Remove {name} from Recent Retirer {name} des fichiers récents
|
||||
Pin folder to Home… Épingler un dossier à l'Accueil…
|
||||
Folders Dossiers
|
||||
Pin a folder… Épingler un dossier…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 39.
|
|
|
@ -28,6 +28,9 @@
|
|||
Name on new comments 新しい注釈の作成者名
|
||||
Open… 開く…
|
||||
Open Recent 最近のファイルを開く
|
||||
Clear Recent Files 最近のファイルをクリア
|
||||
Remove from Recent 最近のファイルから外す
|
||||
Remove {name} from Recent {name} を最近のファイルから外す
|
||||
Pin folder to Home… フォルダーをホームにピン留め…
|
||||
Folders フォルダー
|
||||
Pin a folder… フォルダーをピン留め…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -21,6 +21,10 @@
|
|||
Name on new comments Nome nos novos comentários
|
||||
Open… Abrir…
|
||||
Open Recent Abrir recentes
|
||||
Clear Recent Files Limpar arquivos recentes
|
||||
Remove from Recent Remover dos recentes
|
||||
Remove {name} from Recent Remover {name} dos recentes
|
||||
Clear Limpar
|
||||
Pin folder to Home… Fixar pasta no Início…
|
||||
No recent files Nenhum arquivo recente
|
||||
New blank PDF Novo PDF em branco
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
|
|
@ -21,6 +21,9 @@
|
|||
Name on new comments Имя в новых комментариях
|
||||
Open… Открыть…
|
||||
Open Recent Открыть недавние
|
||||
Clear Recent Files Очистить недавние файлы
|
||||
Remove from Recent Убрать из недавних
|
||||
Remove {name} from Recent Убрать {name} из недавних
|
||||
Pin folder to Home… Закрепить папку на главной…
|
||||
Folders Папки
|
||||
Pin a folder… Закрепить папку…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
|
|
@ -2017,6 +2017,9 @@ action wizard Start ప్రారంభించు
|
|||
Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. PNG లేదా JPEG చిత్రాన్ని ఎంచుకోండి (గరిష్ఠంగా 4 MiB). పారదర్శకత అలాగే ఉంటుంది.
|
||||
Couldn't import the signature image: {e} సంతకం చిత్రాన్ని దిగుమతి చేయడం సాధ్యం కాలేదు: {e}
|
||||
Open Recent ఇటీవలివి తెరువు
|
||||
Clear Recent Files ఇటీవలి ఫైళ్లను క్లియర్ చేయి
|
||||
Remove from Recent ఇటీవలి ఫైళ్ల నుండి తీసివేయి
|
||||
Remove {name} from Recent {name}ను ఇటీవలి ఫైళ్ల నుండి తీసివేయి
|
||||
Pin folder to Home… ఫోల్డర్ను హోమ్కు పిన్ చేయి…
|
||||
No recent files ఇటీవలి ఫైళ్లు లేవు
|
||||
Go to page… పేజీకి వెళ్లు…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 13 and column 16.
|
|
|
@ -62,6 +62,9 @@
|
|||
Name on new comments 新注释的作者姓名
|
||||
Open… 打开…
|
||||
Open Recent 打开最近的文件
|
||||
Clear Recent Files 清除最近的文件
|
||||
Remove from Recent 从最近的文件中移除
|
||||
Remove {name} from Recent 从最近的文件中移除{name}
|
||||
Pin folder to Home… 将文件夹固定到主页…
|
||||
Folders 文件夹
|
||||
Pin a folder… 固定文件夹…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
|
|
@ -21,6 +21,9 @@
|
|||
Name on new comments 新註解的作者名稱
|
||||
Open… 開啟…
|
||||
Open Recent 開啟最近的檔案
|
||||
Clear Recent Files 清除最近的檔案
|
||||
Remove from Recent 從最近的檔案中移除
|
||||
Remove {name} from Recent 從最近的檔案中移除{name}
|
||||
Pin folder to Home… 將資料夾釘選到首頁…
|
||||
Folders 資料夾
|
||||
Pin a folder… 釘選資料夾…
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
|
|
@ -243,6 +243,49 @@ fn the_open_recent_menu_is_disabled_while_the_list_is_empty() {
|
|||
);
|
||||
}
|
||||
|
||||
fn recent_file(name: &str) -> pdfcraft_ui_egui::RecentFile {
|
||||
pdfcraft_ui_egui::RecentFile { name: name.into(), path: format!("/nowhere/{name}"), pages: 1, size: 0 }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_recent_files_at_the_foot_of_open_recent_empties_the_list() {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.open_bytes("doc.pdf", None, fixture(3)).unwrap();
|
||||
app.recent.extend([recent_file("first.pdf"), recent_file("second.pdf")]);
|
||||
app
|
||||
});
|
||||
h.run_steps(4);
|
||||
h.get_by_label("Menu").click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("File ⏵").hover();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Open Recent ⏵").hover();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Clear Recent Files").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.state().recent.is_empty(), "the list is empty");
|
||||
h.get_by_label("Menu").click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("File ⏵").hover();
|
||||
h.run_steps(3);
|
||||
assert!(h.query_by(|n| n.label().as_deref() == Some("Open Recent") && n.is_disabled()).is_some(), "and Open Recent is disabled");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_recent_files_runs_from_the_palette_and_is_saved() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.recent.extend([recent_file("first.pdf"), recent_file("second.pdf")]);
|
||||
assert!(app.execute("file.clear_recent"));
|
||||
assert!(app.recent.is_empty());
|
||||
let mut restarted = PdfCraftApp::new();
|
||||
restarted.recent.push(recent_file("stale.pdf"));
|
||||
restarted.restore(&app.persist());
|
||||
assert!(restarted.recent.is_empty(), "the empty list is what's saved");
|
||||
app.execute("file.clear_recent");
|
||||
assert!(app.toast.as_ref().is_some_and(|(m, _)| m.contains("No recent files")), "nothing to clear is said, not silent");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_shortcuts_dialog_lists_the_real_bindings() {
|
||||
let mut h = harness();
|
||||
|
|
|
|||
|
|
@ -67,6 +67,31 @@ fn long_recent_names_and_paths_are_cut_before_the_page_count() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn home_removes_one_recent_file_or_clears_them_all() {
|
||||
// Tall enough that the Recent list is on screen without scrolling.
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 1600.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
for name in ["first.pdf", "second.pdf", "third.pdf"] {
|
||||
app.recent.push(pdfcraft_ui_egui::RecentFile { name: name.into(), path: format!("/nowhere/{name}"), pages: 1, size: 0 });
|
||||
}
|
||||
app
|
||||
});
|
||||
h.run_steps(4);
|
||||
assert!(h.query_by_label("Remove second.pdf from Recent").is_none(), "the remove button shows only over its row");
|
||||
h.get_by_label("second.pdf").hover();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Remove second.pdf from Recent").click();
|
||||
h.run_steps(2);
|
||||
let names: Vec<String> = h.state().recent.iter().map(|r| r.name.clone()).collect();
|
||||
assert_eq!(names, ["first.pdf", "third.pdf"], "only that file left the list");
|
||||
h.get_by_label("Clear Recent Files").click();
|
||||
h.run_steps(2);
|
||||
assert!(h.state().recent.is_empty(), "Clear empties the list");
|
||||
h.get_by_label_contains("Files you open in PdfCraft appear here");
|
||||
assert!(h.query_by_label("Clear Recent Files").is_none(), "and goes away with nothing left to clear");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_catalog_tool_is_listed_after_view_more() {
|
||||
let mut h = harness(|_| {});
|
||||
|
|
|
|||
|
|
@ -656,10 +656,10 @@ area = "A"
|
|||
tier = "P1"
|
||||
milestone = "M3"
|
||||
status = "shipped"
|
||||
commands = ["file.open_recent"]
|
||||
commands = ["file.open_recent", "file.clear_recent"]
|
||||
tools = []
|
||||
evidence = ["crates/ui-egui/tests/ui.rs::persistence_round_trips_and_tolerates_garbage", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_lists_files_and_opens_one", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_is_disabled_while_the_list_is_empty"]
|
||||
notes = "never reads other apps' lists; File ▸ Open Recent lists them (#290), an already-open file focuses its tab instead of reopening it"
|
||||
evidence = ["crates/ui-egui/tests/ui.rs::persistence_round_trips_and_tolerates_garbage", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_lists_files_and_opens_one", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_is_disabled_while_the_list_is_empty", "crates/ui-egui/tests/commands.rs::clear_recent_files_at_the_foot_of_open_recent_empties_the_list", "crates/ui-egui/tests/commands.rs::clear_recent_files_runs_from_the_palette_and_is_saved", "crates/ui-egui/tests/ui.rs::home_removes_one_recent_file_or_clears_them_all"]
|
||||
notes = "never reads other apps' lists; File ▸ Open Recent lists them (#290), an already-open file focuses its tab instead of reopening it; Clear Recent Files at the foot of Open Recent, on Home and in the palette, and a remove button on each Home row (#430); missing: the row's remove button shows on pointer hover only (keyboard users clear the whole list)"
|
||||
|
||||
[[feature]]
|
||||
id = "core.reopen-last-session"
|
||||
|
|
|
|||
Loading…
Reference in New Issue