feat: import Xournal++ and Xournal notebooks (Issue #47)

The import menu entry (formerly "Import PDF") and drag & drop now also
accept .xopp and .xoj files. Each Xournal page becomes a page of a new
notebook: strokes with pen pressure, highlighters, texts, embedded
images, lined/squared/dotted paper, image backgrounds and PDF
backgrounds (looked up at the stored path and next to the file). All
layers are flattened in order; LaTeX formulas are skipped and counted
in the status message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haraldandClaude Opus 5.5 committed 2026-10-27 11:10:34 +01:00
1 parent b5d9d72e79
commit 2bd697ef82
11 files changed
+902 -44

No files matched your search

+10 -6
View File
@@ -1,4 +1,4 @@
//! Eingebaute, stift- und fingertaugliche Dateiauswahl für Bilder und PDFs.
//! Eingebaute, stift- und fingertaugliche Dateiauswahl für Bilder, PDFs und Xournal++-Dateien.
//!
//! Bewusst ohne Systemdialog: der bräuchte GTK oder das Desktop-Portal, die unter WSL und auf
//! schlanken Systemen oft fehlen. Die Auswahl zeigt Ordner und die passenden Dateien des
@@ -22,8 +22,8 @@ pub struct PickerEntry {
pub enum PickerKind {
/// Bilder zum Einfügen auf der aktuellen Seite
Image,
/// PDF zum Importieren als neues Notizbuch
Pdf,
/// PDF or Xournal++ file to import as a new notebook
Import,
}
impl PickerKind {
@@ -31,7 +31,7 @@ impl PickerKind {
pub fn accepts(self, path: &Path) -> bool {
match self {
PickerKind::Image => is_supported_image_path(path),
PickerKind::Pdf => is_pdf_path(path),
PickerKind::Import => is_pdf_path(path) || crate::xopp::is_xopp_path(path),
}
}
}
@@ -63,7 +63,7 @@ impl FilePicker {
.or_else(|| {
let preferred = match kind {
PickerKind::Image => tn!("🖼 Bilder"),
PickerKind::Pdf => tn!("⬇ Downloads"),
PickerKind::Import => tn!("⬇ Downloads"),
};
let all = shortcuts();
all.iter()
@@ -192,6 +192,7 @@ mod tests {
".versteckt.png",
"c.webp",
"Skript.PDF",
"mathe.xopp",
] {
std::fs::write(dir.path().join(name), b"x").unwrap();
}
@@ -210,7 +211,10 @@ mod tests {
names(PickerKind::Image),
["aOrdner", "zOrdner", "A.jpg", "b.png", "c.webp"]
);
assert_eq!(names(PickerKind::Pdf), ["aOrdner", "zOrdner", "Skript.PDF"]);
assert_eq!(
names(PickerKind::Import),
["aOrdner", "zOrdner", "mathe.xopp", "Skript.PDF"]
);
}
#[test]