1use warnings;
2use strict;
3use Test::More tests => 23;
4use Glib qw(TRUE FALSE);    # To get TRUE and FALSE
5use Gtk3 -init;             # Could just call init separately
6use Image::Sane ':all';     # To get SANE_* enums
7
8BEGIN {
9    use Gscan2pdf::Dialog::Scan::Image_Sane;
10}
11
12#########################
13
14my $window = Gtk3::Window->new;
15
16Gscan2pdf::Translation::set_domain('gscan2pdf');
17use Log::Log4perl qw(:easy);
18Log::Log4perl->easy_init($WARN);
19my $logger = Log::Log4perl::get_logger;
20Gscan2pdf::Frontend::Image_Sane->setup($logger);
21
22my $dialog = Gscan2pdf::Dialog::Scan::Image_Sane->new(
23    title           => 'title',
24    'transient-for' => $window,
25    'logger'        => $logger
26);
27
28$dialog->set(
29    'paper-formats',
30    {
31        new => {
32            l => 0,
33            y => 10,
34            x => 10,
35            t => 0,
36        }
37    }
38);
39
40$dialog->set( 'num-pages', 2 );
41
42my $profile_changes = 0;
43my ( $signal, $signal2 );
44$signal = $dialog->signal_connect(
45    'reloaded-scan-options' => sub {
46        $dialog->signal_handler_disconnect($signal);
47
48        my $options = $dialog->get('available-scan-options');
49
50        # v1.3.7 had the bug that profiles were not being saved properly,
51        # due to the profiles not being cloned in the set and get routines
52
53        # need a new main loop to avoid nesting
54        my $loop1 = Glib::MainLoop->new;
55        $signal = $dialog->signal_connect(
56            'changed-scan-option' => sub {
57                $loop1->quit;
58            }
59        );
60        $dialog->set_option( $options->by_name('tl-x'), 10 );
61        $loop1->run;
62
63        my $loop2 = Glib::MainLoop->new;
64        $signal = $dialog->signal_connect(
65            'changed-scan-option' => sub {
66                $loop2->quit;
67            }
68        );
69        $dialog->set_option( $options->by_name('tl-y'), 10 );
70        $loop2->run;
71
72        $dialog->save_current_profile('profile 1');
73        is_deeply(
74            $dialog->{profiles}{'profile 1'}->get_data,
75            {
76                backend => [
77                    {
78                        'tl-x' => '10'
79                    },
80                    {
81                        'tl-y' => '10'
82                    },
83                ]
84            },
85            'applied 1st profile'
86        );
87        is( $dialog->get('profile'),
88            'profile 1', 'saving current profile sets profile' );
89
90        my $loop3 = Glib::MainLoop->new;
91        $signal = $dialog->signal_connect(
92            'changed-scan-option' => sub {
93                $loop3->quit;
94            }
95        );
96        $dialog->set_option( $options->by_name('tl-x'), 20 );
97        $loop3->run;
98
99        my $loop4 = Glib::MainLoop->new;
100        $signal = $dialog->signal_connect(
101            'changed-scan-option' => sub {
102
103                #                $flag = TRUE;
104                $loop4->quit;
105            }
106        );
107        $dialog->set_option( $options->by_name('tl-y'), 20 );
108        $loop4->run;
109
110        $dialog->save_current_profile('profile 2');
111        is_deeply(
112            $dialog->{profiles}{'profile 2'}->get_data,
113            {
114                backend => [
115                    {
116                        'tl-x' => '20'
117                    },
118                    {
119                        'tl-y' => '20'
120                    },
121                ]
122            },
123            'applied 2nd profile'
124        );
125        is_deeply(
126            $dialog->{profiles}{'profile 1'}->get_data,
127            {
128                backend => [
129                    {
130                        'tl-x' => '10'
131                    },
132                    {
133                        'tl-y' => '10'
134                    },
135                ]
136            },
137            'applied 2nd profile without affecting 1st'
138        );
139
140        $dialog->remove_profile('profile 1');
141        is_deeply(
142            $dialog->{profiles}{'profile 2'}->get_data,
143            {
144                backend => [
145                    {
146                        'tl-x' => '20'
147                    },
148                    {
149                        'tl-y' => '20'
150                    },
151                ]
152            },
153            'remove_profile()'
154        );
155
156        is $options->by_name('source')->{val}, 'Flatbed',
157          'source defaults to Flatbed';
158        is $dialog->get('num-pages'), 1,
159          'allow-batch-flatbed should force num-pages';
160        is $dialog->{framen}->is_sensitive, FALSE, 'num-page gui ghosted';
161        $dialog->set( 'num-pages', 2 );
162        is $dialog->get('num-pages'), 1,
163          'allow-batch-flatbed should force num-pages2';
164        ok $options->flatbed_selected, 'flatbed_selected() via value';
165
166        is $dialog->{vboxx}->get_visible, FALSE,
167          'flatbed, so hide vbox for page numbering';
168
169        $dialog->set( 'allow-batch-flatbed', TRUE );
170        $dialog->set( 'num-pages',           2 );
171        $signal = $dialog->signal_connect(
172            'changed-num-pages' => sub {
173                $dialog->signal_handler_disconnect($signal);
174                is $dialog->get('num-pages'), 1,
175                  'allow-batch-flatbed should force num-pages3';
176                is $dialog->{framen}->is_sensitive, FALSE,
177                  'num-page gui ghosted2';
178            }
179        );
180        $dialog->set( 'allow-batch-flatbed', FALSE );
181
182        # need a new main loop to avoid nesting
183        my $loop5 = Glib::MainLoop->new;
184        is $dialog->get('adf-defaults-scan-all-pages'), 1,
185          'default adf-defaults-scan-all-pages';
186        $signal = $dialog->signal_connect(
187            'changed-scan-option' => sub {
188                my ( $widget, $option, $value ) = @_;
189                if ( $option eq 'source' ) {
190                    $dialog->signal_handler_disconnect($signal);
191                    is $dialog->get('num-pages'), 0,
192                      'adf-defaults-scan-all-pages should force num-pages';
193                    is $options->flatbed_selected, FALSE,
194                      'not flatbed_selected() via value';
195                    $loop5->quit;
196                }
197            }
198        );
199        $dialog->set_option( $options->by_name('source'),
200            'Automatic Document Feeder' );
201        $loop5->run;
202
203        # need a new main loop to avoid nesting
204        my $loop6 = Glib::MainLoop->new;
205        $signal = $dialog->signal_connect(
206            'changed-scan-option' => sub {
207                my ( $widget, $option, $value ) = @_;
208                $dialog->signal_handler_disconnect($signal);
209                $dialog->set( 'num-pages', 1 );
210                $loop6->quit;
211            }
212        );
213        $dialog->set_option( $options->by_name('source'), 'Flatbed' );
214        $loop6->run;
215
216        # need a new main loop to avoid nesting
217        my $loop7 = Glib::MainLoop->new;
218        $signal = $dialog->signal_connect(
219            'changed-scan-option' => sub {
220                my ( $widget, $option, $value ) = @_;
221                $dialog->signal_handler_disconnect($signal);
222                $dialog->signal_handler_disconnect($signal2);
223                fail 'should not try to set invalid option';
224                $loop7->quit;
225            }
226        );
227        $signal2 = $dialog->signal_connect(
228            'changed-current-scan-options' => sub {
229                $dialog->signal_handler_disconnect($signal);
230                $dialog->signal_handler_disconnect($signal2);
231                $loop7->quit;
232            }
233        );
234        $dialog->set_current_scan_options(
235            Gscan2pdf::Scanner::Profile->new_from_data(
236                {
237                    'backend' => [ { 'mode' => 'Lineart' } ]
238                }
239            )
240        );
241        $loop7->run;
242
243        # need a new main loop to avoid nesting
244        my $loop8 = Glib::MainLoop->new;
245        $signal = $dialog->signal_connect(
246            'changed-scan-option' => sub {
247                my ( $widget, $option, $value ) = @_;
248                $dialog->signal_handler_disconnect($signal);
249                $dialog->signal_handler_disconnect($signal2);
250                fail 'should not try to set option if value already correct';
251                $loop8->quit;
252            }
253        );
254        $signal2 = $dialog->signal_connect(
255            'changed-current-scan-options' => sub {
256                $dialog->signal_handler_disconnect($signal);
257                $dialog->signal_handler_disconnect($signal2);
258                $loop8->quit;
259            }
260        );
261        Glib::Idle->add(
262            sub {
263                $dialog->set_current_scan_options(
264                    Gscan2pdf::Scanner::Profile->new_from_data(
265                        {
266                            'backend' => [ { 'mode' => 'Gray' } ]
267                        }
268                    )
269                );
270            }
271        );
272        $loop8->run;
273
274        my $loop9 = Glib::MainLoop->new;
275        $dialog->set( 'adf-defaults-scan-all-pages', 0 );
276        $signal = $dialog->signal_connect(
277            'changed-scan-option' => sub {
278                my ( $widget, $option, $value ) = @_;
279                $dialog->signal_handler_disconnect($signal);
280                is $dialog->get('num-pages'), 1,
281                  'adf-defaults-scan-all-pages should force num-pages 2';
282
283                is $dialog->{vboxx}->get_visible, TRUE,
284                  'simplex ADF, so show vbox for page numbering';
285
286                $loop9->quit;
287            }
288        );
289        $dialog->set_option( $options->by_name('source'),
290            'Automatic Document Feeder' );
291        $loop9->run;
292
293        # bug in 2.5.3 where setting paper via default options only
294        # set combobox without setting options
295        my $loop10 = Glib::MainLoop->new;
296        $signal = $dialog->signal_connect(
297            'changed-paper' => sub {
298                $dialog->signal_handler_disconnect($signal);
299                is_deeply(
300                    $dialog->get('current-scan-options')->get_data,
301                    {
302                        backend => [
303                            {
304                                'tl-x' => '0'
305                            },
306                            {
307                                'tl-y' => '0'
308                            },
309                            {
310                                'br-x' => '10'
311                            },
312                            {
313                                'br-y' => '10'
314                            },
315                        ],
316                        frontend => {
317                            'paper' => 'new'
318                        },
319                    },
320                    'set paper with conflicting options'
321                );
322                $loop10->quit;
323            }
324        );
325        $dialog->set_current_scan_options(
326            Gscan2pdf::Scanner::Profile->new_from_data(
327                {
328                    backend => [
329                        {
330                            'tl-x' => '20'
331                        },
332                        {
333                            'tl-y' => '20'
334                        },
335                    ],
336                    frontend => {
337                        'paper' => 'new'
338                    },
339                },
340            )
341        );
342        $loop10->run;
343
344        # bug previous to v2.1.7 where having having set double sided and
345        # reverse, and then switched from ADF to flatbed, clicking scan produced
346        # the error message that the facing pages should be scanned first
347        $loop10 = Glib::MainLoop->new;
348        $dialog->set( 'side-to-scan', 'reverse' );
349        $signal = $dialog->signal_connect(
350            'changed-scan-option' => sub {
351                my ( $widget, $option, $value ) = @_;
352                $dialog->signal_handler_disconnect($signal);
353
354                # if allow-batch-flatbed = FALSE
355                is $dialog->get('sided'), 'single',
356                  'selecting flatbed forces single sided';
357
358                $loop10->quit;
359            }
360        );
361        $dialog->set_option( $options->by_name('source'), 'Flatbed' );
362        $loop10->run;
363
364        # bug previous to v2.6.7 where changing a geometry option, thus setting
365        # paper to Manual/undef was not respected when reloading options
366        $signal = $dialog->signal_connect(
367            'changed-scan-option' => sub {
368                my ( $widget, $option, $value ) = @_;
369                $dialog->set_paper;
370            }
371        );
372        $signal = $dialog->signal_connect(
373            'changed-paper' => sub {
374                $dialog->signal_handler_disconnect($signal);
375                is_deeply $dialog->get('current-scan-options')->get_data,
376                  {
377                    backend => [
378                        {
379                            'tl-x' => '0'
380                        },
381                        {
382                            'tl-y' => '0'
383                        },
384                        {
385                            'br-x' => '10'
386                        },
387                        {
388                            'source' => 'Flatbed'
389                        },
390                        {
391                            'br-y' => '9'
392                        },
393                    ],
394                  },
395                  'set Manual paper';
396
397                Gtk3->main_quit;
398            }
399        );
400        $dialog->set_option( $options->by_name('br-y'), 9 );
401    }
402);
403$dialog->set( 'device', 'test' );
404$dialog->scan_options;
405Gtk3->main;
406
407is( $dialog->{combobp}->get_num_rows,
408    3, 'available paper reapplied after setting/changing device' );
409is( $dialog->{combobp}->get_active_text,
410    'Manual', 'paper combobox has a value' );
411
412Gscan2pdf::Frontend::Image_Sane->quit;
413__END__
414