diff --git a/cosmic-settings/src/pages/printers/backend.rs b/cosmic-settings/src/pages/printers/backend.rs index 36a7a1a..b3344bf 100644 --- a/cosmic-settings/src/pages/printers/backend.rs +++ b/cosmic-settings/src/pages/printers/backend.rs @@ -113,7 +113,9 @@ pub fn print_test_page_sync(printer: &str) -> Result<(), String> { let dest = cups_rs::get_destination(printer).map_err(|err| err.to_string())?; let job = cups_rs::create_job(&dest, "COSMIC Settings test page") .map_err(|err| err.to_string())?; - job.submit_file(TEST_PAGE, "application/postscript") + // Let CUPS sniff the format: the test page is a cups-filters PDF banner + // template, not PostScript. + job.submit_file(TEST_PAGE, "application/octet-stream") .map_err(|err| err.to_string()) } @@ -177,21 +179,29 @@ pub async fn set_enabled(name: &str, enabled: bool) -> Result<(), String> { /// Sanitize a display name into a valid CUPS queue name and make it unique /// against the current printer list. pub fn unique_name(raw: &str, existing: &[Printer]) -> String { - let sanitized: String = raw - .chars() - .map(|c| { - if c.is_alphanumeric() || matches!(c, '-' | '_' | '.') { - c - } else { - '_' - } - }) - .collect(); + let mut sanitized = String::with_capacity(raw.len()); + for c in raw.chars() { + if c.is_alphanumeric() { + sanitized.push(c); + } else if matches!(c, '[' | ']' | '(' | ')') { + // Brackets usually wrap a model identifier; drop them so + // "series [32C998]" becomes "series_32C998", not "series__32C998_". + continue; + } else { + sanitized.push('_'); + } + } - let base = if sanitized.is_empty() { + let base = sanitized + .split('_') + .filter(|part| !part.is_empty()) + .collect::>() + .join("_"); + + let base = if base.is_empty() { "Printer".to_string() } else { - sanitized + base }; let mut candidate = base.clone(); diff --git a/cosmic-settings/src/pages/printers/mod.rs b/cosmic-settings/src/pages/printers/mod.rs index ea25b86..f0491b0 100644 --- a/cosmic-settings/src/pages/printers/mod.rs +++ b/cosmic-settings/src/pages/printers/mod.rs @@ -112,7 +112,7 @@ impl page::Page for Page { fn dialog(&self) -> Option> { let Dialog::RemovePrinter { name } = self.dialog.as_ref()?; - let confirm = widget::button::destructive(fl!("printers-remove")) + let confirm = widget::button::destructive(fl!("printers-remove-confirm-button")) .on_press(crate::pages::Message::from(Message::ConfirmRemove)); let cancel = widget::button::standard(fl!("cancel")) @@ -711,7 +711,11 @@ fn selected_printer_section() -> Section { .apply(Element::from), ); - column = column.add(widget::row::with_children(actions).spacing(spacing.space_s)); + column = column.add( + widget::flex_row(actions) + .spacing(spacing.space_s) + .width(Length::Fill), + ); column.apply(Element::from) }) diff --git a/i18n/en/cosmic_settings.ftl b/i18n/en/cosmic_settings.ftl index dcc0b7e..9ec5e26 100644 --- a/i18n/en/cosmic_settings.ftl +++ b/i18n/en/cosmic_settings.ftl @@ -675,6 +675,7 @@ printers-not-accepting = Not accepting jobs printers-pause = Pause printers-remove = Remove printer printers-remove-confirm = Remove this printer? +printers-remove-confirm-button = Remove printers-remove-confirm-description = “{ $name }” will be removed from this system. Print jobs queued on it will be discarded. printers-resume = Resume printers-state = State diff --git a/i18n/fr/cosmic_settings.ftl b/i18n/fr/cosmic_settings.ftl index bc8bdf9..3d6e06c 100644 --- a/i18n/fr/cosmic_settings.ftl +++ b/i18n/fr/cosmic_settings.ftl @@ -463,6 +463,7 @@ printers-not-accepting = N'accepte pas les travaux printers-pause = Suspendre printers-remove = Supprimer l'imprimante printers-remove-confirm = Supprimer cette imprimante ? +printers-remove-confirm-button = Supprimer printers-remove-confirm-description = « { $name } » sera supprimée du système. Les travaux en attente sur cette imprimante seront abandonnés. printers-resume = Reprendre printers-state = État