]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormPrint.C
major GUII cleanup + Baruchs patch + Angus's patch + removed a couple of generated...
[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 "xform_macros.h"
16 #include "input_validators.h"
17 #include "LyXView.h"
18 #include "Dialogs.h"
19 #include "support/lstrings.h"
20 #include "lyxrc.h"
21 #include "PrinterParams.h"
22 #include "Liason.h"
23 #include "debug.h"
24 #include "BufferView.h"
25 #include "lyx_gui_misc.h"
26 #include "gettext.h"
27
28
29 #ifdef SIGC_CXX_NAMESPACES
30 using SigC::slot;
31 #endif
32
33 #ifdef CXX_WORKING_NAMESPACES
34 using Liason::printBuffer;
35 using Liason::getPrinterParams;
36 #endif
37
38 C_RETURNCB(FormPrint,  WMHideCB)
39 C_GENERICCB(FormPrint, OKCB)
40 C_GENERICCB(FormPrint, ApplyCB)
41 C_GENERICCB(FormPrint, CancelCB)
42 C_GENERICCB(FormPrint, InputCB)
43
44
45 FormPrint::FormPrint(LyXView * lv, Dialogs * d)
46         : dialog_(0), lv_(lv), d_(d), u_(0), h_(0)
47 {
48         // let the dialog be shown
49         // This is a permanent connection so we won't bother
50         // storing a copy because we won't be disconnecting.
51         d->showPrint.connect(slot(this, &FormPrint::show));
52 }
53
54
55 FormPrint::~FormPrint()
56 {
57         delete dialog_;
58 }
59
60
61 void FormPrint::build()
62 {
63         dialog_ = build_print();
64
65         // allow controlling of input and ok/apply (de)activation
66         fl_set_input_return(dialog_->input_printer,
67                             FL_RETURN_CHANGED);
68         fl_set_input_return(dialog_->input_file,
69                             FL_RETURN_CHANGED);
70         fl_set_input_return(dialog_->input_from_page,
71                             FL_RETURN_CHANGED);
72         fl_set_input_return(dialog_->input_to_page,
73                             FL_RETURN_CHANGED);
74         fl_set_input_return(dialog_->input_count,
75                             FL_RETURN_CHANGED);
76
77         // limit these inputs to unsigned integers
78         fl_set_input_filter(dialog_->input_from_page,
79                             fl_unsigned_int_filter);
80         fl_set_input_filter(dialog_->input_to_page,
81                             fl_unsigned_int_filter);
82         fl_set_input_filter(dialog_->input_count,
83                             fl_unsigned_int_filter);
84
85         // what limits (if any) make sense for these?
86         fl_set_input_maxchars(dialog_->input_printer, 255);
87         fl_set_input_maxchars(dialog_->input_file, 255);
88         fl_set_input_maxchars(dialog_->input_from_page, 4); // 9999
89         fl_set_input_maxchars(dialog_->input_to_page, 4);   // 9999
90         fl_set_input_maxchars(dialog_->input_count, 4);     // 9999
91
92         fl_set_form_atclose(dialog_->form,
93                             C_FormPrintWMHideCB, 0);
94 }
95
96
97 void FormPrint::show()
98 {
99         if (!dialog_) {
100                 build();
101         }
102
103         update();  // make sure its up-to-date
104
105         if (dialog_->form->visible) {
106                 fl_raise_form(dialog_->form);
107         } else {
108                 fl_show_form(dialog_->form,
109                              FL_PLACE_MOUSE | FL_FREE_SIZE,
110                              FL_TRANSIENT,
111                              _("Print"));
112                 fl_set_form_minsize(dialog_->form,
113                                     dialog_->form->w,
114                                     dialog_->form->h);
115                 u_ = d_->updateBufferDependent.connect(slot(this,
116                                                             &FormPrint::update));
117                 h_ = d_->hideBufferDependent.connect(slot(this,
118                                                           &FormPrint::hide));
119         }
120 }
121
122
123 void FormPrint::hide()
124 {
125         if (dialog_
126             && dialog_->form
127             && dialog_->form->visible) {
128                 fl_hide_form(dialog_->form);
129                 u_.disconnect();
130                 h_.disconnect();
131         }
132 }
133
134
135 void FormPrint::apply()
136 {
137         if (!lv_->view()->available()) {
138                 return;
139         }
140
141         PrinterParams::WhichPages wp(PrinterParams::ALL);
142         if (fl_get_button(dialog_->radio_even_pages)) {
143                 wp = PrinterParams::EVEN;
144         } else if (fl_get_button(dialog_->radio_odd_pages)) {
145                 wp = PrinterParams::ODD;
146         }
147
148         string from;
149         int to(0);
150         if (strlen(fl_get_input(dialog_->input_from_page)) > 0) {
151                 // we have at least one page requested
152                 from = fl_get_input(dialog_->input_from_page);
153                 if (strlen(fl_get_input(dialog_->input_to_page)) > 0) {
154                         // okay we have a range
155                         to = strToInt(fl_get_input(dialog_->input_to_page));
156                 } // else we only print one page.
157         }
158
159         PrinterParams::Target t(PrinterParams::PRINTER);
160         if (fl_get_button(dialog_->radio_file)) {
161                 t = PrinterParams::FILE;
162         }
163
164         // we really should use the return value here I think.
165         if (!printBuffer(lv_->buffer(),
166                          PrinterParams(t,
167                                        string(fl_get_input(dialog_->input_printer)),
168                                        string(fl_get_input(dialog_->input_file)),
169                                        wp, from, to,
170                                        static_cast<bool>(fl_get_button(dialog_->
171                                                                        radio_order_reverse)),
172                                        static_cast<bool>(fl_get_button(dialog_->
173                                                                        radio_unsorted)),
174                                        strToInt(fl_get_input(dialog_->input_count))))) {
175                 WriteAlert(_("Error:"),
176                            _("Unable to print"),
177                            _("Check that your parameters are correct"));
178         }
179 }
180
181
182 void FormPrint::update()
183 {
184         if (dialog_
185             && lv_->view()->available()) {
186                 PrinterParams pp(getPrinterParams(lv_->buffer()));
187
188                 fl_set_input(dialog_->input_printer, pp.printer_name.c_str());
189                 fl_set_input(dialog_->input_file, pp.file_name.c_str());
190
191                 switch (pp.target) {
192                 case PrinterParams::FILE:
193                         fl_set_button(dialog_->radio_printer, 0);
194                         fl_set_button(dialog_->radio_file, 1);
195                         break;
196
197                 case PrinterParams::PRINTER:
198                 default:
199                         fl_set_button(dialog_->radio_printer, 1);
200                         fl_set_button(dialog_->radio_file, 0);
201                         break;
202                 }
203
204                 switch (pp.reverse_order) {
205                 case true:
206                         fl_set_button(dialog_->radio_order_normal, 0);
207                         fl_set_button(dialog_->radio_order_reverse, 1);
208                         break;
209
210                 case false:
211                 default:
212                         fl_set_button(dialog_->radio_order_normal, 1);
213                         fl_set_button(dialog_->radio_order_reverse, 0);
214                         break;
215                 }
216 // should be able to remove the various set_button 0 and rely on radio button
217 // action.  Provided xforms is smart enough :D
218                 fl_set_button(dialog_->radio_all_pages, 0);
219                 fl_set_button(dialog_->radio_odd_pages, 0);
220                 fl_set_button(dialog_->radio_even_pages, 0);
221                 switch (pp.which_pages) {
222                 case PrinterParams::ODD:
223                         fl_set_button(dialog_->radio_odd_pages, 1);
224                         break;
225
226                 case PrinterParams::EVEN:
227                         fl_set_button(dialog_->radio_even_pages, 1);
228                         break;
229
230                 case PrinterParams::ALL:
231                 default:
232                         fl_set_button(dialog_->radio_all_pages, 1);
233                         break;
234                 }
235
236                 // hmmm... maybe a bit weird but maybe not
237                 // we might just be remembering the last
238                 // time this was printed.
239                 if (!pp.from_page.empty()) {
240                         fl_set_input(dialog_->input_from_page,
241                                      pp.from_page.c_str());
242                         // we only set the "to" page of a range
243                         // if there's a corresponding "from"
244                         fl_activate_object(dialog_->input_to_page);
245                         if (pp.to_page) {
246                                 fl_set_input(dialog_->input_to_page,
247                                              tostr(pp.to_page).c_str());
248                         } else {
249                                 fl_set_input(dialog_->input_to_page,"");
250                         }
251                 } else {
252                         fl_deactivate_object(dialog_->input_to_page);
253                         fl_set_input(dialog_->input_to_page,"");
254                         fl_set_input(dialog_->input_from_page,"");
255                 }
256
257                 fl_set_input(dialog_->input_count,
258                              tostr(pp.count_copies).c_str());
259
260                 // Even readonly docs can be printed
261                 // these 4 activations are probably superfluous but I'm
262                 // being explicit for a reason.
263                 // They can probably be removed soon along with a few more
264                 // of the de/activations above once input() is a bit smarter.
265                 fl_activate_object(dialog_->input_count);
266                 fl_activate_object(dialog_->input_file);
267                 fl_activate_object(dialog_->input_from_page);
268                 fl_activate_object(dialog_->input_printer);
269                 // and we should always be in a working state upon exit
270                 input();
271         }
272 }
273
274
275 // It would be nice if we checked for cases like:
276 // Print only-odd-pages and from_page == an even number
277 //
278 void FormPrint::input()
279 {
280         bool activate = true;
281
282         // using a fl_input_filter that only permits numbers no '-' or '+'
283         // and the user cannot enter a negative number even if they try.
284         if (strlen(fl_get_input(dialog_->input_from_page))) {
285                 // using a page range so activate the "to" field
286                 fl_activate_object(dialog_->input_to_page);
287                 if (strlen(fl_get_input(dialog_->input_to_page))
288                     && (strToInt(fl_get_input(dialog_->input_from_page))
289                         > strToInt(fl_get_input(dialog_->input_to_page)))) {
290                         // both from and to have values but from > to
291                         // We could have code to silently swap these
292                         // values but I'll disable the ok/apply until
293                         // the user fixes it since they may be editting
294                         // one of the fields.
295                         activate = false;
296                         // set both backgrounds to red?
297                 }
298         } else if (strlen(fl_get_input(dialog_->input_to_page))) {
299                 // from is empty but to exists so probably editting from
300                 // therefore deactivate ok and apply until form is valid again
301                 activate = false;
302         } else {
303                 // both from and to are empty.  This is valid so activate
304                 // ok and apply but deactivate to
305                 fl_deactivate_object(dialog_->input_to_page);
306         }
307
308         if (fl_get_button(dialog_->radio_file)
309             && !strlen(fl_get_input(dialog_->input_file))) {
310                 activate = false;
311         }
312
313         // it is probably legal to have no printer name since the system will
314         // have a default printer set.  Or should have.
315 //      if (fl_get_button(dialog_->radio_printer)
316 //          && !strlen(fl_get_input(dialog_->input_printer))) {
317 //              activate = false;
318 //      }
319
320         if (activate) {
321                 fl_activate_object(dialog_->button_ok);
322                 fl_activate_object(dialog_->button_apply);
323                 fl_set_object_lcol(dialog_->button_ok, FL_BLACK);
324                 fl_set_object_lcol(dialog_->button_apply, FL_BLACK);
325         } else {
326                 fl_deactivate_object(dialog_->button_ok);
327                 fl_deactivate_object(dialog_->button_apply);
328                 fl_set_object_lcol(dialog_->button_ok, FL_INACTIVE);
329                 fl_set_object_lcol(dialog_->button_apply, FL_INACTIVE);
330         }
331 }
332
333
334 int FormPrint::WMHideCB(FL_FORM * form, void *)
335 {
336         // Ensure that the signals (u and h) are disconnected even if the
337         // window manager is used to close the dialog.
338         FormPrint * pre = static_cast<FormPrint*>(form->u_vdata);
339         pre->hide();
340         return FL_CANCEL;
341 }
342
343
344 void FormPrint::OKCB(FL_OBJECT * ob, long)
345 {
346         FormPrint * pre = static_cast<FormPrint*>(ob->form->u_vdata);
347         pre->apply();
348         pre->hide();
349 }
350
351
352 void FormPrint::ApplyCB(FL_OBJECT * ob, long)
353 {
354         FormPrint * pre = static_cast<FormPrint*>(ob->form->u_vdata);
355         pre->apply();
356 }
357
358
359 void FormPrint::CancelCB(FL_OBJECT * ob, long)
360 {
361         FormPrint * pre = static_cast<FormPrint*>(ob->form->u_vdata);
362         pre->hide();
363 }
364
365
366 void FormPrint::InputCB(FL_OBJECT * ob, long)
367 {
368         FormPrint * pre = static_cast<FormPrint*>(ob->form->u_vdata);
369         pre->input();
370 }