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