Skip to main content

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