1/*
2 * Copyright (C) 2009-2017 Canonical Ltd.
3 * Author: Robert Ancell <robert.ancell@canonical.com>,
4 *         Eduard Gotwig <g@ox.io>
5 *
6 * This program is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
10 * license.
11 */
12
13[GtkTemplate (ui = "/org/gnome/SimpleScan/ui/preferences-dialog.ui")]
14private class PreferencesDialog : Hdy.PreferencesWindow
15{
16    private Settings settings;
17
18    [GtkChild]
19    private unowned Gtk.ComboBox text_dpi_combo;
20    [GtkChild]
21    private unowned Gtk.ComboBox photo_dpi_combo;
22    [GtkChild]
23    private unowned Gtk.ComboBox paper_size_combo;
24    [GtkChild]
25    private unowned Gtk.Scale brightness_scale;
26    [GtkChild]
27    private unowned Gtk.Scale contrast_scale;
28    [GtkChild]
29    private unowned Gtk.RadioButton page_delay_0s_button;
30    [GtkChild]
31    private unowned Gtk.RadioButton page_delay_3s_button;
32    [GtkChild]
33    private unowned Gtk.RadioButton page_delay_6s_button;
34    [GtkChild]
35    private unowned Gtk.RadioButton page_delay_10s_button;
36    [GtkChild]
37    private unowned Gtk.RadioButton page_delay_15s_button;
38    [GtkChild]
39    private unowned Gtk.ListStore text_dpi_model;
40    [GtkChild]
41    private unowned Gtk.ListStore photo_dpi_model;
42    [GtkChild]
43    private unowned Gtk.RadioButton front_side_button;
44    [GtkChild]
45    private unowned Gtk.RadioButton back_side_button;
46    [GtkChild]
47    private unowned Gtk.RadioButton both_side_button;
48    [GtkChild]
49    private unowned Gtk.ListStore paper_size_model;
50    [GtkChild]
51    private unowned Gtk.Adjustment brightness_adjustment;
52    [GtkChild]
53    private unowned Gtk.Adjustment contrast_adjustment;
54
55    public PreferencesDialog (Settings settings)
56    {
57        this.settings = settings;
58
59        Gtk.TreeIter iter;
60        paper_size_model.append (out iter);
61        paper_size_model.set (iter, 0, 0, 1, 0, 2,
62                              /* Combo box value for automatic paper size */
63                              _("Automatic"), -1);
64        paper_size_model.append (out iter);
65        paper_size_model.set (iter, 0, 1050, 1, 1480, 2, "A6", -1);
66        paper_size_model.append (out iter);
67        paper_size_model.set (iter, 0, 1480, 1, 2100, 2, "A5", -1);
68        paper_size_model.append (out iter);
69        paper_size_model.set (iter, 0, 2100, 1, 2970, 2, "A4", -1);
70        paper_size_model.append (out iter);
71        paper_size_model.set (iter, 0, 2970, 1, 4200, 2, "A3", -1);
72        paper_size_model.append (out iter);
73        paper_size_model.set (iter, 0, 2159, 1, 2794, 2, "Letter", -1);
74        paper_size_model.append (out iter);
75        paper_size_model.set (iter, 0, 2159, 1, 3556, 2, "Legal", -1);
76        paper_size_model.append (out iter);
77        paper_size_model.set (iter, 0, 1016, 1, 1524, 2, "4×6", -1);
78
79        var dpi = settings.get_int ("text-dpi");
80        if (dpi <= 0)
81            dpi = DEFAULT_TEXT_DPI;
82        set_dpi_combo (text_dpi_combo, DEFAULT_TEXT_DPI, dpi);
83        text_dpi_combo.changed.connect (() => { settings.set_int ("text-dpi", get_text_dpi ()); });
84        dpi = settings.get_int ("photo-dpi");
85        if (dpi <= 0)
86            dpi = DEFAULT_PHOTO_DPI;
87        set_dpi_combo (photo_dpi_combo, DEFAULT_PHOTO_DPI, dpi);
88        photo_dpi_combo.changed.connect (() => { settings.set_int ("photo-dpi", get_photo_dpi ()); });
89
90        set_page_side ((ScanSide) settings.get_enum ("page-side"));
91        front_side_button.toggled.connect ((button) => { if (button.active) settings.set_enum ("page-side", ScanSide.FRONT); });
92        back_side_button.toggled.connect ((button) => { if (button.active) settings.set_enum ("page-side", ScanSide.BACK); });
93        both_side_button.toggled.connect ((button) => { if (button.active) settings.set_enum ("page-side", ScanSide.BOTH); });
94
95        var renderer = new Gtk.CellRendererText ();
96        paper_size_combo.pack_start (renderer, true);
97        paper_size_combo.add_attribute (renderer, "text", 2);
98
99        var lower = brightness_adjustment.lower;
100        var darker_label = "<small>%s</small>".printf (_("Darker"));
101        var upper = brightness_adjustment.upper;
102        var lighter_label = "<small>%s</small>".printf (_("Lighter"));
103        brightness_scale.add_mark (lower, Gtk.PositionType.BOTTOM, darker_label);
104        brightness_scale.add_mark (0, Gtk.PositionType.BOTTOM, null);
105        brightness_scale.add_mark (upper, Gtk.PositionType.BOTTOM, lighter_label);
106        brightness_adjustment.value = settings.get_int ("brightness");
107        brightness_adjustment.value_changed.connect (() => { settings.set_int ("brightness", get_brightness ()); });
108
109        lower = contrast_adjustment.lower;
110        var less_label = "<small>%s</small>".printf (_("Less"));
111        upper = contrast_adjustment.upper;
112        var more_label = "<small>%s</small>".printf (_("More"));
113        contrast_scale.add_mark (lower, Gtk.PositionType.BOTTOM, less_label);
114        contrast_scale.add_mark (0, Gtk.PositionType.BOTTOM, null);
115        contrast_scale.add_mark (upper, Gtk.PositionType.BOTTOM, more_label);
116        contrast_adjustment.value = settings.get_int ("contrast");
117        contrast_adjustment.value_changed.connect (() => { settings.set_int ("contrast", get_contrast ()); });
118
119        var paper_width = settings.get_int ("paper-width");
120        var paper_height = settings.get_int ("paper-height");
121        set_paper_size (paper_width, paper_height);
122        paper_size_combo.changed.connect (() =>
123        {
124            int w, h;
125            get_paper_size (out w, out h);
126            settings.set_int ("paper-width", w);
127            settings.set_int ("paper-height", h);
128        });
129
130        set_page_delay (settings.get_int ("page-delay"));
131        page_delay_0s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 0); });
132        page_delay_3s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 3000); });
133        page_delay_6s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 6000); });
134        page_delay_10s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 10000); });
135        page_delay_15s_button.toggled.connect ((button) => { if (button.active) settings.set_int ("page-delay", 15000); });
136    }
137
138    private void set_page_side (ScanSide page_side)
139    {
140        switch (page_side)
141        {
142        case ScanSide.FRONT:
143            front_side_button.active = true;
144            break;
145        case ScanSide.BACK:
146            back_side_button.active = true;
147            break;
148        default:
149        case ScanSide.BOTH:
150            both_side_button.active = true;
151            break;
152        }
153    }
154
155    public ScanSide get_page_side ()
156    {
157        if (front_side_button.active)
158            return ScanSide.FRONT;
159        else if (back_side_button.active)
160            return ScanSide.BACK;
161        else
162            return ScanSide.BOTH;
163    }
164
165    public void set_paper_size (int width, int height)
166    {
167        Gtk.TreeIter iter;
168        bool have_iter;
169
170        for (have_iter = paper_size_model.get_iter_first (out iter);
171             have_iter;
172             have_iter = paper_size_model.iter_next (ref iter))
173        {
174            int w, h;
175            paper_size_model.get (iter, 0, out w, 1, out h, -1);
176            if (w == width && h == height)
177               break;
178        }
179
180        if (!have_iter)
181            have_iter = paper_size_model.get_iter_first (out iter);
182        if (have_iter)
183            paper_size_combo.set_active_iter (iter);
184    }
185
186    public int get_text_dpi ()
187    {
188        Gtk.TreeIter iter;
189        int dpi = DEFAULT_TEXT_DPI;
190
191        if (text_dpi_combo.get_active_iter (out iter))
192            text_dpi_model.get (iter, 0, out dpi, -1);
193
194        return dpi;
195    }
196
197    public int get_photo_dpi ()
198    {
199        Gtk.TreeIter iter;
200        int dpi = DEFAULT_PHOTO_DPI;
201
202        if (photo_dpi_combo.get_active_iter (out iter))
203            photo_dpi_model.get (iter, 0, out dpi, -1);
204
205        return dpi;
206    }
207
208    public bool get_paper_size (out int width, out int height)
209    {
210        Gtk.TreeIter iter;
211
212        width = height = 0;
213        if (paper_size_combo.get_active_iter (out iter))
214        {
215            paper_size_model.get (iter, 0, ref width, 1, ref height, -1);
216            return true;
217        }
218
219        return false;
220    }
221
222    public int get_brightness ()
223    {
224        return (int) brightness_adjustment.value;
225    }
226
227    public void set_brightness (int brightness)
228    {
229        brightness_adjustment.value = brightness;
230    }
231
232    public int get_contrast ()
233    {
234        return (int) contrast_adjustment.value;
235    }
236
237    public void set_contrast (int contrast)
238    {
239        contrast_adjustment.value = contrast;
240    }
241
242    public int get_page_delay ()
243    {
244        if (page_delay_15s_button.active)
245            return 15000;
246        else if (page_delay_10s_button.active)
247            return 10000;
248        else if (page_delay_6s_button.active)
249            return 6000;
250        else if (page_delay_3s_button.active)
251            return 3000;
252        else
253            return 0;
254    }
255
256    public void set_page_delay (int page_delay)
257    {
258        if (page_delay >= 15000)
259            page_delay_15s_button.active = true;
260        else if (page_delay >= 10000)
261            page_delay_10s_button.active = true;
262        else if (page_delay >= 6000)
263            page_delay_6s_button.active = true;
264        else if (page_delay >= 3000)
265            page_delay_3s_button.active = true;
266        else
267            page_delay_0s_button.active = true;
268    }
269
270    private void set_dpi_combo (Gtk.ComboBox combo, int default_dpi, int current_dpi)
271    {
272        var renderer = new Gtk.CellRendererText ();
273        combo.pack_start (renderer, true);
274        combo.add_attribute (renderer, "text", 1);
275
276        var model = combo.model as Gtk.ListStore;
277        int[] scan_resolutions = {75, 150, 200, 300, 600, 1200, 2400};
278        foreach (var dpi in scan_resolutions)
279        {
280            string label;
281            if (dpi == default_dpi)
282                /* Preferences dialog: Label for default resolution in resolution list */
283                label = _("%d dpi (default)").printf (dpi);
284            else if (dpi == 75)
285                /* Preferences dialog: Label for minimum resolution in resolution list */
286                label = _("%d dpi (draft)").printf (dpi);
287            else if (dpi == 1200)
288                /* Preferences dialog: Label for maximum resolution in resolution list */
289                label = _("%d dpi (high resolution)").printf (dpi);
290            else
291                /* Preferences dialog: Label for resolution value in resolution list (dpi = dots per inch) */
292                label = _("%d dpi").printf (dpi);
293
294            Gtk.TreeIter iter;
295            model.append (out iter);
296            model.set (iter, 0, dpi, 1, label, -1);
297
298            if (dpi == current_dpi)
299                combo.set_active_iter (iter);
300        }
301    }
302}
303