1use crate::{PageSetup, PrintSettings, PrintSetup, Window, ffi};
6use glib::{
7 prelude::*,
8 signal::{SignalHandlerId, connect_raw},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GtkPrintDialog")]
64 pub struct PrintDialog(Object<ffi::GtkPrintDialog, ffi::GtkPrintDialogClass>);
65
66 match fn {
67 type_ => || ffi::gtk_print_dialog_get_type(),
68 }
69}
70
71impl PrintDialog {
72 #[doc(alias = "gtk_print_dialog_new")]
78 pub fn new() -> PrintDialog {
79 assert_initialized_main_thread!();
80 unsafe { from_glib_full(ffi::gtk_print_dialog_new()) }
81 }
82
83 pub fn builder() -> PrintDialogBuilder {
88 PrintDialogBuilder::new()
89 }
90
91 #[doc(alias = "gtk_print_dialog_get_accept_label")]
98 #[doc(alias = "get_accept_label")]
99 #[doc(alias = "accept-label")]
100 pub fn accept_label(&self) -> glib::GString {
101 unsafe {
102 from_glib_none(ffi::gtk_print_dialog_get_accept_label(
103 self.to_glib_none().0,
104 ))
105 }
106 }
107
108 #[doc(alias = "gtk_print_dialog_get_modal")]
116 #[doc(alias = "get_modal")]
117 #[doc(alias = "modal")]
118 pub fn is_modal(&self) -> bool {
119 unsafe { from_glib(ffi::gtk_print_dialog_get_modal(self.to_glib_none().0)) }
120 }
121
122 #[doc(alias = "gtk_print_dialog_get_page_setup")]
128 #[doc(alias = "get_page_setup")]
129 #[doc(alias = "page-setup")]
130 pub fn page_setup(&self) -> Option<PageSetup> {
131 unsafe { from_glib_none(ffi::gtk_print_dialog_get_page_setup(self.to_glib_none().0)) }
132 }
133
134 #[doc(alias = "gtk_print_dialog_get_print_settings")]
140 #[doc(alias = "get_print_settings")]
141 #[doc(alias = "print-settings")]
142 pub fn print_settings(&self) -> Option<PrintSettings> {
143 unsafe {
144 from_glib_none(ffi::gtk_print_dialog_get_print_settings(
145 self.to_glib_none().0,
146 ))
147 }
148 }
149
150 #[doc(alias = "gtk_print_dialog_get_title")]
157 #[doc(alias = "get_title")]
158 pub fn title(&self) -> glib::GString {
159 unsafe { from_glib_none(ffi::gtk_print_dialog_get_title(self.to_glib_none().0)) }
160 }
161
162 #[doc(alias = "gtk_print_dialog_print")]
178 pub fn print<P: FnOnce(Result<gio::OutputStream, glib::Error>) + 'static>(
179 &self,
180 parent: Option<&impl IsA<Window>>,
181 setup: Option<&PrintSetup>,
182 cancellable: Option<&impl IsA<gio::Cancellable>>,
183 callback: P,
184 ) {
185 let main_context = glib::MainContext::ref_thread_default();
186 let is_main_context_owner = main_context.is_owner();
187 let has_acquired_main_context = (!is_main_context_owner)
188 .then(|| main_context.acquire().ok())
189 .flatten();
190 assert!(
191 is_main_context_owner || has_acquired_main_context.is_some(),
192 "Async operations only allowed if the thread is owning the MainContext"
193 );
194
195 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
196 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
197 unsafe extern "C" fn print_trampoline<
198 P: FnOnce(Result<gio::OutputStream, glib::Error>) + 'static,
199 >(
200 _source_object: *mut glib::gobject_ffi::GObject,
201 res: *mut gio::ffi::GAsyncResult,
202 user_data: glib::ffi::gpointer,
203 ) {
204 unsafe {
205 let mut error = std::ptr::null_mut();
206 let ret =
207 ffi::gtk_print_dialog_print_finish(_source_object as *mut _, res, &mut error);
208 let result = if error.is_null() {
209 Ok(from_glib_full(ret))
210 } else {
211 Err(from_glib_full(error))
212 };
213 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
214 Box_::from_raw(user_data as *mut _);
215 let callback: P = callback.into_inner();
216 callback(result);
217 }
218 }
219 let callback = print_trampoline::<P>;
220 unsafe {
221 ffi::gtk_print_dialog_print(
222 self.to_glib_none().0,
223 parent.map(|p| p.as_ref()).to_glib_none().0,
224 setup.to_glib_none().0,
225 cancellable.map(|p| p.as_ref()).to_glib_none().0,
226 Some(callback),
227 Box_::into_raw(user_data) as *mut _,
228 );
229 }
230 }
231
232 pub fn print_future(
233 &self,
234 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
235 setup: Option<&PrintSetup>,
236 ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::OutputStream, glib::Error>> + 'static>>
237 {
238 let parent = parent.map(ToOwned::to_owned);
239 let setup = setup.map(ToOwned::to_owned);
240 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
241 obj.print(
242 parent.as_ref().map(::std::borrow::Borrow::borrow),
243 setup.as_ref().map(::std::borrow::Borrow::borrow),
244 Some(cancellable),
245 move |res| {
246 send.resolve(res);
247 },
248 );
249 }))
250 }
251
252 #[doc(alias = "gtk_print_dialog_print_file")]
268 pub fn print_file<P: FnOnce(Result<(), glib::Error>) + 'static>(
269 &self,
270 parent: Option<&impl IsA<Window>>,
271 setup: Option<&PrintSetup>,
272 file: &impl IsA<gio::File>,
273 cancellable: Option<&impl IsA<gio::Cancellable>>,
274 callback: P,
275 ) {
276 let main_context = glib::MainContext::ref_thread_default();
277 let is_main_context_owner = main_context.is_owner();
278 let has_acquired_main_context = (!is_main_context_owner)
279 .then(|| main_context.acquire().ok())
280 .flatten();
281 assert!(
282 is_main_context_owner || has_acquired_main_context.is_some(),
283 "Async operations only allowed if the thread is owning the MainContext"
284 );
285
286 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
287 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
288 unsafe extern "C" fn print_file_trampoline<P: FnOnce(Result<(), glib::Error>) + 'static>(
289 _source_object: *mut glib::gobject_ffi::GObject,
290 res: *mut gio::ffi::GAsyncResult,
291 user_data: glib::ffi::gpointer,
292 ) {
293 unsafe {
294 let mut error = std::ptr::null_mut();
295 ffi::gtk_print_dialog_print_file_finish(_source_object as *mut _, res, &mut error);
296 let result = if error.is_null() {
297 Ok(())
298 } else {
299 Err(from_glib_full(error))
300 };
301 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
302 Box_::from_raw(user_data as *mut _);
303 let callback: P = callback.into_inner();
304 callback(result);
305 }
306 }
307 let callback = print_file_trampoline::<P>;
308 unsafe {
309 ffi::gtk_print_dialog_print_file(
310 self.to_glib_none().0,
311 parent.map(|p| p.as_ref()).to_glib_none().0,
312 setup.to_glib_none().0,
313 file.as_ref().to_glib_none().0,
314 cancellable.map(|p| p.as_ref()).to_glib_none().0,
315 Some(callback),
316 Box_::into_raw(user_data) as *mut _,
317 );
318 }
319 }
320
321 pub fn print_file_future(
322 &self,
323 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
324 setup: Option<&PrintSetup>,
325 file: &(impl IsA<gio::File> + Clone + 'static),
326 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
327 let parent = parent.map(ToOwned::to_owned);
328 let setup = setup.map(ToOwned::to_owned);
329 let file = file.clone();
330 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
331 obj.print_file(
332 parent.as_ref().map(::std::borrow::Borrow::borrow),
333 setup.as_ref().map(::std::borrow::Borrow::borrow),
334 &file,
335 Some(cancellable),
336 move |res| {
337 send.resolve(res);
338 },
339 );
340 }))
341 }
342
343 #[doc(alias = "gtk_print_dialog_set_accept_label")]
349 #[doc(alias = "accept-label")]
350 pub fn set_accept_label(&self, accept_label: &str) {
351 unsafe {
352 ffi::gtk_print_dialog_set_accept_label(
353 self.to_glib_none().0,
354 accept_label.to_glib_none().0,
355 );
356 }
357 }
358
359 #[doc(alias = "gtk_print_dialog_set_modal")]
365 #[doc(alias = "modal")]
366 pub fn set_modal(&self, modal: bool) {
367 unsafe {
368 ffi::gtk_print_dialog_set_modal(self.to_glib_none().0, modal.into_glib());
369 }
370 }
371
372 #[doc(alias = "gtk_print_dialog_set_page_setup")]
376 #[doc(alias = "page-setup")]
377 pub fn set_page_setup(&self, page_setup: &PageSetup) {
378 unsafe {
379 ffi::gtk_print_dialog_set_page_setup(
380 self.to_glib_none().0,
381 page_setup.to_glib_none().0,
382 );
383 }
384 }
385
386 #[doc(alias = "gtk_print_dialog_set_print_settings")]
390 #[doc(alias = "print-settings")]
391 pub fn set_print_settings(&self, print_settings: &PrintSettings) {
392 unsafe {
393 ffi::gtk_print_dialog_set_print_settings(
394 self.to_glib_none().0,
395 print_settings.to_glib_none().0,
396 );
397 }
398 }
399
400 #[doc(alias = "gtk_print_dialog_set_title")]
404 #[doc(alias = "title")]
405 pub fn set_title(&self, title: &str) {
406 unsafe {
407 ffi::gtk_print_dialog_set_title(self.to_glib_none().0, title.to_glib_none().0);
408 }
409 }
410
411 #[doc(alias = "gtk_print_dialog_setup")]
430 pub fn setup<P: FnOnce(Result<PrintSetup, glib::Error>) + 'static>(
431 &self,
432 parent: Option<&impl IsA<Window>>,
433 cancellable: Option<&impl IsA<gio::Cancellable>>,
434 callback: P,
435 ) {
436 let main_context = glib::MainContext::ref_thread_default();
437 let is_main_context_owner = main_context.is_owner();
438 let has_acquired_main_context = (!is_main_context_owner)
439 .then(|| main_context.acquire().ok())
440 .flatten();
441 assert!(
442 is_main_context_owner || has_acquired_main_context.is_some(),
443 "Async operations only allowed if the thread is owning the MainContext"
444 );
445
446 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
447 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
448 unsafe extern "C" fn setup_trampoline<
449 P: FnOnce(Result<PrintSetup, glib::Error>) + 'static,
450 >(
451 _source_object: *mut glib::gobject_ffi::GObject,
452 res: *mut gio::ffi::GAsyncResult,
453 user_data: glib::ffi::gpointer,
454 ) {
455 unsafe {
456 let mut error = std::ptr::null_mut();
457 let ret =
458 ffi::gtk_print_dialog_setup_finish(_source_object as *mut _, res, &mut error);
459 let result = if error.is_null() {
460 Ok(from_glib_full(ret))
461 } else {
462 Err(from_glib_full(error))
463 };
464 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
465 Box_::from_raw(user_data as *mut _);
466 let callback: P = callback.into_inner();
467 callback(result);
468 }
469 }
470 let callback = setup_trampoline::<P>;
471 unsafe {
472 ffi::gtk_print_dialog_setup(
473 self.to_glib_none().0,
474 parent.map(|p| p.as_ref()).to_glib_none().0,
475 cancellable.map(|p| p.as_ref()).to_glib_none().0,
476 Some(callback),
477 Box_::into_raw(user_data) as *mut _,
478 );
479 }
480 }
481
482 pub fn setup_future(
483 &self,
484 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
485 ) -> Pin<Box_<dyn std::future::Future<Output = Result<PrintSetup, glib::Error>> + 'static>>
486 {
487 let parent = parent.map(ToOwned::to_owned);
488 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
489 obj.setup(
490 parent.as_ref().map(::std::borrow::Borrow::borrow),
491 Some(cancellable),
492 move |res| {
493 send.resolve(res);
494 },
495 );
496 }))
497 }
498
499 #[cfg(feature = "v4_14")]
500 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
501 #[doc(alias = "accept-label")]
502 pub fn connect_accept_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
503 unsafe extern "C" fn notify_accept_label_trampoline<F: Fn(&PrintDialog) + 'static>(
504 this: *mut ffi::GtkPrintDialog,
505 _param_spec: glib::ffi::gpointer,
506 f: glib::ffi::gpointer,
507 ) {
508 unsafe {
509 let f: &F = &*(f as *const F);
510 f(&from_glib_borrow(this))
511 }
512 }
513 unsafe {
514 let f: Box_<F> = Box_::new(f);
515 connect_raw(
516 self.as_ptr() as *mut _,
517 c"notify::accept-label".as_ptr() as *const _,
518 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
519 notify_accept_label_trampoline::<F> as *const (),
520 )),
521 Box_::into_raw(f),
522 )
523 }
524 }
525
526 #[cfg(feature = "v4_14")]
527 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
528 #[doc(alias = "modal")]
529 pub fn connect_modal_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
530 unsafe extern "C" fn notify_modal_trampoline<F: Fn(&PrintDialog) + 'static>(
531 this: *mut ffi::GtkPrintDialog,
532 _param_spec: glib::ffi::gpointer,
533 f: glib::ffi::gpointer,
534 ) {
535 unsafe {
536 let f: &F = &*(f as *const F);
537 f(&from_glib_borrow(this))
538 }
539 }
540 unsafe {
541 let f: Box_<F> = Box_::new(f);
542 connect_raw(
543 self.as_ptr() as *mut _,
544 c"notify::modal".as_ptr() as *const _,
545 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
546 notify_modal_trampoline::<F> as *const (),
547 )),
548 Box_::into_raw(f),
549 )
550 }
551 }
552
553 #[cfg(feature = "v4_14")]
554 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
555 #[doc(alias = "page-setup")]
556 pub fn connect_page_setup_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
557 unsafe extern "C" fn notify_page_setup_trampoline<F: Fn(&PrintDialog) + 'static>(
558 this: *mut ffi::GtkPrintDialog,
559 _param_spec: glib::ffi::gpointer,
560 f: glib::ffi::gpointer,
561 ) {
562 unsafe {
563 let f: &F = &*(f as *const F);
564 f(&from_glib_borrow(this))
565 }
566 }
567 unsafe {
568 let f: Box_<F> = Box_::new(f);
569 connect_raw(
570 self.as_ptr() as *mut _,
571 c"notify::page-setup".as_ptr() as *const _,
572 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
573 notify_page_setup_trampoline::<F> as *const (),
574 )),
575 Box_::into_raw(f),
576 )
577 }
578 }
579
580 #[cfg(feature = "v4_14")]
581 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
582 #[doc(alias = "print-settings")]
583 pub fn connect_print_settings_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
584 unsafe extern "C" fn notify_print_settings_trampoline<F: Fn(&PrintDialog) + 'static>(
585 this: *mut ffi::GtkPrintDialog,
586 _param_spec: glib::ffi::gpointer,
587 f: glib::ffi::gpointer,
588 ) {
589 unsafe {
590 let f: &F = &*(f as *const F);
591 f(&from_glib_borrow(this))
592 }
593 }
594 unsafe {
595 let f: Box_<F> = Box_::new(f);
596 connect_raw(
597 self.as_ptr() as *mut _,
598 c"notify::print-settings".as_ptr() as *const _,
599 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
600 notify_print_settings_trampoline::<F> as *const (),
601 )),
602 Box_::into_raw(f),
603 )
604 }
605 }
606
607 #[cfg(feature = "v4_14")]
608 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
609 #[doc(alias = "title")]
610 pub fn connect_title_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
611 unsafe extern "C" fn notify_title_trampoline<F: Fn(&PrintDialog) + 'static>(
612 this: *mut ffi::GtkPrintDialog,
613 _param_spec: glib::ffi::gpointer,
614 f: glib::ffi::gpointer,
615 ) {
616 unsafe {
617 let f: &F = &*(f as *const F);
618 f(&from_glib_borrow(this))
619 }
620 }
621 unsafe {
622 let f: Box_<F> = Box_::new(f);
623 connect_raw(
624 self.as_ptr() as *mut _,
625 c"notify::title".as_ptr() as *const _,
626 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
627 notify_title_trampoline::<F> as *const (),
628 )),
629 Box_::into_raw(f),
630 )
631 }
632 }
633}
634
635#[cfg(feature = "v4_14")]
636#[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
637impl Default for PrintDialog {
638 fn default() -> Self {
639 Self::new()
640 }
641}
642
643#[must_use = "The builder must be built to be used"]
648pub struct PrintDialogBuilder {
649 builder: glib::object::ObjectBuilder<'static, PrintDialog>,
650}
651
652impl PrintDialogBuilder {
653 fn new() -> Self {
654 Self {
655 builder: glib::object::Object::builder(),
656 }
657 }
658
659 #[cfg(feature = "v4_14")]
662 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
663 pub fn accept_label(self, accept_label: impl Into<glib::GString>) -> Self {
664 Self {
665 builder: self.builder.property("accept-label", accept_label.into()),
666 }
667 }
668
669 #[cfg(feature = "v4_14")]
671 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
672 pub fn modal(self, modal: bool) -> Self {
673 Self {
674 builder: self.builder.property("modal", modal),
675 }
676 }
677
678 #[cfg(feature = "v4_14")]
680 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
681 pub fn page_setup(self, page_setup: &PageSetup) -> Self {
682 Self {
683 builder: self.builder.property("page-setup", page_setup.clone()),
684 }
685 }
686
687 #[cfg(feature = "v4_14")]
689 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
690 pub fn print_settings(self, print_settings: &PrintSettings) -> Self {
691 Self {
692 builder: self
693 .builder
694 .property("print-settings", print_settings.clone()),
695 }
696 }
697
698 #[cfg(feature = "v4_14")]
701 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
702 pub fn title(self, title: impl Into<glib::GString>) -> Self {
703 Self {
704 builder: self.builder.property("title", title.into()),
705 }
706 }
707
708 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
711 pub fn build(self) -> PrintDialog {
712 assert_initialized_main_thread!();
713 self.builder.build()
714 }
715}