// SPDX-License-Identifier: GPL-3.0-or-later // examples/cli.rs // // CLI test harness for the noctua_core document foundation. use clap::{ArgGroup, Parser}; use noctua_core::document::manager::{DocumentCommand, DocumentManager, DocumentState}; use noctua_core::document::session::SessionKind; use std::path::PathBuf; #[derive(Parser, Debug)] #[command( name = "noctua", about = "A document viewer for the COSMIC desktop", group( ArgGroup::new("source") .required(true) .args(["open_document", "open_directory", "open_session"]) ) )] struct Cli { /// Open a document (Raster, Vector, Portable) #[arg(long, value_name = "PATH")] open_document: Option, /// Open a directory #[arg(long, value_name = "PATH")] open_directory: Option, /// Open a session file (.ron) #[arg(long, value_name = "PATH")] open_session: Option, } fn main() { env_logger::init(); let cli = Cli::parse(); let mut manager = DocumentManager::new(); if let Some(path) = cli.open_session { manager.handle(DocumentCommand::OpenSession(path)); } else if let Some(path) = cli.open_document { let dir = path .parent() .map(|p| p.to_path_buf()) .unwrap_or_else(|| PathBuf::from(".")); let session_name = dir .file_name() .and_then(|n| n.to_str()) .unwrap_or("Browse") .to_string(); if manager.session(&session_name).is_none() { manager.handle(DocumentCommand::CreateSession { name: session_name.clone(), kind: SessionKind::DirectoryBrowser, path: Some(dir.clone()), }); manager.handle(DocumentCommand::ScanDirectory { session: session_name.clone(), dir, }); } manager.handle(DocumentCommand::AddFileToSession { session: session_name, path, }); } else if let Some(path) = cli.open_directory { let session_name = path .file_name() .and_then(|n| n.to_str()) .unwrap_or("Browse") .to_string(); if manager.session(&session_name).is_none() { manager.handle(DocumentCommand::CreateSession { name: session_name.clone(), kind: SessionKind::DirectoryBrowser, path: Some(path.clone()), }); manager.handle(DocumentCommand::ScanDirectory { session: session_name.clone(), dir: path, }); } manager.handle(DocumentCommand::SetActive(session_name)); } match &manager.state { DocumentState::Empty => println!("UI: No document loaded."), DocumentState::Loading => println!("UI: Loading..."), DocumentState::Error(err) => eprintln!("UI: Error -> {err}"), DocumentState::Loaded(_) => { println!("UI: Document loaded."); if let Some(name) = manager.active_session_name.clone() { if let Some(session) = manager.session(&name) { println!( "UI: Session '{}' ({:?}) has {} items, current index: {:?}", session.name, session.kind, session.items.len(), session.current_index ); match session.kind { SessionKind::DirectoryBrowser => { println!("UI: Display as directory browser (thumbnails in left panel)"); } SessionKind::DocumentCollection => { println!("UI: Display as document collection (pages)"); } } } println!("\nUI: Test navigation..."); manager.handle(DocumentCommand::NavigateNext); if let Some(session) = manager.session(&name) { println!( "UI: After NavigateNext -> index {:?}", session.current_index ); } manager.handle(DocumentCommand::NavigatePrevious); if let Some(session) = manager.session(&name) { println!( "UI: After NavigatePrevious -> index {:?}", session.current_index ); } manager.handle(DocumentCommand::SelectItem(0)); if let Some(session) = manager.session(&name) { println!( "UI: After SelectItem(0) -> index {:?}", session.current_index ); } } } } }