gtk4/subclass/
print_operation.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for subclassing [`PrintOperation`](crate::PrintOperation).
5
6use glib::translate::*;
7
8use crate::{
9    ffi, prelude::*, subclass::prelude::*, PageSetup, PrintContext, PrintOperation,
10    PrintOperationPreview, PrintOperationResult, PrintSettings, Widget, Window,
11};
12
13pub trait PrintOperationImpl: PrintOperationImplExt + PrintOperationPreviewImpl {
14    /// Signal emitted after the user has finished changing
15    ///    print settings in the dialog, before the actual rendering starts.
16    fn begin_print(&self, context: &PrintContext) {
17        self.parent_begin_print(context)
18    }
19
20    /// Signal emitted when displaying the print dialog.
21    fn create_custom_widget(&self) -> Option<Widget> {
22        self.parent_create_custom_widget()
23    }
24
25    /// Signal emitted right before “begin-print” if
26    ///    you added a custom widget in the “create-custom-widget” handler.
27    fn custom_widget_apply(&self, widget: &Widget) {
28        self.parent_custom_widget_apply(widget)
29    }
30
31    /// Signal emitted when the print operation run has finished
32    ///    doing everything required for printing.
33    fn done(&self, result: PrintOperationResult) {
34        self.parent_done(result)
35    }
36
37    /// Signal emitted for every page that is printed.
38    fn draw_page(&self, context: &PrintContext, page_nr: i32) {
39        self.parent_draw_page(context, page_nr)
40    }
41
42    /// Signal emitted after all pages have been rendered.
43    fn end_print(&self, context: &PrintContext) {
44        self.parent_end_print(context)
45    }
46
47    /// Signal emitted after the “begin-print” signal, but
48    ///    before the actual rendering starts.
49    fn paginate(&self, context: &PrintContext) -> bool {
50        self.parent_paginate(context)
51    }
52
53    /// Signal emitted when a preview is requested from the
54    ///    native dialog.
55    fn preview(
56        &self,
57        preview: &PrintOperationPreview,
58        context: &PrintContext,
59        parent: Option<&Window>,
60    ) -> bool {
61        self.parent_preview(preview, context, parent)
62    }
63
64    /// Emitted once for every page that is printed,
65    ///    to give the application a chance to modify the page setup.
66    fn request_page_setup(&self, context: &PrintContext, page_nr: i32, setup: &PageSetup) {
67        self.parent_request_page_setup(context, page_nr, setup)
68    }
69
70    /// Emitted at between the various phases of the print
71    ///    operation.
72    fn status_changed(&self) {
73        self.parent_status_changed()
74    }
75
76    /// Emitted after change of selected printer.
77    fn update_custom_widget(&self, widget: &Widget, setup: &PageSetup, settings: &PrintSettings) {
78        self.parent_update_custom_widget(widget, setup, settings)
79    }
80}
81
82mod sealed {
83    pub trait Sealed {}
84    impl<T: super::PrintOperationImplExt> Sealed for T {}
85}
86
87pub trait PrintOperationImplExt: sealed::Sealed + ObjectSubclass {
88    fn parent_begin_print(&self, context: &PrintContext) {
89        unsafe {
90            let data = Self::type_data();
91            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
92            if let Some(f) = (*parent_class).begin_print {
93                f(
94                    self.obj()
95                        .unsafe_cast_ref::<PrintOperation>()
96                        .to_glib_none()
97                        .0,
98                    context.to_glib_none().0,
99                )
100            }
101        }
102    }
103
104    fn parent_create_custom_widget(&self) -> Option<Widget> {
105        unsafe {
106            let data = Self::type_data();
107            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
108            if let Some(f) = (*parent_class).create_custom_widget {
109                let ret = f(self
110                    .obj()
111                    .unsafe_cast_ref::<PrintOperation>()
112                    .to_glib_none()
113                    .0);
114                Some(from_glib_full(ret))
115            } else {
116                None
117            }
118        }
119    }
120
121    fn parent_custom_widget_apply(&self, widget: &Widget) {
122        unsafe {
123            let data = Self::type_data();
124            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
125            if let Some(f) = (*parent_class).custom_widget_apply {
126                f(
127                    self.obj()
128                        .unsafe_cast_ref::<PrintOperation>()
129                        .to_glib_none()
130                        .0,
131                    widget.to_glib_none().0,
132                );
133            }
134        }
135    }
136
137    fn parent_done(&self, result: PrintOperationResult) {
138        unsafe {
139            let data = Self::type_data();
140            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
141            if let Some(f) = (*parent_class).done {
142                f(
143                    self.obj()
144                        .unsafe_cast_ref::<PrintOperation>()
145                        .to_glib_none()
146                        .0,
147                    result.into_glib(),
148                );
149            }
150        }
151    }
152
153    fn parent_draw_page(&self, context: &PrintContext, page_nr: i32) {
154        unsafe {
155            let data = Self::type_data();
156            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
157            if let Some(f) = (*parent_class).draw_page {
158                f(
159                    self.obj()
160                        .unsafe_cast_ref::<PrintOperation>()
161                        .to_glib_none()
162                        .0,
163                    context.to_glib_none().0,
164                    page_nr,
165                );
166            }
167        }
168    }
169
170    fn parent_end_print(&self, context: &PrintContext) {
171        unsafe {
172            let data = Self::type_data();
173            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
174            if let Some(f) = (*parent_class).end_print {
175                f(
176                    self.obj()
177                        .unsafe_cast_ref::<PrintOperation>()
178                        .to_glib_none()
179                        .0,
180                    context.to_glib_none().0,
181                );
182            }
183        }
184    }
185
186    // Returns true if pagination is complete
187    fn parent_paginate(&self, context: &PrintContext) -> bool {
188        unsafe {
189            let data = Self::type_data();
190            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
191            if let Some(f) = (*parent_class).paginate {
192                from_glib(f(
193                    self.obj()
194                        .unsafe_cast_ref::<PrintOperation>()
195                        .to_glib_none()
196                        .0,
197                    context.to_glib_none().0,
198                ))
199            } else {
200                // assume the number of pages is already set & pagination is not needed
201                true
202            }
203        }
204    }
205
206    // true if the listener wants to take over control of the preview.
207    fn parent_preview(
208        &self,
209        preview: &PrintOperationPreview,
210        context: &PrintContext,
211        parent: Option<&Window>,
212    ) -> bool {
213        unsafe {
214            let data = Self::type_data();
215            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
216            if let Some(f) = (*parent_class).preview {
217                from_glib(f(
218                    self.obj()
219                        .unsafe_cast_ref::<PrintOperation>()
220                        .to_glib_none()
221                        .0,
222                    preview.to_glib_none().0,
223                    context.to_glib_none().0,
224                    parent.to_glib_none().0,
225                ))
226            } else {
227                // Let the default PrintOperationPreview be used
228                false
229            }
230        }
231    }
232
233    fn parent_request_page_setup(&self, context: &PrintContext, page_nr: i32, setup: &PageSetup) {
234        unsafe {
235            let data = Self::type_data();
236            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
237            if let Some(f) = (*parent_class).request_page_setup {
238                f(
239                    self.obj()
240                        .unsafe_cast_ref::<PrintOperation>()
241                        .to_glib_none()
242                        .0,
243                    context.to_glib_none().0,
244                    page_nr,
245                    setup.to_glib_none().0,
246                );
247            }
248        }
249    }
250
251    fn parent_status_changed(&self) {
252        unsafe {
253            let data = Self::type_data();
254            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
255            if let Some(f) = (*parent_class).status_changed {
256                f(self
257                    .obj()
258                    .unsafe_cast_ref::<PrintOperation>()
259                    .to_glib_none()
260                    .0);
261            }
262        }
263    }
264
265    fn parent_update_custom_widget(
266        &self,
267        widget: &Widget,
268        setup: &PageSetup,
269        settings: &PrintSettings,
270    ) {
271        unsafe {
272            let data = Self::type_data();
273            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkPrintOperationClass;
274            if let Some(f) = (*parent_class).update_custom_widget {
275                f(
276                    self.obj()
277                        .unsafe_cast_ref::<PrintOperation>()
278                        .to_glib_none()
279                        .0,
280                    widget.to_glib_none().0,
281                    setup.to_glib_none().0,
282                    settings.to_glib_none().0,
283                );
284            }
285        }
286    }
287}
288
289impl<T: PrintOperationImpl> PrintOperationImplExt for T {}
290
291unsafe impl<T: PrintOperationImpl> IsSubclassable<T> for PrintOperation {
292    fn class_init(class: &mut glib::Class<Self>) {
293        Self::parent_class_init::<T>(class);
294
295        let klass = class.as_mut();
296        klass.begin_print = Some(print_operation_begin_print::<T>);
297        klass.create_custom_widget = Some(print_operation_create_custom_widget::<T>);
298        klass.custom_widget_apply = Some(print_operation_custom_widget_apply::<T>);
299        klass.done = Some(print_operation_done::<T>);
300        klass.draw_page = Some(print_operation_draw_page::<T>);
301        klass.end_print = Some(print_operation_end_print::<T>);
302        klass.request_page_setup = Some(print_operation_request_page_setup::<T>);
303        klass.status_changed = Some(print_operation_status_changed::<T>);
304        klass.update_custom_widget = Some(print_operation_update_custom_widget::<T>);
305    }
306}
307
308unsafe extern "C" fn print_operation_begin_print<T: PrintOperationImpl>(
309    ptr: *mut ffi::GtkPrintOperation,
310    contextptr: *mut ffi::GtkPrintContext,
311) {
312    let instance = &*(ptr as *mut T::Instance);
313    let imp = instance.imp();
314    let context: Borrowed<PrintContext> = from_glib_borrow(contextptr);
315
316    imp.begin_print(&context)
317}
318
319unsafe extern "C" fn print_operation_create_custom_widget<T: PrintOperationImpl>(
320    ptr: *mut ffi::GtkPrintOperation,
321) -> *mut ffi::GtkWidget {
322    let instance = &*(ptr as *mut T::Instance);
323    let imp = instance.imp();
324
325    imp.create_custom_widget().into_glib_ptr()
326}
327
328unsafe extern "C" fn print_operation_custom_widget_apply<T: PrintOperationImpl>(
329    ptr: *mut ffi::GtkPrintOperation,
330    widgetptr: *mut ffi::GtkWidget,
331) {
332    let instance = &*(ptr as *mut T::Instance);
333    let imp = instance.imp();
334    let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
335
336    imp.custom_widget_apply(&widget)
337}
338
339unsafe extern "C" fn print_operation_done<T: PrintOperationImpl>(
340    ptr: *mut ffi::GtkPrintOperation,
341    resultptr: ffi::GtkPrintOperationResult,
342) {
343    let instance = &*(ptr as *mut T::Instance);
344    let imp = instance.imp();
345
346    imp.done(from_glib(resultptr))
347}
348
349unsafe extern "C" fn print_operation_draw_page<T: PrintOperationImpl>(
350    ptr: *mut ffi::GtkPrintOperation,
351    contextptr: *mut ffi::GtkPrintContext,
352    page_nr: i32,
353) {
354    let instance = &*(ptr as *mut T::Instance);
355    let imp = instance.imp();
356    let context: Borrowed<PrintContext> = from_glib_borrow(contextptr);
357
358    imp.draw_page(&context, page_nr)
359}
360
361unsafe extern "C" fn print_operation_end_print<T: PrintOperationImpl>(
362    ptr: *mut ffi::GtkPrintOperation,
363    contextptr: *mut ffi::GtkPrintContext,
364) {
365    let instance = &*(ptr as *mut T::Instance);
366    let imp = instance.imp();
367    let context: Borrowed<PrintContext> = from_glib_borrow(contextptr);
368
369    imp.end_print(&context)
370}
371
372unsafe extern "C" fn print_operation_request_page_setup<T: PrintOperationImpl>(
373    ptr: *mut ffi::GtkPrintOperation,
374    contextptr: *mut ffi::GtkPrintContext,
375    page_nr: i32,
376    setupptr: *mut ffi::GtkPageSetup,
377) {
378    let instance = &*(ptr as *mut T::Instance);
379    let imp = instance.imp();
380    let context: Borrowed<PrintContext> = from_glib_borrow(contextptr);
381    let setup: Borrowed<PageSetup> = from_glib_borrow(setupptr);
382
383    imp.request_page_setup(&context, page_nr, &setup)
384}
385
386unsafe extern "C" fn print_operation_status_changed<T: PrintOperationImpl>(
387    ptr: *mut ffi::GtkPrintOperation,
388) {
389    let instance = &*(ptr as *mut T::Instance);
390    let imp = instance.imp();
391
392    imp.status_changed()
393}
394
395unsafe extern "C" fn print_operation_update_custom_widget<T: PrintOperationImpl>(
396    ptr: *mut ffi::GtkPrintOperation,
397    widgetptr: *mut ffi::GtkWidget,
398    setupptr: *mut ffi::GtkPageSetup,
399    settingsptr: *mut ffi::GtkPrintSettings,
400) {
401    let instance = &*(ptr as *mut T::Instance);
402    let imp = instance.imp();
403    let widget: Borrowed<Widget> = from_glib_borrow(widgetptr);
404    let setup: Borrowed<PageSetup> = from_glib_borrow(setupptr);
405    let settings: Borrowed<PrintSettings> = from_glib_borrow(settingsptr);
406
407    imp.update_custom_widget(&widget, &setup, &settings)
408}