use super::{HandleToken, DESTINATION, PATH};
use crate::{
helpers::{call_basic_response_method, call_request_method},
Error, WindowIdentifier,
};
use serde::{Deserialize, Serialize, Serializer};
use std::os::unix::prelude::AsRawFd;
use strum_macros::{AsRefStr, EnumString, IntoStaticStr, ToString};
use zvariant::{Fd, Signature};
use zvariant_derive::{DeserializeDict, SerializeDict, TypeDict};
#[derive(
Debug, Clone, Deserialize, EnumString, AsRefStr, IntoStaticStr, ToString, PartialEq, Eq,
)]
#[strum(serialize_all = "lowercase")]
pub enum Orientation {
Landscape,
Portrait,
#[strum(serialize = "reverse_landscape")]
ReverseLandscape,
#[strum(serialize = "reverse_portrait")]
ReversePortrait,
}
impl zvariant::Type for Orientation {
fn signature() -> Signature<'static> {
String::signature()
}
}
impl Serialize for Orientation {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
String::serialize(&self.to_string(), serializer)
}
}
#[derive(
Debug, Clone, Deserialize, EnumString, AsRefStr, IntoStaticStr, ToString, PartialEq, Eq,
)]
#[strum(serialize_all = "lowercase")]
pub enum Quality {
Draft,
Low,
Normal,
High,
}
impl zvariant::Type for Quality {
fn signature() -> Signature<'static> {
String::signature()
}
}
impl Serialize for Quality {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
String::serialize(&self.to_string(), serializer)
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug, Default)]
pub struct Settings {
pub orientation: Option<Orientation>,
#[zvariant(rename = "paper-format")]
pub paper_format: Option<String>,
#[zvariant(rename = "paper-width")]
pub paper_width: Option<String>,
#[zvariant(rename = "paper-height")]
pub paper_height: Option<String>,
#[zvariant(rename = "n-copies")]
pub n_copies: Option<String>,
#[zvariant(rename = "default-source")]
pub default_source: Option<String>,
pub quality: Option<Quality>,
pub resolution: Option<String>,
#[zvariant(rename = "use-color")]
pub use_color: Option<bool>,
pub duplex: Option<String>,
pub collate: Option<String>,
pub reverse: Option<String>,
#[zvariant(rename = "media-type")]
pub media_type: Option<String>,
pub dither: Option<String>,
pub scale: Option<String>,
#[zvariant(rename = "print-pages")]
pub print_pages: Option<String>,
#[zvariant(rename = "page-ranges")]
pub page_ranges: Option<String>,
#[zvariant(rename = "page-set")]
pub page_set: Option<String>,
pub finishings: Option<String>,
#[zvariant(rename = "number-up")]
pub number_up: Option<String>,
#[zvariant(rename = "number-up-layout")]
pub number_up_layout: Option<String>,
#[zvariant(rename = "output-bin")]
pub output_bin: Option<String>,
#[zvariant(rename = "resolution-x")]
pub resolution_x: Option<String>,
#[zvariant(rename = "resolution-y")]
pub resolution_y: Option<String>,
#[zvariant(rename = "printer-lpi")]
pub print_lpi: Option<String>,
#[zvariant(rename = "output-basename")]
pub output_basename: Option<String>,
#[zvariant(rename = "output-file-format")]
pub output_file_format: Option<String>,
#[zvariant(rename = "output-uri")]
pub output_uri: Option<String>,
}
impl Settings {
pub fn orientation(mut self, orientation: Orientation) -> Self {
self.orientation = Some(orientation);
self
}
pub fn paper_format(mut self, paper_format: &str) -> Self {
self.paper_format = Some(paper_format.to_string());
self
}
pub fn paper_width(mut self, paper_width: &str) -> Self {
self.paper_width = Some(paper_width.to_string());
self
}
pub fn paper_height(mut self, paper_height: &str) -> Self {
self.paper_height = Some(paper_height.to_string());
self
}
pub fn n_copies(mut self, n_copies: &str) -> Self {
self.n_copies = Some(n_copies.to_string());
self
}
pub fn default_source(mut self, default_source: &str) -> Self {
self.default_source = Some(default_source.to_string());
self
}
pub fn quality(mut self, quality: Quality) -> Self {
self.quality = Some(quality);
self
}
pub fn resolution(mut self, resolution: &str) -> Self {
self.resolution = Some(resolution.to_string());
self
}
pub fn use_color(mut self, use_color: bool) -> Self {
self.use_color = Some(use_color);
self
}
pub fn duplex(mut self, duplex: &str) -> Self {
self.duplex = Some(duplex.to_string());
self
}
pub fn collate(mut self, collate: &str) -> Self {
self.collate = Some(collate.to_string());
self
}
pub fn reverse(mut self, reverse: &str) -> Self {
self.reverse = Some(reverse.to_string());
self
}
pub fn media_type(mut self, media_type: &str) -> Self {
self.media_type = Some(media_type.to_string());
self
}
pub fn dither(mut self, dither: &str) -> Self {
self.dither = Some(dither.to_string());
self
}
pub fn scale(mut self, scale: &str) -> Self {
self.scale = Some(scale.to_string());
self
}
pub fn print_pages(mut self, print_pages: &str) -> Self {
self.print_pages = Some(print_pages.to_string());
self
}
pub fn page_ranges(mut self, page_ranges: &str) -> Self {
self.page_ranges = Some(page_ranges.to_string());
self
}
pub fn page_set(mut self, page_set: &str) -> Self {
self.page_set = Some(page_set.to_string());
self
}
pub fn finishings(mut self, finishings: &str) -> Self {
self.finishings = Some(finishings.to_string());
self
}
pub fn number_up(mut self, number_up: &str) -> Self {
self.number_up = Some(number_up.to_string());
self
}
pub fn number_up_layout(mut self, number_up_layout: &str) -> Self {
self.number_up_layout = Some(number_up_layout.to_string());
self
}
pub fn output_bin(mut self, output_bin: &str) -> Self {
self.output_bin = Some(output_bin.to_string());
self
}
pub fn resolution_x(mut self, resolution_x: &str) -> Self {
self.resolution_x = Some(resolution_x.to_string());
self
}
pub fn resolution_y(mut self, resolution_y: &str) -> Self {
self.resolution_y = Some(resolution_y.to_string());
self
}
pub fn print_lpi(mut self, print_lpi: &str) -> Self {
self.print_lpi = Some(print_lpi.to_string());
self
}
pub fn output_basename(mut self, output_basename: &str) -> Self {
self.output_basename = Some(output_basename.to_string());
self
}
pub fn output_file_format(mut self, output_file_format: &str) -> Self {
self.output_file_format = Some(output_file_format.to_string());
self
}
pub fn output_uri(mut self, output_uri: &str) -> Self {
self.output_uri = Some(output_uri.to_string());
self
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug, Default)]
pub struct PageSetup {
#[zvariant(rename = "PPDName")]
pub ppdname: Option<String>,
pub name: Option<String>,
pub display_name: Option<String>,
pub width: Option<f64>,
pub height: Option<f64>,
pub margin_top: Option<f64>,
pub margin_bottom: Option<f64>,
pub margin_right: Option<f64>,
pub margin_left: Option<f64>,
pub orientation: Option<Orientation>,
}
impl PageSetup {
pub fn ppdname(mut self, ppdname: &str) -> Self {
self.ppdname = Some(ppdname.to_string());
self
}
pub fn name(mut self, name: &str) -> Self {
self.name = Some(name.to_string());
self
}
pub fn display_name(mut self, display_name: &str) -> Self {
self.display_name = Some(display_name.to_string());
self
}
pub fn orientation(mut self, orientation: Orientation) -> Self {
self.orientation = Some(orientation);
self
}
pub fn width(mut self, width: f64) -> Self {
self.width = Some(width);
self
}
pub fn height(mut self, height: f64) -> Self {
self.height = Some(height);
self
}
pub fn margin_top(mut self, margin_top: f64) -> Self {
self.margin_top = Some(margin_top);
self
}
pub fn margin_bottom(mut self, margin_bottom: f64) -> Self {
self.margin_bottom = Some(margin_bottom);
self
}
pub fn margin_right(mut self, margin_right: f64) -> Self {
self.margin_right = Some(margin_right);
self
}
pub fn margin_left(mut self, margin_left: f64) -> Self {
self.margin_left = Some(margin_left);
self
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug, Default)]
struct PreparePrintOptions {
handle_token: HandleToken,
modal: Option<bool>,
}
impl PreparePrintOptions {
pub fn modal(mut self, modal: bool) -> Self {
self.modal = Some(modal);
self
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug, Default)]
struct PrintOptions {
handle_token: HandleToken,
modal: Option<bool>,
token: Option<u32>,
}
impl PrintOptions {
pub fn token(mut self, token: u32) -> Self {
self.token = Some(token);
self
}
pub fn modal(mut self, modal: bool) -> Self {
self.modal = Some(modal);
self
}
}
#[derive(DeserializeDict, SerializeDict, TypeDict, Debug)]
pub struct PreparePrint {
pub settings: Settings,
#[zvariant(rename = "page-setup")]
pub page_setup: PageSetup,
pub token: u32,
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.Print")]
pub struct PrintProxy<'a>(zbus::azync::Proxy<'a>);
impl<'a> PrintProxy<'a> {
pub async fn new(connection: &zbus::azync::Connection) -> Result<PrintProxy<'a>, Error> {
let proxy = zbus::ProxyBuilder::new_bare(connection)
.interface("org.freedesktop.portal.Print")
.path(PATH)?
.destination(DESTINATION)
.build_async()
.await?;
Ok(Self(proxy))
}
pub fn inner(&self) -> &zbus::azync::Proxy<'_> {
&self.0
}
#[doc(alias = "PreparePint")]
pub async fn prepare_print(
&self,
identifier: WindowIdentifier,
title: &str,
settings: Settings,
page_setup: PageSetup,
modal: bool,
) -> Result<PreparePrint, Error> {
let options = PreparePrintOptions::default().modal(modal);
call_request_method(
&self.0,
&options.handle_token,
"PreparePint",
&(identifier, title, settings, page_setup, &options),
)
.await
}
#[doc(alias = "Print")]
pub async fn print<F>(
&self,
identifier: WindowIdentifier,
title: &str,
fd: &F,
token: Option<u32>,
modal: bool,
) -> Result<(), Error>
where
F: AsRawFd,
{
let options = PrintOptions::default()
.token(token.unwrap_or(0))
.modal(modal);
call_basic_response_method(
&self.0,
&options.handle_token,
"Print",
&(identifier, title, Fd::from(fd.as_raw_fd()), &options),
)
.await
}
}