]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormPrint.C
717bba95efb5c0996fa8f3af3cab7cefe86eaee7
[lyx.git] / src / frontends / xforms / FormPrint.C
1 /* FormPrint.C
2  * FormPrint Interface Class Implementation
3  */
4
5 #include <config.h>
6
7 #include FORMS_H_LOCATION
8
9 #ifdef __GNUG__
10 #pragma implementation
11 #endif
12
13 #include "FormPrint.h"
14 #include "form_print.h"
15 #include "input_validators.h"
16 #include "LyXView.h"
17 #include "Dialogs.h"
18 #include "support/lstrings.h"
19 #include "lyxrc.h"
20 #include "PrinterParams.h"
21 #include "Liason.h"
22 #include "debug.h"
23 #include "BufferView.h"
24 #include "lyx_gui_misc.h"      // WriteAlert
25 #include "xforms_helpers.h"     // for browseFile
26
27 using Liason::printBuffer;
28 using Liason::getPrinterParams;
29 using std::make_pair;
30
31 FormPrint::FormPrint(LyXView * lv, Dialogs * d)
32         : FormBaseBD(lv, d, _("Print")),
33           target_(2), order_(2), which_(3)
34 {
35         // let the dialog be shown
36         // This is a permanent connection so we won't bother
37         // storing a copy because we won't be disconnecting.
38         d->showPrint.connect(slot(this, &FormPrint::show));
39 }
40
41
42 void FormPrint::build()
43 {
44         dialog_.reset(build_print());
45
46         // Workaround dumb xforms sizing bug
47         minw_ = form()->w;
48         minh_ = form()->h;
49
50         // Manage the ok, apply and cancel/close buttons
51         bc().setOK(dialog_->button_ok);
52         bc().setApply(dialog_->button_apply);
53         bc().setCancel(dialog_->button_cancel);
54         bc().refresh();
55
56         // allow controlling of input and ok/apply (de)activation
57         fl_set_input_return(dialog_->input_printer,
58                             FL_RETURN_CHANGED);
59         fl_set_input_return(dialog_->input_file,
60                             FL_RETURN_CHANGED);
61         fl_set_input_return(dialog_->input_from_page,
62                             FL_RETURN_CHANGED);
63         fl_set_input_return(dialog_->input_to_page,
64                             FL_RETURN_CHANGED);
65         fl_set_input_return(dialog_->input_count,
66                             FL_RETURN_CHANGED);
67
68         // limit these inputs to unsigned integers
69         fl_set_input_filter(dialog_->input_from_page,
70                             fl_unsigned_int_filter);
71         fl_set_input_filter(dialog_->input_to_page,
72                             fl_unsigned_int_filter);
73         fl_set_input_filter(dialog_->input_count,
74                             fl_unsigned_int_filter);
75
76         // what limits (if any) make sense for these?
77         fl_set_input_maxchars(dialog_->input_printer, 255);
78         fl_set_input_maxchars(dialog_->input_file, 255);
79         fl_set_input_maxchars(dialog_->input_from_page, 4); // 9999
80         fl_set_input_maxchars(dialog_->input_to_page, 4);   // 9999
81         fl_set_input_maxchars(dialog_->input_count, 4);     // 9999
82
83         target_.reset();
84         target_.registerRadioButton(dialog_->radio_printer,
85                                     PrinterParams::PRINTER);
86         target_.registerRadioButton(dialog_->radio_file,
87                                     PrinterParams::FILE);
88         order_.reset();
89         order_.registerRadioButton(dialog_->radio_order_reverse,
90                                    true);
91         order_.registerRadioButton(dialog_->radio_order_normal,
92                                    false);
93         which_.reset();
94         which_.registerRadioButton(dialog_->radio_odd_pages,
95                                    PrinterParams::ODD);
96         which_.registerRadioButton(dialog_->radio_even_pages,
97                                    PrinterParams::EVEN);
98         which_.registerRadioButton(dialog_->radio_all_pages,
99                                    PrinterParams::ALL);
100 }
101
102
103 FL_FORM * FormPrint::form() const
104 {
105         if (dialog_.get())
106                 return dialog_->form;
107         return 0;
108 }
109
110
111 void FormPrint::apply()
112 {
113         if (!lv_->view()->available()) {
114                 return;
115         }
116
117         PrinterParams::WhichPages
118                 wp(static_cast<PrinterParams::WhichPages>(which_.getButton()));
119
120         string from;
121         int to(0);
122         if (strlen(fl_get_input(dialog_->input_from_page)) > 0) {
123                 // we have at least one page requested
124                 from = fl_get_input(dialog_->input_from_page);
125                 if (strlen(fl_get_input(dialog_->input_to_page)) > 0) {
126                         // okay we have a range
127                         to = strToInt(fl_get_input(dialog_->input_to_page));
128                 } // else we only print one page.
129         }
130
131         PrinterParams::Target
132                 t(static_cast<PrinterParams::Target>(target_.getButton()));
133
134         // we really should use the return value here I think.
135         if (!printBuffer(lv_->buffer(),
136                          PrinterParams(t,
137                                        string(fl_get_input(dialog_->input_printer)),
138                                        string(fl_get_input(dialog_->input_file)),
139                                        wp, from, to,
140                                        static_cast<bool>(order_.getButton()),
141                                        !static_cast<bool>(fl_get_button(dialog_->
142                                                                         radio_collated)),
143                                        strToInt(fl_get_input(dialog_->input_count))))) {
144                 WriteAlert(_("Error:"),
145                            _("Unable to print"),
146                            _("Check that your parameters are correct"));
147         }
148 }
149
150
151 void FormPrint::update()
152 {
153         if (dialog_.get()
154             && lv_->view()->available()) {
155                 PrinterParams pp(getPrinterParams(lv_->buffer()));
156
157                 fl_set_input(dialog_->input_printer, pp.printer_name.c_str());
158                 fl_set_input(dialog_->input_file, pp.file_name.c_str());
159
160                 target_.setButton(pp.target);
161                 order_.setButton(pp.reverse_order);
162                 which_.setButton(pp.which_pages);
163
164                 // hmmm... maybe a bit weird but maybe not
165                 // we might just be remembering the last
166                 // time this was printed.
167                 if (!pp.from_page.empty()) {
168                         fl_set_input(dialog_->input_from_page,
169                                      pp.from_page.c_str());
170                         // we only set the "to" page of a range
171                         // if there's a corresponding "from"
172                         fl_activate_object(dialog_->input_to_page);
173                         if (pp.to_page) {
174                                 fl_set_input(dialog_->input_to_page,
175                                              tostr(pp.to_page).c_str());
176                         } else {
177                                 fl_set_input(dialog_->input_to_page,"");
178                         }
179                 } else {
180                         fl_deactivate_object(dialog_->input_to_page);
181                         fl_set_input(dialog_->input_to_page,"");
182                         fl_set_input(dialog_->input_from_page,"");
183                 }
184
185                 fl_set_input(dialog_->input_count,
186                              tostr(pp.count_copies).c_str());
187                 bc().valid(true);
188         }
189 }
190
191
192 // It would be nice if we checked for cases like:
193 // Print only-odd-pages and from_page == an even number
194 //
195 bool FormPrint::input(FL_OBJECT * ob, long)
196 {
197         bool activate = true;
198
199         // using a fl_input_filter that only permits numbers no '-' or '+'
200         // and the user cannot enter a negative number even if they try.
201         if (strlen(fl_get_input(dialog_->input_from_page))) {
202                 // using a page range so activate the "to" field
203                 fl_activate_object(dialog_->input_to_page);
204                 if (strlen(fl_get_input(dialog_->input_to_page))
205                     && (strToInt(fl_get_input(dialog_->input_from_page))
206                         > strToInt(fl_get_input(dialog_->input_to_page)))) {
207                         // both from and to have values but from > to
208                         // We could have code to silently swap these
209                         // values but I'll disable the ok/apply until
210                         // the user fixes it since they may be editting
211                         // one of the fields.
212                         activate = false;
213                         // set both backgrounds to red?
214                 }
215         } else if (strlen(fl_get_input(dialog_->input_to_page))) {
216                 // from is empty but to exists so probably editting from
217                 // therefore deactivate ok and apply until form is valid again
218                 activate = false;
219         } else {
220                 // both from and to are empty.  This is valid so activate
221                 // ok and apply but deactivate to
222                 fl_deactivate_object(dialog_->input_to_page);
223         }
224
225         if (fl_get_button(dialog_->radio_file)
226             && !strlen(fl_get_input(dialog_->input_file))) {
227                 activate = false;
228         }
229
230         if (ob == dialog_->button_browse) {
231                 browse();
232         }
233                 
234         // it is probably legal to have no printer name since the system will
235         // have a default printer set.  Or should have.
236 //      if (fl_get_button(dialog_->radio_printer)
237 //          && !strlen(fl_get_input(dialog_->input_printer))) {
238 //              activate = false;
239 //      }
240         return activate;
241 }
242
243
244 void FormPrint::browse()
245 {
246         // Get the filename from the dialog
247         string const filename = fl_get_input(dialog_->input_file);
248
249         string const title = N_("Print to file");
250         string const pattern = "*.ps";
251
252         // Show the file browser dialog
253         string const new_filename =
254                 browseFile(lv_, filename, title, pattern,
255                            make_pair(string(), string()),
256                            make_pair(string(), string()));
257
258         // Save the filename to the dialog
259         if (new_filename != filename && !new_filename.empty()) {
260                 fl_set_input(dialog_->input_file, new_filename.c_str());
261                 input(0, 0);
262         }
263 }