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