1use crate::{ffi, PageSetup, PrintSettings, PrintSetup, Window};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GtkPrintDialog")]
15 pub struct PrintDialog(Object<ffi::GtkPrintDialog, ffi::GtkPrintDialogClass>);
16
17 match fn {
18 type_ => || ffi::gtk_print_dialog_get_type(),
19 }
20}
21
22impl PrintDialog {
23 #[doc(alias = "gtk_print_dialog_new")]
24 pub fn new() -> PrintDialog {
25 assert_initialized_main_thread!();
26 unsafe { from_glib_full(ffi::gtk_print_dialog_new()) }
27 }
28
29 pub fn builder() -> PrintDialogBuilder {
34 PrintDialogBuilder::new()
35 }
36
37 #[doc(alias = "gtk_print_dialog_get_accept_label")]
38 #[doc(alias = "get_accept_label")]
39 #[doc(alias = "accept-label")]
40 pub fn accept_label(&self) -> glib::GString {
41 unsafe {
42 from_glib_none(ffi::gtk_print_dialog_get_accept_label(
43 self.to_glib_none().0,
44 ))
45 }
46 }
47
48 #[doc(alias = "gtk_print_dialog_get_modal")]
49 #[doc(alias = "get_modal")]
50 #[doc(alias = "modal")]
51 pub fn is_modal(&self) -> bool {
52 unsafe { from_glib(ffi::gtk_print_dialog_get_modal(self.to_glib_none().0)) }
53 }
54
55 #[doc(alias = "gtk_print_dialog_get_page_setup")]
56 #[doc(alias = "get_page_setup")]
57 #[doc(alias = "page-setup")]
58 pub fn page_setup(&self) -> Option<PageSetup> {
59 unsafe { from_glib_none(ffi::gtk_print_dialog_get_page_setup(self.to_glib_none().0)) }
60 }
61
62 #[doc(alias = "gtk_print_dialog_get_print_settings")]
63 #[doc(alias = "get_print_settings")]
64 #[doc(alias = "print-settings")]
65 pub fn print_settings(&self) -> Option<PrintSettings> {
66 unsafe {
67 from_glib_none(ffi::gtk_print_dialog_get_print_settings(
68 self.to_glib_none().0,
69 ))
70 }
71 }
72
73 #[doc(alias = "gtk_print_dialog_get_title")]
74 #[doc(alias = "get_title")]
75 pub fn title(&self) -> glib::GString {
76 unsafe { from_glib_none(ffi::gtk_print_dialog_get_title(self.to_glib_none().0)) }
77 }
78
79 #[doc(alias = "gtk_print_dialog_print")]
80 pub fn print<P: FnOnce(Result<gio::OutputStream, glib::Error>) + 'static>(
81 &self,
82 parent: Option<&impl IsA<Window>>,
83 setup: Option<&PrintSetup>,
84 cancellable: Option<&impl IsA<gio::Cancellable>>,
85 callback: P,
86 ) {
87 let main_context = glib::MainContext::ref_thread_default();
88 let is_main_context_owner = main_context.is_owner();
89 let has_acquired_main_context = (!is_main_context_owner)
90 .then(|| main_context.acquire().ok())
91 .flatten();
92 assert!(
93 is_main_context_owner || has_acquired_main_context.is_some(),
94 "Async operations only allowed if the thread is owning the MainContext"
95 );
96
97 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
98 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
99 unsafe extern "C" fn print_trampoline<
100 P: FnOnce(Result<gio::OutputStream, glib::Error>) + 'static,
101 >(
102 _source_object: *mut glib::gobject_ffi::GObject,
103 res: *mut gio::ffi::GAsyncResult,
104 user_data: glib::ffi::gpointer,
105 ) {
106 let mut error = std::ptr::null_mut();
107 let ret = ffi::gtk_print_dialog_print_finish(_source_object as *mut _, res, &mut error);
108 let result = if error.is_null() {
109 Ok(from_glib_full(ret))
110 } else {
111 Err(from_glib_full(error))
112 };
113 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
114 Box_::from_raw(user_data as *mut _);
115 let callback: P = callback.into_inner();
116 callback(result);
117 }
118 let callback = print_trampoline::<P>;
119 unsafe {
120 ffi::gtk_print_dialog_print(
121 self.to_glib_none().0,
122 parent.map(|p| p.as_ref()).to_glib_none().0,
123 setup.to_glib_none().0,
124 cancellable.map(|p| p.as_ref()).to_glib_none().0,
125 Some(callback),
126 Box_::into_raw(user_data) as *mut _,
127 );
128 }
129 }
130
131 pub fn print_future(
132 &self,
133 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
134 setup: Option<&PrintSetup>,
135 ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::OutputStream, glib::Error>> + 'static>>
136 {
137 let parent = parent.map(ToOwned::to_owned);
138 let setup = setup.map(ToOwned::to_owned);
139 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
140 obj.print(
141 parent.as_ref().map(::std::borrow::Borrow::borrow),
142 setup.as_ref().map(::std::borrow::Borrow::borrow),
143 Some(cancellable),
144 move |res| {
145 send.resolve(res);
146 },
147 );
148 }))
149 }
150
151 #[doc(alias = "gtk_print_dialog_print_file")]
152 pub fn print_file<P: FnOnce(Result<(), glib::Error>) + 'static>(
153 &self,
154 parent: Option<&impl IsA<Window>>,
155 setup: Option<&PrintSetup>,
156 file: &impl IsA<gio::File>,
157 cancellable: Option<&impl IsA<gio::Cancellable>>,
158 callback: P,
159 ) {
160 let main_context = glib::MainContext::ref_thread_default();
161 let is_main_context_owner = main_context.is_owner();
162 let has_acquired_main_context = (!is_main_context_owner)
163 .then(|| main_context.acquire().ok())
164 .flatten();
165 assert!(
166 is_main_context_owner || has_acquired_main_context.is_some(),
167 "Async operations only allowed if the thread is owning the MainContext"
168 );
169
170 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
171 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
172 unsafe extern "C" fn print_file_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
173 _source_object: *mut glib::gobject_ffi::GObject,
174 res: *mut gio::ffi::GAsyncResult,
175 user_data: glib::ffi::gpointer,
176 ) {
177 let mut error = std::ptr::null_mut();
178 ffi::gtk_print_dialog_print_file_finish(_source_object as *mut _, res, &mut error);
179 let result = if error.is_null() {
180 Ok(())
181 } else {
182 Err(from_glib_full(error))
183 };
184 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
185 Box_::from_raw(user_data as *mut _);
186 let callback: P = callback.into_inner();
187 callback(result);
188 }
189 let callback = print_file_trampoline::<P>;
190 unsafe {
191 ffi::gtk_print_dialog_print_file(
192 self.to_glib_none().0,
193 parent.map(|p| p.as_ref()).to_glib_none().0,
194 setup.to_glib_none().0,
195 file.as_ref().to_glib_none().0,
196 cancellable.map(|p| p.as_ref()).to_glib_none().0,
197 Some(callback),
198 Box_::into_raw(user_data) as *mut _,
199 );
200 }
201 }
202
203 pub fn print_file_future(
204 &self,
205 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
206 setup: Option<&PrintSetup>,
207 file: &(impl IsA<gio::File> + Clone + 'static),
208 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
209 let parent = parent.map(ToOwned::to_owned);
210 let setup = setup.map(ToOwned::to_owned);
211 let file = file.clone();
212 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
213 obj.print_file(
214 parent.as_ref().map(::std::borrow::Borrow::borrow),
215 setup.as_ref().map(::std::borrow::Borrow::borrow),
216 &file,
217 Some(cancellable),
218 move |res| {
219 send.resolve(res);
220 },
221 );
222 }))
223 }
224
225 #[doc(alias = "gtk_print_dialog_set_accept_label")]
226 #[doc(alias = "accept-label")]
227 pub fn set_accept_label(&self, accept_label: &str) {
228 unsafe {
229 ffi::gtk_print_dialog_set_accept_label(
230 self.to_glib_none().0,
231 accept_label.to_glib_none().0,
232 );
233 }
234 }
235
236 #[doc(alias = "gtk_print_dialog_set_modal")]
237 #[doc(alias = "modal")]
238 pub fn set_modal(&self, modal: bool) {
239 unsafe {
240 ffi::gtk_print_dialog_set_modal(self.to_glib_none().0, modal.into_glib());
241 }
242 }
243
244 #[doc(alias = "gtk_print_dialog_set_page_setup")]
245 #[doc(alias = "page-setup")]
246 pub fn set_page_setup(&self, page_setup: &PageSetup) {
247 unsafe {
248 ffi::gtk_print_dialog_set_page_setup(
249 self.to_glib_none().0,
250 page_setup.to_glib_none().0,
251 );
252 }
253 }
254
255 #[doc(alias = "gtk_print_dialog_set_print_settings")]
256 #[doc(alias = "print-settings")]
257 pub fn set_print_settings(&self, print_settings: &PrintSettings) {
258 unsafe {
259 ffi::gtk_print_dialog_set_print_settings(
260 self.to_glib_none().0,
261 print_settings.to_glib_none().0,
262 );
263 }
264 }
265
266 #[doc(alias = "gtk_print_dialog_set_title")]
267 #[doc(alias = "title")]
268 pub fn set_title(&self, title: &str) {
269 unsafe {
270 ffi::gtk_print_dialog_set_title(self.to_glib_none().0, title.to_glib_none().0);
271 }
272 }
273
274 #[doc(alias = "gtk_print_dialog_setup")]
275 pub fn setup<P: FnOnce(Result<PrintSetup, glib::Error>) + 'static>(
276 &self,
277 parent: Option<&impl IsA<Window>>,
278 cancellable: Option<&impl IsA<gio::Cancellable>>,
279 callback: P,
280 ) {
281 let main_context = glib::MainContext::ref_thread_default();
282 let is_main_context_owner = main_context.is_owner();
283 let has_acquired_main_context = (!is_main_context_owner)
284 .then(|| main_context.acquire().ok())
285 .flatten();
286 assert!(
287 is_main_context_owner || has_acquired_main_context.is_some(),
288 "Async operations only allowed if the thread is owning the MainContext"
289 );
290
291 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
292 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
293 unsafe extern "C" fn setup_trampoline<
294 P: FnOnce(Result<PrintSetup, glib::Error>) + 'static,
295 >(
296 _source_object: *mut glib::gobject_ffi::GObject,
297 res: *mut gio::ffi::GAsyncResult,
298 user_data: glib::ffi::gpointer,
299 ) {
300 let mut error = std::ptr::null_mut();
301 let ret = ffi::gtk_print_dialog_setup_finish(_source_object as *mut _, res, &mut error);
302 let result = if error.is_null() {
303 Ok(from_glib_full(ret))
304 } else {
305 Err(from_glib_full(error))
306 };
307 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
308 Box_::from_raw(user_data as *mut _);
309 let callback: P = callback.into_inner();
310 callback(result);
311 }
312 let callback = setup_trampoline::<P>;
313 unsafe {
314 ffi::gtk_print_dialog_setup(
315 self.to_glib_none().0,
316 parent.map(|p| p.as_ref()).to_glib_none().0,
317 cancellable.map(|p| p.as_ref()).to_glib_none().0,
318 Some(callback),
319 Box_::into_raw(user_data) as *mut _,
320 );
321 }
322 }
323
324 pub fn setup_future(
325 &self,
326 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
327 ) -> Pin<Box_<dyn std::future::Future<Output = Result<PrintSetup, glib::Error>> + 'static>>
328 {
329 let parent = parent.map(ToOwned::to_owned);
330 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
331 obj.setup(
332 parent.as_ref().map(::std::borrow::Borrow::borrow),
333 Some(cancellable),
334 move |res| {
335 send.resolve(res);
336 },
337 );
338 }))
339 }
340
341 #[cfg(feature = "v4_14")]
342 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
343 #[doc(alias = "accept-label")]
344 pub fn connect_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
345 unsafe extern "C" fn notify_accept_label_trampoline<F: Fn(&PrintDialog) + 'static>(
346 this: *mut ffi::GtkPrintDialog,
347 _param_spec: glib::ffi::gpointer,
348 f: glib::ffi::gpointer,
349 ) {
350 let f: &F = &*(f as *const F);
351 f(&from_glib_borrow(this))
352 }
353 unsafe {
354 let f: Box_<F> = Box_::new(f);
355 connect_raw(
356 self.as_ptr() as *mut _,
357 c"notify::accept-label".as_ptr() as *const _,
358 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
359 notify_accept_label_trampoline::<F> as *const (),
360 )),
361 Box_::into_raw(f),
362 )
363 }
364 }
365
366 #[cfg(feature = "v4_14")]
367 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
368 #[doc(alias = "modal")]
369 pub fn connect_modal_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
370 unsafe extern "C" fn notify_modal_trampoline<F: Fn(&PrintDialog) + 'static>(
371 this: *mut ffi::GtkPrintDialog,
372 _param_spec: glib::ffi::gpointer,
373 f: glib::ffi::gpointer,
374 ) {
375 let f: &F = &*(f as *const F);
376 f(&from_glib_borrow(this))
377 }
378 unsafe {
379 let f: Box_<F> = Box_::new(f);
380 connect_raw(
381 self.as_ptr() as *mut _,
382 c"notify::modal".as_ptr() as *const _,
383 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
384 notify_modal_trampoline::<F> as *const (),
385 )),
386 Box_::into_raw(f),
387 )
388 }
389 }
390
391 #[cfg(feature = "v4_14")]
392 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
393 #[doc(alias = "page-setup")]
394 pub fn connect_page_setup_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
395 unsafe extern "C" fn notify_page_setup_trampoline<F: Fn(&PrintDialog) + 'static>(
396 this: *mut ffi::GtkPrintDialog,
397 _param_spec: glib::ffi::gpointer,
398 f: glib::ffi::gpointer,
399 ) {
400 let f: &F = &*(f as *const F);
401 f(&from_glib_borrow(this))
402 }
403 unsafe {
404 let f: Box_<F> = Box_::new(f);
405 connect_raw(
406 self.as_ptr() as *mut _,
407 c"notify::page-setup".as_ptr() as *const _,
408 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
409 notify_page_setup_trampoline::<F> as *const (),
410 )),
411 Box_::into_raw(f),
412 )
413 }
414 }
415
416 #[cfg(feature = "v4_14")]
417 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
418 #[doc(alias = "print-settings")]
419 pub fn connect_print_settings_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
420 unsafe extern "C" fn notify_print_settings_trampoline<F: Fn(&PrintDialog) + 'static>(
421 this: *mut ffi::GtkPrintDialog,
422 _param_spec: glib::ffi::gpointer,
423 f: glib::ffi::gpointer,
424 ) {
425 let f: &F = &*(f as *const F);
426 f(&from_glib_borrow(this))
427 }
428 unsafe {
429 let f: Box_<F> = Box_::new(f);
430 connect_raw(
431 self.as_ptr() as *mut _,
432 c"notify::print-settings".as_ptr() as *const _,
433 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
434 notify_print_settings_trampoline::<F> as *const (),
435 )),
436 Box_::into_raw(f),
437 )
438 }
439 }
440
441 #[cfg(feature = "v4_14")]
442 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
443 #[doc(alias = "title")]
444 pub fn connect_title_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
445 unsafe extern "C" fn notify_title_trampoline<F: Fn(&PrintDialog) + 'static>(
446 this: *mut ffi::GtkPrintDialog,
447 _param_spec: glib::ffi::gpointer,
448 f: glib::ffi::gpointer,
449 ) {
450 let f: &F = &*(f as *const F);
451 f(&from_glib_borrow(this))
452 }
453 unsafe {
454 let f: Box_<F> = Box_::new(f);
455 connect_raw(
456 self.as_ptr() as *mut _,
457 c"notify::title".as_ptr() as *const _,
458 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
459 notify_title_trampoline::<F> as *const (),
460 )),
461 Box_::into_raw(f),
462 )
463 }
464 }
465}
466
467#[cfg(feature = "v4_14")]
468#[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
469impl Default for PrintDialog {
470 fn default() -> Self {
471 Self::new()
472 }
473}
474
475#[must_use = "The builder must be built to be used"]
480pub struct PrintDialogBuilder {
481 builder: glib::object::ObjectBuilder<'static, PrintDialog>,
482}
483
484impl PrintDialogBuilder {
485 fn new() -> Self {
486 Self {
487 builder: glib::object::Object::builder(),
488 }
489 }
490
491 #[cfg(feature = "v4_14")]
492 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
493 pub fn accept_label(self, accept_label: impl Into<glib::GString>) -> Self {
494 Self {
495 builder: self.builder.property("accept-label", accept_label.into()),
496 }
497 }
498
499 #[cfg(feature = "v4_14")]
500 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
501 pub fn modal(self, modal: bool) -> Self {
502 Self {
503 builder: self.builder.property("modal", modal),
504 }
505 }
506
507 #[cfg(feature = "v4_14")]
508 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
509 pub fn page_setup(self, page_setup: &PageSetup) -> Self {
510 Self {
511 builder: self.builder.property("page-setup", page_setup.clone()),
512 }
513 }
514
515 #[cfg(feature = "v4_14")]
516 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
517 pub fn print_settings(self, print_settings: &PrintSettings) -> Self {
518 Self {
519 builder: self
520 .builder
521 .property("print-settings", print_settings.clone()),
522 }
523 }
524
525 #[cfg(feature = "v4_14")]
526 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
527 pub fn title(self, title: impl Into<glib::GString>) -> Self {
528 Self {
529 builder: self.builder.property("title", title.into()),
530 }
531 }
532
533 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
536 pub fn build(self) -> PrintDialog {
537 assert_initialized_main_thread!();
538 self.builder.build()
539 }
540}