]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormDocument.C
sourcedoc-friendly files.
[lyx.git] / src / frontends / xforms / FormDocument.C
1 /**
2  * \file FormDocument.C
3  * Copyright 2000-2001 The LyX Team.
4  * See the file COPYING.
5  *
6  * \author Jürgen Vigna, jug@sad.it
7  */
8
9 #include <config.h>
10
11 #include FORMS_H_LOCATION
12 #include XPM_H_LOCATION
13
14 #ifdef __GNUG_
15 #pragma implementation
16 #endif
17
18 #include "FormDocument.h"
19 #include "form_document.h"
20 #include "Alert.h"
21 #include "Dialogs.h"
22 #include "lyxtextclasslist.h"
23 #include "combox.h"
24 #include "tex-strings.h"
25 #include "bufferparams.h"
26 #include "vspace.h"
27 #include "bmtable.h"
28 #include "language.h"
29 #include "LyXView.h"
30 #include "lyxfunc.h"
31 #include "lyxrc.h"
32 #include "BufferView.h"
33 #include "buffer.h"
34 #include "Liason.h"
35 #include "CutAndPaste.h"
36 #include "bufferview_funcs.h"
37 #include "xforms_helpers.h" 
38 #include "debug.h"
39 #include "input_validators.h" // fl_unsigned_float_filter
40 #include "helper_funcs.h" 
41 #include "lyx_main.h" // for user_lyxdir
42
43 #include "insets/insetquotes.h"
44
45 #include "support/filetools.h"
46 #include "support/lstrings.h"
47
48 #include <functional>
49
50 using std::bind2nd;
51
52 using Liason::setMinibuffer;
53 using SigC::slot;
54 using std::vector;
55
56 FormDocument::FormDocument(LyXView * lv, Dialogs * d)
57         : FormBaseBD(lv, d, _("Document Layout")),
58           ActCell(0), Confirmed(0),
59           current_bullet_panel(0), current_bullet_depth(0), fbullet(0)
60 {
61         // let the dialog be shown
62         // This is a permanent connection so we won't bother
63         // storing a copy because we won't be disconnecting.
64         d->showDocument.connect(slot(this, &FormDocument::show));
65 }
66
67
68 void FormDocument::redraw()
69 {
70         if (form() && form()->visible)
71                 fl_redraw_form(form());
72         else
73                 return;
74
75         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabbed_folder);
76         if (outer_form && outer_form->visible)
77                 fl_redraw_form(outer_form);
78 }
79
80
81 FL_FORM * FormDocument::form() const
82 {
83         if (dialog_.get()) return dialog_->form;
84         return 0;
85 }
86
87
88 void FormDocument::build()
89 {
90         int n;
91
92         // the tabbed folder
93         dialog_.reset(build_tabbed_document());
94
95         // Manage the restore, ok, apply, restore and cancel/close buttons
96         bc().setOK(dialog_->button_ok);
97         bc().setApply(dialog_->button_apply);
98         bc().setCancel(dialog_->button_cancel);
99         bc().setRestore(dialog_->button_restore);
100         bc().addReadOnly (dialog_->button_save_defaults);
101         bc().addReadOnly (dialog_->button_reset_defaults);
102
103         // the document paper form
104         paper_.reset(build_doc_paper());
105         fl_addto_choice(paper_->choice_papersize,
106                         _(" Default | Custom | USletter | USlegal "
107                           "| USexecutive | A3 | A4 | A5 | B3 | B4 | B5 "));
108         fl_addto_choice(paper_->choice_paperpackage,
109                         _(" None "
110                           "| Small Margins "
111                           "| Very small Margins "
112                           "| Very wide Margins "));
113
114         fl_set_input_return(paper_->input_custom_width,  FL_RETURN_CHANGED);
115         fl_set_input_return(paper_->input_custom_height, FL_RETURN_CHANGED);
116         fl_set_input_return(paper_->input_top_margin,    FL_RETURN_CHANGED);
117         fl_set_input_return(paper_->input_bottom_margin, FL_RETURN_CHANGED);
118         fl_set_input_return(paper_->input_inner_margin,  FL_RETURN_CHANGED);
119         fl_set_input_return(paper_->input_outer_margin,  FL_RETURN_CHANGED);
120         fl_set_input_return(paper_->input_head_height,   FL_RETURN_CHANGED);
121         fl_set_input_return(paper_->input_head_sep,      FL_RETURN_CHANGED);
122         fl_set_input_return(paper_->input_foot_skip,     FL_RETURN_CHANGED);
123
124
125         // Create the contents of the unit choices
126         // Don't include the "%" terms...
127         vector<string> units_vec = getLatexUnits();
128 #if 0
129         for (vector<string>::iterator it = units_vec.begin();
130                 it != units_vec.end(); ++it) {
131                 if (contains(*it, "%"))
132                         it = units_vec.erase(it, it+1) - 1;
133         }
134 #else
135         vector<string>::iterator ret =
136                 std::remove_if(units_vec.begin(),
137                                units_vec.end(),
138                                bind2nd(contains_functor(), "%"));
139         units_vec.erase(ret, units_vec.end());
140 #endif
141         string units = getStringFromVector(units_vec, "|");
142
143         fl_addto_choice(paper_->choice_custom_width_units,  units.c_str());
144         fl_addto_choice(paper_->choice_custom_height_units, units.c_str());
145         fl_addto_choice(paper_->choice_top_margin_units,    units.c_str());
146         fl_addto_choice(paper_->choice_bottom_margin_units, units.c_str());
147         fl_addto_choice(paper_->choice_inner_margin_units,  units.c_str());
148         fl_addto_choice(paper_->choice_outer_margin_units,  units.c_str());
149         fl_addto_choice(paper_->choice_head_height_units,   units.c_str());
150         fl_addto_choice(paper_->choice_head_sep_units,      units.c_str());
151         fl_addto_choice(paper_->choice_foot_skip_units,     units.c_str());
152
153         bc().addReadOnly (paper_->choice_paperpackage);
154         bc().addReadOnly (paper_->group_radio_orientation);
155         bc().addReadOnly (paper_->radio_portrait);
156         bc().addReadOnly (paper_->radio_landscape);
157         bc().addReadOnly (paper_->choice_papersize);
158         bc().addReadOnly (paper_->check_use_geometry);
159         bc().addReadOnly (paper_->input_custom_width);
160         bc().addReadOnly (paper_->input_custom_height);
161         bc().addReadOnly (paper_->input_top_margin);
162         bc().addReadOnly (paper_->input_bottom_margin);
163         bc().addReadOnly (paper_->input_inner_margin);
164         bc().addReadOnly (paper_->input_outer_margin);
165         bc().addReadOnly (paper_->input_head_height);
166         bc().addReadOnly (paper_->input_head_sep);
167         bc().addReadOnly (paper_->input_foot_skip);
168
169         // the document class form
170         class_.reset(build_doc_class());
171
172         FL_OBJECT * obj;
173         // The language is a combo-box and has to be inserted manually
174         obj = class_->choice_doc_class;
175         fl_deactivate_object(obj);
176         fl_addto_form(class_->form);
177         combo_doc_class.reset(new Combox(FL_COMBOX_DROPLIST));
178         combo_doc_class->add(obj->x, obj->y, obj->w, obj->h, 400,
179                              dialog_->tabbed_folder);
180         combo_doc_class->shortcut("#C",1);
181         combo_doc_class->setcallback(ComboInputCB, this);
182         fl_end_form();
183         for (LyXTextClassList::const_iterator cit = textclasslist.begin();
184              cit != textclasslist.end(); ++cit) {
185                 combo_doc_class->addto(cit->description());
186         }
187
188         fl_addto_choice(class_->choice_doc_spacing,
189                         _(" Single | OneHalf | Double | Other "));
190         fl_addto_choice(class_->choice_doc_fontsize, "default|10|11|12");
191         for (n=0; tex_fonts[n][0]; ++n) {
192                 fl_addto_choice(class_->choice_doc_fonts,tex_fonts[n]);
193         }
194         fl_addto_choice(class_->choice_doc_pagestyle,
195                         "default|empty|plain|headings|fancy");
196         fl_addto_choice(class_->choice_doc_skip,
197                         _(" Smallskip | Medskip | Bigskip | Length "));
198         fl_addto_choice(class_->choice_default_skip_units,  units.c_str());
199         fl_set_input_return(class_->input_doc_extra, FL_RETURN_CHANGED);
200         fl_set_input_return(class_->input_doc_skip, FL_RETURN_CHANGED);
201         fl_set_input_return(class_->input_doc_spacing, FL_RETURN_CHANGED);
202
203         // Set input filters on doc spacing to make it accept only
204         // unsigned numbers.
205         fl_set_input_filter(class_->input_doc_spacing, fl_unsigned_float_filter);
206
207         bc().addReadOnly (class_->radio_doc_indent);
208         bc().addReadOnly (class_->radio_doc_skip);
209
210         bc().addReadOnly (class_->choice_doc_pagestyle);
211         bc().addReadOnly (class_->choice_doc_fonts);
212         bc().addReadOnly (class_->choice_doc_fontsize);
213         bc().addReadOnly (class_->radio_doc_sides_one);
214         bc().addReadOnly (class_->radio_doc_sides_two);
215         bc().addReadOnly (class_->radio_doc_columns_one);
216         bc().addReadOnly (class_->radio_doc_columns_two);
217         bc().addReadOnly (class_->input_doc_extra);
218         bc().addReadOnly (class_->input_doc_skip);
219         bc().addReadOnly (class_->choice_doc_skip);
220         bc().addReadOnly (class_->choice_doc_spacing);
221         bc().addReadOnly (class_->input_doc_spacing);
222
223         // the document language form
224         language_.reset(build_doc_language());
225         fl_addto_choice(language_->choice_inputenc,
226                         "default|auto|latin1|latin2|latin3|latin4|latin5|latin9"
227                         "|koi8-r|koi8-u|cp866|cp1251|iso88595");
228
229         // The language is a combo-box and has to be inserted manually
230         obj = language_->choice_language;
231         fl_deactivate_object(obj);
232         fl_addto_form(language_->form);
233         combo_language.reset(new Combox(FL_COMBOX_DROPLIST));
234         combo_language->add(obj->x, obj->y, obj->w, obj->h, 400,
235                             dialog_->tabbed_folder);
236         combo_language->shortcut("#L",1);
237         combo_language->setcallback(ComboInputCB, this);
238         fl_end_form();
239
240         for (Languages::const_iterator cit = languages.begin();
241              cit != languages.end(); ++cit) {
242                 combo_language->addto(cit->second.lang());
243         }
244
245         fl_addto_choice(language_->choice_quotes_language,
246                         _(" ``text'' | ''text'' | ,,text`` | ,,text'' |"
247                           " «text» | »text« "));
248
249         bc().addReadOnly (language_->choice_inputenc);
250         bc().addReadOnly (language_->choice_quotes_language);
251         bc().addReadOnly (language_->radio_single);
252         bc().addReadOnly (language_->radio_double);
253
254         // the document options form
255         options_.reset(build_doc_options());
256         fl_set_input_return(options_->input_float_placement, FL_RETURN_CHANGED);
257         fl_set_counter_bounds(options_->slider_secnumdepth,-2,5);
258         fl_set_counter_bounds(options_->slider_tocdepth,-1,5);
259         fl_set_counter_step(options_->slider_secnumdepth,1,1);
260         fl_set_counter_step(options_->slider_tocdepth,1,1);
261         fl_set_counter_precision(options_->slider_secnumdepth, 0);
262         fl_set_counter_precision(options_->slider_tocdepth, 0);
263         for (n=0; tex_graphics[n][0]; ++n) {
264                 fl_addto_choice(options_->choice_postscript_driver,
265                                 tex_graphics[n]);
266         }
267         fl_addto_choice(options_->choice_citation_format,
268                         _(" Author-year | Numerical "));
269
270         bc_.addReadOnly (options_->slider_secnumdepth);
271         bc_.addReadOnly (options_->slider_tocdepth);
272         bc_.addReadOnly (options_->check_use_amsmath);
273         bc_.addReadOnly (options_->check_use_natbib);
274         bc_.addReadOnly (options_->choice_citation_format);
275         bc_.addReadOnly (options_->input_float_placement);
276         bc_.addReadOnly (options_->choice_postscript_driver);
277
278         // the document bullets form
279         bullets_.reset(build_doc_bullet());
280         fl_addto_choice(bullets_->choice_bullet_size,
281                         _(" default | tiny | script | footnote | small |"
282                           " normal | large | Large | LARGE | huge | Huge"));
283         fl_set_choice(bullets_->choice_bullet_size, 1);
284         fl_set_input_return(bullets_->input_bullet_latex, FL_RETURN_CHANGED);
285         fl_set_input_maxchars(bullets_->input_bullet_latex, 80);
286
287         bc().addReadOnly (bullets_->bmtable_bullet_panel);
288         bc().addReadOnly (bullets_->choice_bullet_size);
289         bc().addReadOnly (bullets_->input_bullet_latex);
290         bc().addReadOnly (bullets_->radio_bullet_depth);
291         bc().addReadOnly (bullets_->radio_bullet_panel);
292
293         fl_addto_tabfolder(dialog_->tabbed_folder,_("Document"),
294                            class_->form);
295         fl_addto_tabfolder(dialog_->tabbed_folder,_("Paper"),
296                            paper_->form);
297         fl_addto_tabfolder(dialog_->tabbed_folder,_("Language"),
298                            language_->form);
299         fl_addto_tabfolder(dialog_->tabbed_folder,_("Extra"),
300                            options_->form);
301         fbullet = fl_addto_tabfolder(dialog_->tabbed_folder,_("Bullets"),
302                                      bullets_->form);
303         if ((XpmVersion < 4) || (XpmVersion == 4 && XpmRevision < 7)) {
304                 lyxerr << _("Your version of libXpm is older than 4.7.\n"
305                             "The `bullet' tab of the document dialog "
306                             "has been disabled") << '\n';
307                 fl_deactivate_object(fbullet);
308                 fl_set_object_lcol(fbullet, FL_INACTIVE);
309         }
310 }
311
312
313 void FormDocument::apply()
314 {
315         if (!lv_->view()->available() || !dialog_.get())
316                 return;
317
318         bool redo = class_apply();
319         paper_apply();
320         redo = language_apply() || redo;
321         redo = options_apply() || redo;
322         bullets_apply();
323
324         if (redo) {
325                 lv_->view()->redoCurrentBuffer();
326         }
327         lv_->buffer()->markDirty();
328         setMinibuffer(lv_, _("Document layout set"));
329 }
330
331
332 void FormDocument::cancel()
333 {
334         // this avoids confusion when reopening
335         BufferParams & param = lv_->buffer()->params;
336         param.temp_bullets[0] = param.user_defined_bullets[0];
337         param.temp_bullets[1] = param.user_defined_bullets[1];
338         param.temp_bullets[2] = param.user_defined_bullets[2];
339         param.temp_bullets[3] = param.user_defined_bullets[3];
340         hide();
341 }
342
343
344 void FormDocument::update()
345 {
346         if (!dialog_.get())
347                 return;
348
349         checkReadOnly();
350
351         BufferParams const & params = lv_->buffer()->params;
352
353         class_update(params);
354         paper_update(params);
355         language_update(params);
356         options_update(params);
357         bullets_update(params);
358 }
359
360
361 namespace {
362 // should this go elsewhere? Maybe a ControllerDocument? (JMarc)
363 /** Save the buffer's parameters as user default.
364     This function saves a file \c user_lyxdir/templates/defaults.lyx
365     which parameters are those of the current buffer. This file
366     is used as a default template when creating a new
367     file. Returns \c true on success.
368 */
369 bool saveParamsAsDefault(BufferParams const &params)
370 {
371         if (!Alert::askQuestion(_("Do you want to save the current settings"),
372                          _("for the document layout as default?"),
373                          _("(they will be valid for any new document)")))
374                 return false;
375         
376         string const fname = AddName(AddPath(user_lyxdir, "templates/"),
377                                      "defaults.lyx");
378         Buffer defaults = Buffer(fname);
379         defaults.params = params;
380         
381         // add an empty paragraph. Is this enough?
382         defaults.paragraph = new Paragraph;
383                 
384         return defaults.writeFile(defaults.fileName(), false);
385 }
386
387 } //namespace
388
389 bool FormDocument::input(FL_OBJECT * ob, long data)
390 {
391         State cb = static_cast<State>(data);
392
393         switch (cb) {
394         case CHECKCHOICECLASS:
395                 CheckChoiceClass(ob, 0);
396                 break;
397         case CHOICEBULLETSIZE:
398                 ChoiceBulletSize(ob, 0);
399                 break;
400         case INPUTBULLETLATEX:
401                 InputBulletLaTeX(ob, 0);
402                 break;
403         case BULLETDEPTH1:
404         case BULLETDEPTH2:
405         case BULLETDEPTH3:
406         case BULLETDEPTH4:
407                 BulletDepth(ob, cb);
408                 break;
409         case BULLETPANEL1:
410         case BULLETPANEL2:
411         case BULLETPANEL3:
412         case BULLETPANEL4:
413         case BULLETPANEL5:
414         case BULLETPANEL6:
415                 BulletPanel(ob, cb);
416                 break;
417         case BULLETBMTABLE:
418                 BulletBMTable(ob, 0);
419                 break;
420         default:
421                 break;
422         }
423
424         bool const length_input = fl_get_choice(class_->choice_doc_skip) == 4;
425         if (ob == class_->choice_doc_skip) {
426                 setEnabled(class_->input_doc_skip, length_input);
427                 setEnabled(class_->choice_default_skip_units, length_input);
428         }
429
430         if (ob == class_->choice_doc_spacing)
431                 setEnabled(class_->input_doc_spacing,
432                            fl_get_choice(class_->choice_doc_spacing) == 4);
433
434         bool const skip_used = fl_get_button(class_->radio_doc_skip);
435         if (ob == class_->radio_doc_skip ||
436             ob == class_->radio_doc_indent) {
437                 setEnabled(class_->choice_doc_skip, skip_used);
438                 setEnabled(class_->input_doc_skip,
439                            skip_used && length_input);
440                 setEnabled(class_->choice_default_skip_units,
441                            skip_used && length_input);
442                 // Default unit choice is cm if metric, inches if US paper.
443                 // If papersize is default, check the lyxrc-settings
444                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
445                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
446                         || paperchoice == 2 || paperchoice > 5;
447                 int const default_unit = metric ? 8 : 9;
448                 if (strip(fl_get_input(class_->input_doc_skip)).empty())
449                         fl_set_choice(class_->choice_default_skip_units,
450                                       default_unit);
451         }
452
453         if (ob == options_->check_use_natbib) {
454                 setEnabled(options_->choice_citation_format,
455                            fl_get_button(options_->check_use_natbib));
456         }
457
458         if (ob == dialog_->button_save_defaults) {
459                 BufferParams params;
460                 class_apply(params);
461                 paper_apply(params);
462                 language_apply(params);
463                 options_apply(params);
464                 bullets_apply(params);
465                 saveParamsAsDefault(params);
466         }
467
468         if (ob == dialog_->button_reset_defaults) {
469                 BufferParams params = lv_->buffer()->params;
470                 params.textclass = combo_doc_class->get() - 1;
471                 params.useClassDefaults();
472                 UpdateLayoutDocument(params);
473         }
474
475         if (ob == paper_->radio_landscape)
476                 fl_set_choice(paper_->choice_paperpackage,
477                 BufferParams::PACKAGE_NONE + 1);
478
479         if (ob == paper_->choice_papersize) {
480                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
481                 bool const defsize = paperchoice == 1;
482                 bool const custom = paperchoice == 2;
483                 bool const a3size = paperchoice == 6;
484                 bool const b3size = paperchoice == 9;
485                 bool const b4size = paperchoice == 10;
486
487                 if (custom)
488                         fl_set_button(paper_->radio_portrait, 1);
489
490                 bool const use_geom = (custom || a3size || b3size || b4size);
491
492                 fl_set_button(paper_->check_use_geometry, int(use_geom));
493
494                 setEnabled(paper_->input_top_margin,    use_geom);
495                 setEnabled(paper_->input_bottom_margin, use_geom);
496                 setEnabled(paper_->input_inner_margin,  use_geom);
497                 setEnabled(paper_->input_outer_margin,  use_geom);
498                 setEnabled(paper_->input_head_height,   use_geom);
499                 setEnabled(paper_->input_head_sep,      use_geom);
500                 setEnabled(paper_->input_foot_skip,     use_geom);
501                 setEnabled(paper_->choice_top_margin_units,    use_geom);
502                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
503                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
504                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
505                 setEnabled(paper_->choice_head_height_units,   use_geom);
506                 setEnabled(paper_->choice_head_sep_units,      use_geom);
507                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
508                 setEnabled(paper_->choice_custom_width_units,  use_geom);
509                 setEnabled(paper_->choice_custom_height_units, use_geom);
510
511                 setEnabled(paper_->input_custom_width,  custom);
512                 setEnabled(paper_->input_custom_height, custom);
513                 setEnabled(paper_->choice_custom_width_units,  custom);
514                 setEnabled(paper_->choice_custom_height_units, custom);
515                 setEnabled(paper_->radio_portrait,  !custom);
516                 setEnabled(paper_->radio_landscape, !custom);
517
518                 // Default unit choice is cm if metric, inches if US paper.
519                 // If papersize is default, use the lyxrc-settings
520                 bool const metric = (defsize && lyxrc.default_papersize > 3)
521                         || paperchoice == 2 || paperchoice > 5;
522                 int const default_unit = metric ? 8 : 9;
523                 if (strip(fl_get_input(paper_->input_custom_width)).empty())
524                 fl_set_choice(paper_->choice_custom_width_units,
525                               default_unit);
526                 if (strip(fl_get_input(paper_->input_custom_height)).empty())
527                         fl_set_choice(paper_->choice_custom_height_units,
528                                       default_unit);
529                 if (strip(fl_get_input(paper_->input_top_margin)).empty())
530                         fl_set_choice(paper_->choice_top_margin_units,
531                                       default_unit);
532                 if (strip(fl_get_input(paper_->input_bottom_margin)).empty())
533                         fl_set_choice(paper_->choice_bottom_margin_units,
534                                       default_unit);
535                 if (strip(fl_get_input(paper_->input_inner_margin)).empty())
536                         fl_set_choice(paper_->choice_inner_margin_units,
537                                       default_unit);
538                 if (strip(fl_get_input(paper_->input_outer_margin)).empty())
539                         fl_set_choice(paper_->choice_outer_margin_units,
540                                       default_unit);
541                 if (strip(fl_get_input(paper_->input_head_height)).empty())
542                         fl_set_choice(paper_->choice_head_height_units,
543                                       default_unit);
544                 if (strip(fl_get_input(paper_->input_head_sep)).empty())
545                         fl_set_choice(paper_->choice_head_sep_units,
546                                       default_unit);
547                 if (strip(fl_get_input(paper_->input_foot_skip)).empty())
548                         fl_set_choice(paper_->choice_foot_skip_units,
549                                       default_unit);
550         }
551
552         if (ob == paper_->choice_papersize ||
553             ob == paper_->radio_portrait ||
554             ob == paper_->radio_landscape) {
555
556                 setEnabled(paper_->choice_paperpackage,
557                            //either default papersize (preferences)
558                            //or document papersize has to be A4
559                            (fl_get_choice(paper_->choice_papersize) == 7
560                             || fl_get_choice(paper_->choice_papersize) == 1
561                             && lyxrc.default_papersize == 5)
562                            && fl_get_button(paper_->radio_portrait));
563         }
564
565         if (ob == paper_->choice_paperpackage) {
566                 if (fl_get_choice(paper_->choice_paperpackage) != 1) {
567                         fl_set_button(paper_->check_use_geometry, 0);
568
569                         setEnabled(paper_->input_top_margin,    false);
570                         setEnabled(paper_->input_bottom_margin, false);
571                         setEnabled(paper_->input_inner_margin,  false);
572                         setEnabled(paper_->input_outer_margin,  false);
573                         setEnabled(paper_->input_head_height,   false);
574                         setEnabled(paper_->input_head_sep,      false);
575                         setEnabled(paper_->input_foot_skip,     false);
576                         setEnabled(paper_->choice_top_margin_units,    false);
577                         setEnabled(paper_->choice_bottom_margin_units, false);
578                         setEnabled(paper_->choice_inner_margin_units,  false);
579                         setEnabled(paper_->choice_outer_margin_units,  false);
580                         setEnabled(paper_->choice_head_height_units,   false);
581                         setEnabled(paper_->choice_head_sep_units,      false);
582                         setEnabled(paper_->choice_foot_skip_units,     false);
583                 }
584         }
585
586         if (ob == paper_->check_use_geometry) {
587                 //don't allow switching geometry off in custom papersize mode
588                 //nor in A3, B3, and B4
589                 int const choice = fl_get_choice(paper_->choice_papersize);
590                 if (choice == 2 || choice == 6 || choice == 9 || choice == 10)
591                         fl_set_button(paper_->check_use_geometry, 1);
592
593                 fl_set_choice(paper_->choice_paperpackage,
594                               BufferParams::PACKAGE_NONE + 1);
595
596                 bool const use_geom = fl_get_button(paper_->check_use_geometry);
597                 setEnabled(paper_->input_top_margin,    use_geom);
598                 setEnabled(paper_->input_bottom_margin, use_geom);
599                 setEnabled(paper_->input_inner_margin,  use_geom);
600                 setEnabled(paper_->input_outer_margin,  use_geom);
601                 setEnabled(paper_->input_head_height,   use_geom);
602                 setEnabled(paper_->input_head_sep,      use_geom);
603                 setEnabled(paper_->input_foot_skip,     use_geom);
604                 setEnabled(paper_->choice_top_margin_units,    use_geom);
605                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
606                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
607                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
608                 setEnabled(paper_->choice_head_height_units,   use_geom);
609                 setEnabled(paper_->choice_head_sep_units,      use_geom);
610                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
611         }
612
613         switch (data) {
614         case INPUT:
615         case CHECKCHOICECLASS:
616         case CHOICEBULLETSIZE:
617         case INPUTBULLETLATEX:
618         case BULLETBMTABLE:
619                 return CheckDocumentInput(ob, 0);
620         default:
621                 break;
622         }
623
624         return true;
625 }
626
627
628 void FormDocument::ComboInputCB(int, void * v, Combox * combox)
629 {
630         FormDocument * pre = static_cast<FormDocument*>(v);
631         if (combox == pre->combo_doc_class.get())
632                 pre->CheckChoiceClass(0, 0);
633         pre->bc().valid(pre->CheckDocumentInput(0,0));
634 }
635
636
637 bool FormDocument::class_apply(BufferParams &params)
638 {
639         bool redo = false;
640
641         // If default skip is a "Length" but there's no text in the
642         // input field, reset the kind to "Medskip", which is the default.
643         if ((fl_get_choice (class_->choice_doc_skip) == 4) &&
644             !*(fl_get_input (class_->input_doc_skip))) {
645                 fl_set_choice (class_->choice_doc_skip, 2);
646         }
647         params.fonts = fl_get_choice_text(class_->choice_doc_fonts);
648         params.fontsize = fl_get_choice_text(class_->choice_doc_fontsize);
649         params.pagestyle = fl_get_choice_text(class_->choice_doc_pagestyle);
650
651         params.textclass = combo_doc_class->get() - 1;
652         
653         BufferParams::PARSEP tmpsep = params.paragraph_separation;
654         if (fl_get_button(class_->radio_doc_indent))
655                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
656         else
657                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
658         if (tmpsep != params.paragraph_separation)
659                 redo = true;
660         
661         VSpace tmpdefskip = params.getDefSkip();
662         switch (fl_get_choice (class_->choice_doc_skip)) {
663         case 1:
664                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
665                 break;
666         case 2:
667                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
668                 break;
669         case 3:
670             params.setDefSkip(VSpace(VSpace::BIGSKIP));
671             break;
672         case 4:
673         {
674                 string const length =
675                         getLengthFromWidgets(class_->input_doc_skip,
676                                              class_->choice_default_skip_units);
677
678                 params.setDefSkip(VSpace(LyXGlueLength(length)));
679                 break;
680         }
681         default:
682                 // DocumentDefskipCB assures that this never happens
683                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
684                 break;
685         }
686         if (!(tmpdefskip == params.getDefSkip()))
687                 redo = true;
688         
689         if (fl_get_button(class_->radio_doc_columns_two))
690                 params.columns = 2;
691         else
692                 params.columns = 1;
693         if (fl_get_button(class_->radio_doc_sides_two))
694                 params.sides = LyXTextClass::TwoSides;
695         else
696                 params.sides = LyXTextClass::OneSide;
697         
698         Spacing tmpSpacing = params.spacing;
699         switch (fl_get_choice(class_->choice_doc_spacing)) {
700         case 1:
701                 lyxerr[Debug::INFO] << "Spacing: SINGLE\n";
702                 params.spacing.set(Spacing::Single);
703                 break;
704         case 2:
705                 lyxerr[Debug::INFO] << "Spacing: ONEHALF\n";
706                 params.spacing.set(Spacing::Onehalf);
707                 break;
708         case 3:
709                 lyxerr[Debug::INFO] << "Spacing: DOUBLE\n";
710                 params.spacing.set(Spacing::Double);
711                 break;
712         case 4:
713                 lyxerr[Debug::INFO] << "Spacing: OTHER\n";
714                 params.spacing.set(Spacing::Other, 
715                                    fl_get_input(class_->input_doc_spacing));
716                 break;
717         }
718         if (tmpSpacing != params.spacing)
719                 redo = true;
720         
721         params.options = fl_get_input(class_->input_doc_extra);
722         
723         return redo;
724 }
725
726
727 bool FormDocument::class_apply()
728 {
729         BufferParams &params = lv_->buffer()->params;
730
731         unsigned int const old_class = params.textclass;
732
733         bool redo = class_apply(params);
734
735         if (params.textclass != old_class) {
736                 // try to load new_class
737                 if (textclasslist[params.textclass].load()) {
738                         // successfully loaded
739                         redo = true;
740                         setMinibuffer(lv_, _("Converting document to new document class..."));
741                         int ret = CutAndPaste::SwitchLayoutsBetweenClasses(
742                                 old_class, params.textclass,
743                                 lv_->buffer()->paragraph,
744                                 lv_->buffer()->params);
745                         if (ret) {
746                                 string s;
747                                 if (ret == 1) {
748                                         s = _("One paragraph couldn't be converted");
749                                 } else {
750                                         s += tostr(ret);
751                                         s += _(" paragraphs couldn't be converted");
752                                 }
753                                 Alert::alert(_("Conversion Errors!"),s,
754                                            _("into chosen document class"));
755                         }
756                         
757                 } else {
758                         // problem changing class -- warn user and retain old style
759                         Alert::alert(_("Conversion Errors!"),
760                                    _("Errors loading new document class."),
761                                    _("Reverting to original document class."));
762                         combo_doc_class->select(int(old_class) + 1);
763                 }
764         }
765         
766         return redo;
767 }
768
769
770 void FormDocument::paper_apply(BufferParams & params)
771 {
772         params.papersize2 = char(fl_get_choice(paper_->choice_papersize)-1);
773
774         params.paperpackage =
775                 char(fl_get_choice(paper_->choice_paperpackage)-1);
776
777         // set params.papersize from params.papersize2 and params.paperpackage
778         params.setPaperStuff();
779
780         params.use_geometry = fl_get_button(paper_->check_use_geometry);
781
782         if (fl_get_button(paper_->radio_landscape))
783                 params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
784         else
785                 params.orientation = BufferParams::ORIENTATION_PORTRAIT;
786
787         params.paperwidth =
788                 getLengthFromWidgets(paper_->input_custom_width,
789                                      paper_->choice_custom_width_units);
790
791         params.paperheight =
792                 getLengthFromWidgets(paper_->input_custom_height,
793                                      paper_->choice_custom_height_units);
794
795         params.leftmargin =
796                 getLengthFromWidgets(paper_->input_inner_margin,
797                                      paper_->choice_inner_margin_units);
798
799         params.topmargin =
800                 getLengthFromWidgets(paper_->input_top_margin,
801                                      paper_->choice_top_margin_units);
802
803         params.rightmargin =
804                 getLengthFromWidgets(paper_->input_outer_margin,
805                                      paper_->choice_outer_margin_units);
806
807         params.bottommargin =
808                 getLengthFromWidgets(paper_->input_bottom_margin,
809                                      paper_->choice_bottom_margin_units);
810
811         params.headheight =
812                 getLengthFromWidgets(paper_->input_head_height,
813                                      paper_->choice_head_height_units);
814
815         params.headsep =
816                 getLengthFromWidgets(paper_->input_head_sep,
817                                      paper_->choice_head_sep_units);
818
819         params.footskip =
820                 getLengthFromWidgets(paper_->input_foot_skip,
821                                      paper_->choice_foot_skip_units);
822 }
823
824
825 void FormDocument::paper_apply()
826 {
827         paper_apply(lv_->buffer()->params);
828 }
829
830
831 bool FormDocument::language_apply(BufferParams & params)
832 {
833         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
834         bool redo = false;
835
836         switch (fl_get_choice(language_->choice_quotes_language) - 1) {
837         case 0:
838                 lga = InsetQuotes::EnglishQ;
839                 break;
840         case 1:
841                 lga = InsetQuotes::SwedishQ;
842                 break;
843         case 2:
844                 lga = InsetQuotes::GermanQ;
845                 break;
846         case 3:
847                 lga = InsetQuotes::PolishQ;
848                 break;
849         case 4:
850                 lga = InsetQuotes::FrenchQ;
851                 break;
852         case 5:
853                 lga = InsetQuotes::DanishQ;
854                 break;
855         }
856         params.quotes_language = lga;
857         if (fl_get_button(language_->radio_single))   
858                 params.quotes_times = InsetQuotes::SingleQ;
859         else
860                 params.quotes_times = InsetQuotes::DoubleQ;
861
862         Language const * old_language = params.language;
863         Language const * new_language = 
864                 languages.getLanguage(combo_language->getline());
865         if (!new_language)
866                 new_language = default_language;
867
868         if (old_language != new_language
869             && old_language->RightToLeft() == params.language->RightToLeft()
870             && !lv_->buffer()->isMultiLingual())
871                 lv_->buffer()->changeLanguage(old_language, params.language);
872
873         if (old_language != new_language) {
874                 redo = true;
875         }
876
877         params.language = new_language;
878         params.inputenc = fl_get_choice_text(language_->choice_inputenc);
879
880         return redo;
881 }
882
883
884 bool FormDocument::language_apply()
885 {
886         return language_apply(lv_->buffer()->params);
887 }
888
889
890 bool FormDocument::options_apply(BufferParams & params)
891 {
892         bool redo = false;
893
894         params.graphicsDriver =
895                 fl_get_choice_text(options_->choice_postscript_driver);
896         params.use_amsmath = fl_get_button(options_->check_use_amsmath);
897         params.use_natbib  = fl_get_button(options_->check_use_natbib);
898         params.use_numerical_citations  =
899                 fl_get_choice(options_->choice_citation_format)-1;
900
901         int tmpchar = int(fl_get_counter_value(options_->slider_secnumdepth));
902         if (params.secnumdepth != tmpchar)
903                 redo = true;
904         params.secnumdepth = tmpchar;
905    
906         params.tocdepth = int(fl_get_counter_value(options_->slider_tocdepth));
907
908         params.float_placement =
909                 fl_get_input(options_->input_float_placement);
910
911         return redo;
912 }
913
914
915 bool FormDocument::options_apply()
916 {
917         return options_apply(lv_->buffer()->params);
918 }
919
920
921 void FormDocument::bullets_apply(BufferParams & params)
922 {
923         /* update the bullet settings */
924         BufferParams & buf_params = lv_->buffer()->params;
925
926         // a little bit of loop unrolling
927         params.user_defined_bullets[0] = buf_params.temp_bullets[0];
928         params.user_defined_bullets[1] = buf_params.temp_bullets[1];
929         params.user_defined_bullets[2] = buf_params.temp_bullets[2];
930         params.user_defined_bullets[3] = buf_params.temp_bullets[3];
931 }
932
933
934 void FormDocument::bullets_apply()
935 {
936         bullets_apply(lv_->buffer()->params);
937 }
938
939
940 void FormDocument::class_update(BufferParams const & params)
941 {
942         if (!class_.get())
943                 return;
944
945         LyXTextClass const & tclass = textclasslist[params.textclass];
946
947         combo_doc_class->select(tclass.description());
948         fl_set_choice_text(class_->choice_doc_fonts, params.fonts.c_str());
949         fl_clear_choice(class_->choice_doc_fontsize);
950         fl_addto_choice(class_->choice_doc_fontsize, "default");
951         fl_addto_choice(class_->choice_doc_fontsize,
952                         tclass.opt_fontsize().c_str());
953         fl_set_choice(class_->choice_doc_fontsize,
954                       tokenPos(tclass.opt_fontsize(), '|', params.fontsize)+2);
955         fl_clear_choice(class_->choice_doc_pagestyle);
956         fl_addto_choice(class_->choice_doc_pagestyle, "default");
957         fl_addto_choice(class_->choice_doc_pagestyle,
958                         tclass.opt_pagestyle().c_str());
959         fl_set_choice(class_->choice_doc_pagestyle,
960                       tokenPos(tclass.opt_pagestyle(), '|', params.pagestyle)+2);
961         fl_set_button(class_->radio_doc_indent, 0);
962         fl_set_button(class_->radio_doc_skip, 0);
963         if (params.paragraph_separation == BufferParams::PARSEP_INDENT)
964                 fl_set_button(class_->radio_doc_indent, 1);
965         else
966                 fl_set_button(class_->radio_doc_skip, 1);
967
968         bool const input_length = fl_get_choice(class_->choice_doc_skip) == 4;
969         setEnabled(class_->choice_default_skip_units, input_length);
970         setEnabled(class_->input_doc_skip, input_length);
971
972         switch (params.getDefSkip().kind()) {
973         case VSpace::SMALLSKIP: 
974                 fl_set_choice (class_->choice_doc_skip, 1);
975                 break;
976         case VSpace::MEDSKIP: 
977                 fl_set_choice (class_->choice_doc_skip, 2);
978                 break;
979         case VSpace::BIGSKIP: 
980                 fl_set_choice (class_->choice_doc_skip, 3);
981                 break;
982         case VSpace::LENGTH:
983         {
984                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
985                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
986                         || paperchoice == 2 || paperchoice > 5;
987                 string const default_unit = metric ? "cm" : "in";
988                 string const length = params.getDefSkip().asLyXCommand();
989                 updateWidgetsFromLengthString(class_->input_doc_skip,
990                                       class_->choice_default_skip_units,
991                                       length, default_unit);
992                 break;
993         }
994         default:
995                 fl_set_choice (class_->choice_doc_skip, 2);
996                 break;
997         }
998         fl_set_button(class_->radio_doc_sides_one, 0);
999         fl_set_button(class_->radio_doc_sides_two, 0);
1000         setEnabled(class_->choice_doc_skip,
1001                    fl_get_button(class_->radio_doc_skip));
1002
1003         if (params.sides == LyXTextClass::TwoSides)
1004                 fl_set_button(class_->radio_doc_sides_two, 1);
1005         else
1006                 fl_set_button(class_->radio_doc_sides_one, 1);
1007         fl_set_button(class_->radio_doc_columns_one, 0);
1008         fl_set_button(class_->radio_doc_columns_two, 0);
1009         if (params.columns == 2)
1010                 fl_set_button(class_->radio_doc_columns_two, 1);
1011         else
1012                 fl_set_button(class_->radio_doc_columns_one, 1);
1013  
1014         fl_set_input(class_->input_doc_spacing, "");
1015         setEnabled(class_->input_doc_spacing, false);
1016
1017         switch (params.spacing.getSpace()) {
1018         case Spacing::Default: // nothing bad should happen with this
1019         case Spacing::Single:
1020                 // \singlespacing
1021                 fl_set_choice(class_->choice_doc_spacing, 1);
1022                 break;
1023         case Spacing::Onehalf:
1024                 // \onehalfspacing
1025                 fl_set_choice(class_->choice_doc_spacing, 2);
1026                 break;
1027         case Spacing::Double:
1028                 // \doublespacing
1029                 fl_set_choice(class_->choice_doc_spacing, 3);
1030                 break;
1031         case Spacing::Other:
1032         {
1033                 fl_set_choice(class_->choice_doc_spacing, 4);
1034                 char sval[20];
1035                 sprintf(sval,"%g",params.spacing.getValue()); 
1036                 fl_set_input(class_->input_doc_spacing, sval);
1037                 setEnabled(class_->input_doc_spacing, true);
1038                 break;
1039         }
1040         }
1041         if (!params.options.empty())
1042                 fl_set_input(class_->input_doc_extra, params.options.c_str());
1043         else
1044                 fl_set_input(class_->input_doc_extra, "");
1045 }
1046
1047
1048 void FormDocument::language_update(BufferParams const & params)
1049 {
1050         if (!language_.get())
1051                 return;
1052
1053         combo_language->select(params.language->lang());
1054         fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
1055         fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
1056         fl_set_button(language_->radio_single, 0);
1057         fl_set_button(language_->radio_double, 0);
1058         if (params.quotes_times == InsetQuotes::SingleQ)
1059                 fl_set_button(language_->radio_single, 1);
1060         else
1061                 fl_set_button(language_->radio_double, 1);
1062 }
1063
1064
1065 void FormDocument::options_update(BufferParams const & params)
1066 {
1067         if (!options_.get())
1068                 return;
1069
1070         fl_set_choice_text(options_->choice_postscript_driver,
1071                            params.graphicsDriver.c_str());
1072         fl_set_button(options_->check_use_amsmath, params.use_amsmath);
1073         fl_set_button(options_->check_use_natbib,  params.use_natbib);
1074         fl_set_choice(options_->choice_citation_format,
1075                       int(params.use_numerical_citations)+1);
1076         setEnabled(options_->choice_citation_format, params.use_natbib);
1077         fl_set_counter_value(options_->slider_secnumdepth, params.secnumdepth);
1078         fl_set_counter_value(options_->slider_tocdepth, params.tocdepth);
1079         if (!params.float_placement.empty())
1080                 fl_set_input(options_->input_float_placement,
1081                              params.float_placement.c_str());
1082         else
1083                 fl_set_input(options_->input_float_placement, "");
1084 }
1085
1086
1087 void FormDocument::paper_update(BufferParams const & params)
1088 {
1089         if (!paper_.get())
1090                 return;
1091
1092         fl_set_choice(paper_->choice_papersize, params.papersize2 + 1);
1093         fl_set_choice(paper_->choice_paperpackage, params.paperpackage + 1);
1094         fl_set_button(paper_->check_use_geometry, params.use_geometry);
1095
1096         int const paperchoice = fl_get_choice(paper_->choice_papersize);
1097         bool const useCustom = paperchoice == 2;
1098         bool const useGeom = fl_get_button(paper_->check_use_geometry);
1099
1100         fl_set_button(paper_->radio_portrait, 0);
1101         setEnabled(paper_->radio_portrait, !useCustom);
1102         fl_set_button(paper_->radio_landscape, 0);
1103         setEnabled(paper_->radio_landscape, !useCustom);
1104
1105         if (params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
1106                 fl_set_button(paper_->radio_landscape, 1);
1107         else
1108                 fl_set_button(paper_->radio_portrait, 1);
1109         setEnabled(paper_->choice_paperpackage,
1110                    //either default papersize (preferences)
1111                    //or document papersize has to be A4
1112                    (paperchoice == 7
1113                     || paperchoice == 1 && lyxrc.default_papersize == 5)
1114                    && fl_get_button(paper_->radio_portrait));
1115
1116         // Default unit choice is cm if metric, inches if US paper.
1117         bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
1118                         || paperchoice == 2 || paperchoice > 5;
1119         string const default_unit = metric ? "cm" : "in";
1120         updateWidgetsFromLengthString(paper_->input_custom_width,
1121                               paper_->choice_custom_width_units,
1122                               params.paperwidth, default_unit);
1123         setEnabled(paper_->input_custom_width, useCustom);
1124         setEnabled(paper_->choice_custom_width_units, useCustom);
1125
1126         updateWidgetsFromLengthString(paper_->input_custom_height,
1127                                       paper_->choice_custom_height_units,
1128                                       params.paperheight, default_unit);
1129         setEnabled(paper_->input_custom_height, useCustom);
1130         setEnabled(paper_->choice_custom_height_units, useCustom);
1131
1132         updateWidgetsFromLengthString(paper_->input_inner_margin,
1133                                       paper_->choice_inner_margin_units,
1134                                       params.leftmargin, default_unit);
1135         setEnabled(paper_->input_inner_margin, useGeom);
1136         setEnabled(paper_->choice_inner_margin_units, useGeom);
1137
1138         updateWidgetsFromLengthString(paper_->input_top_margin,
1139                                       paper_->choice_top_margin_units,
1140                                       params.topmargin, default_unit);
1141         setEnabled(paper_->input_top_margin, useGeom);
1142         setEnabled(paper_->choice_top_margin_units, useGeom);
1143
1144         updateWidgetsFromLengthString(paper_->input_outer_margin,
1145                                       paper_->choice_outer_margin_units,
1146                                       params.rightmargin, default_unit);
1147         setEnabled(paper_->input_outer_margin, useGeom);
1148         setEnabled(paper_->choice_outer_margin_units, useGeom);
1149
1150         updateWidgetsFromLengthString(paper_->input_bottom_margin,
1151                                       paper_->choice_bottom_margin_units,
1152                                       params.bottommargin, default_unit);
1153         setEnabled(paper_->input_bottom_margin, useGeom);
1154         setEnabled(paper_->choice_bottom_margin_units, useGeom);
1155
1156         updateWidgetsFromLengthString(paper_->input_head_height,
1157                                       paper_->choice_head_height_units,
1158                                       params.headheight, default_unit);
1159         setEnabled(paper_->input_head_height, useGeom);
1160         setEnabled(paper_->choice_head_height_units, useGeom);
1161
1162         updateWidgetsFromLengthString(paper_->input_head_sep,
1163                                       paper_->choice_head_sep_units,
1164                                       params.headsep, default_unit);
1165         setEnabled(paper_->input_head_sep, useGeom);
1166         setEnabled(paper_->choice_head_sep_units, useGeom);
1167
1168         updateWidgetsFromLengthString(paper_->input_foot_skip,
1169                                       paper_->choice_foot_skip_units,
1170                                       params.footskip, default_unit);
1171         setEnabled(paper_->input_foot_skip, useGeom);
1172         setEnabled(paper_->choice_foot_skip_units, useGeom);
1173
1174         fl_set_focus_object(paper_->form, paper_->choice_papersize);
1175 }
1176
1177
1178 void FormDocument::bullets_update(BufferParams const & params)
1179 {
1180         if (!bullets_.get() ||
1181             ((XpmVersion<4) ||
1182              (XpmVersion==4 && XpmRevision<7)))
1183                 return;
1184
1185         bool const isLinuxDoc = lv_->buffer()->isLinuxDoc();
1186         setEnabled(fbullet, !isLinuxDoc);
1187
1188         if (isLinuxDoc) return;
1189
1190         fl_set_button(bullets_->radio_bullet_depth_1, 1);
1191         fl_set_input(bullets_->input_bullet_latex,
1192                      params.user_defined_bullets[0].getText().c_str());
1193         fl_set_choice(bullets_->choice_bullet_size,
1194                       params.user_defined_bullets[0].getSize() + 2);
1195 }
1196
1197
1198 void FormDocument::checkReadOnly()
1199 {
1200         if (bc().readOnly(lv_->buffer()->isReadonly())) {
1201                 combo_doc_class->deactivate();
1202                 combo_language->deactivate();
1203                 fl_set_object_label(dialog_->text_warning,
1204                                     _("Document is read-only."
1205                                       " No changes to layout permitted."));
1206                 fl_show_object(dialog_->text_warning);
1207         } else {
1208                 combo_doc_class->activate();
1209                 combo_language->activate();
1210                 fl_hide_object(dialog_->text_warning);
1211         }
1212 }
1213
1214
1215 bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
1216 {
1217         string str;
1218         bool ok = true;
1219         char const * input;
1220
1221         // this has to be all out of if/elseif because it has to deactivate
1222         // the document buttons and so the whole stuff has to be tested again.
1223         // disable OK/Apply if input is not valid
1224         str = fl_get_input(class_->input_doc_skip);
1225         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1226         str = fl_get_input(paper_->input_custom_width);
1227         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1228         str = fl_get_input(paper_->input_custom_height);
1229         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1230         str = fl_get_input(paper_->input_outer_margin);
1231         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1232         str = fl_get_input(paper_->input_inner_margin);
1233         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1234         str = fl_get_input(paper_->input_top_margin);
1235         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1236         str = fl_get_input(paper_->input_bottom_margin);
1237         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1238         str = fl_get_input(paper_->input_head_height);
1239         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1240         str = fl_get_input(paper_->input_head_sep);
1241         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1242         str = fl_get_input(paper_->input_foot_skip);
1243         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1244
1245         //display warning if input is not valid
1246         if (ob == class_->input_doc_skip
1247                         || ob == paper_->input_custom_width
1248                         || ob == paper_->input_custom_height
1249                         || ob == paper_->input_outer_margin
1250                         || ob == paper_->input_inner_margin
1251                         || ob == paper_->input_top_margin
1252                         || ob == paper_->input_bottom_margin
1253                         || ob == paper_->input_head_height
1254                         || ob == paper_->input_head_sep
1255                         || ob == paper_->input_foot_skip) {
1256                 if (!ok) {
1257                         fl_set_object_label(dialog_->text_warning,
1258                                 _("Warning: Invalid Length (valid example: 10mm)"));
1259                         fl_show_object(dialog_->text_warning);
1260                         return false;
1261                 } else {
1262                         fl_hide_object(dialog_->text_warning);
1263                         return true;
1264                 }
1265         }
1266
1267         // "Synchronize" the choice and the input field, so that it
1268         // is impossible to commit senseless data.
1269         input = fl_get_input (class_->input_doc_skip);
1270         if ((fl_get_choice(class_->choice_doc_skip) == 4) && !*input)
1271                 ok = false;
1272         else if (fl_get_choice(class_->choice_doc_skip) != 4)
1273                 fl_set_input (class_->input_doc_skip, "");
1274
1275         input = fl_get_input(class_->input_doc_spacing);
1276         if ((fl_get_choice(class_->choice_doc_spacing) == 4) && !*input)
1277                 ok = false;
1278         else if (fl_get_choice(class_->choice_doc_spacing) != 4)
1279                 fl_set_input (class_->input_doc_spacing, "");
1280         return ok;
1281 }
1282
1283
1284 void FormDocument::ChoiceBulletSize(FL_OBJECT * ob, long /*data*/)
1285 {
1286         BufferParams & param = lv_->buffer()->params;
1287
1288         // convert from 1-6 range to -1-4 
1289         param.temp_bullets[current_bullet_depth].setSize(fl_get_choice(ob) - 2);
1290         fl_set_input(bullets_->input_bullet_latex,
1291                      param.temp_bullets[current_bullet_depth].getText().c_str());
1292 }
1293
1294
1295 void FormDocument::InputBulletLaTeX(FL_OBJECT *, long)
1296 {
1297         BufferParams & param = lv_->buffer()->params;
1298
1299         param.temp_bullets[current_bullet_depth].
1300                 setText(fl_get_input(bullets_->input_bullet_latex));
1301 }
1302
1303
1304 void FormDocument::BulletDepth(FL_OBJECT * ob, State cb)
1305 {
1306         /* Should I do the following:                                 */
1307         /*  1. change to the panel that the current bullet belongs in */
1308         /*  2. show that bullet as selected                           */
1309         /*  3. change the size setting to the size of the bullet in Q.*/
1310         /*  4. display the latex equivalent in the latex box          */
1311         /*                                                            */
1312         /* I'm inclined to just go with 3 and 4 at the moment and     */
1313         /* maybe try to support the others later                      */
1314         BufferParams & param = lv_->buffer()->params;
1315
1316         int data = 0;
1317         if (cb == BULLETDEPTH1)
1318                 data = 0;
1319         else if (cb == BULLETDEPTH2)
1320                 data = 1;
1321         else if (cb == BULLETDEPTH3)
1322                 data = 2;
1323         else if (cb == BULLETDEPTH4)
1324                 data = 3;
1325
1326         switch (fl_get_button_numb(ob)) {
1327         case 3:
1328                 // right mouse button resets to default
1329                 param.temp_bullets[data] = ITEMIZE_DEFAULTS[data];
1330         default:
1331                 current_bullet_depth = data;
1332                 fl_set_input(bullets_->input_bullet_latex,
1333                              param.temp_bullets[data].getText().c_str());
1334                 fl_set_choice(bullets_->choice_bullet_size,
1335                               param.temp_bullets[data].getSize() + 2);
1336         }
1337 }
1338
1339
1340 void FormDocument::BulletPanel(FL_OBJECT * /*ob*/, State cb)
1341 {
1342         /* Here we have to change the background pixmap to that selected */
1343         /* by the user. (eg. standard.xpm, psnfss1.xpm etc...)           */
1344     
1345         int data = 0;
1346         if (cb == BULLETPANEL1)
1347                 data = 0;
1348         else if (cb == BULLETPANEL2)
1349                 data = 1;
1350         else if (cb == BULLETPANEL3)
1351                 data = 2;
1352         else if (cb == BULLETPANEL4)
1353                 data = 3;
1354         else if (cb == BULLETPANEL5)
1355                 data = 4;
1356         else if (cb == BULLETPANEL6)
1357                 data = 5;
1358
1359         if (data != current_bullet_panel) {
1360                 fl_freeze_form(bullets_->form);
1361                 current_bullet_panel = data;
1362
1363                 /* free the current pixmap */
1364                 fl_free_bmtable_pixmap(bullets_->bmtable_bullet_panel);
1365                 string new_panel;
1366                 switch (cb) {
1367                         /* display the new one */
1368                 case BULLETPANEL1 :
1369                         new_panel = "standard";
1370                         break;
1371                 case BULLETPANEL2 :
1372                         new_panel = "amssymb";
1373                         break;
1374                 case BULLETPANEL3 :
1375                         new_panel = "psnfss1";
1376                         break;
1377                 case BULLETPANEL4 :
1378                         new_panel = "psnfss2";
1379                         break;
1380                 case BULLETPANEL5 :
1381                         new_panel = "psnfss3";
1382                         break;
1383                 case BULLETPANEL6 :
1384                         new_panel = "psnfss4";
1385                         break;
1386                 default :
1387                         /* something very wrong happened */
1388                         // play it safe for now but should be an exception
1389                         current_bullet_panel = 0;  // standard panel
1390                         new_panel = "standard";
1391                         break;
1392                 }
1393                 new_panel += ".xpm";
1394                 fl_set_bmtable_pixmap_file(bullets_->bmtable_bullet_panel, 6, 6,
1395                                            LibFileSearch("images", new_panel).c_str());
1396                 fl_redraw_object(bullets_->bmtable_bullet_panel);
1397                 fl_unfreeze_form(bullets_->form);
1398         }
1399 }
1400
1401
1402 void FormDocument::BulletBMTable(FL_OBJECT * ob, long /*data*/)
1403 {
1404         /* handle the user input by setting the current bullet depth's pixmap */
1405         /* to that extracted from the current chosen position of the BMTable  */
1406         /* Don't forget to free the button's old pixmap first.                */
1407         
1408         BufferParams & param = lv_->buffer()->params;
1409         int bmtable_button = fl_get_bmtable(ob);
1410         
1411         /* try to keep the button held down till another is pushed */
1412         /*  fl_set_bmtable(ob, 1, bmtable_button); */
1413         param.temp_bullets[current_bullet_depth].setFont(current_bullet_panel);
1414         param.temp_bullets[current_bullet_depth].setCharacter(bmtable_button);
1415         fl_set_input(bullets_->input_bullet_latex,
1416                      param.temp_bullets[current_bullet_depth].getText().c_str());
1417 }
1418
1419
1420 void FormDocument::CheckChoiceClass(FL_OBJECT * ob, long)
1421 {
1422         if (!ob)
1423                 ob = class_->choice_doc_class;
1424
1425         lv_->prohibitInput();
1426
1427         unsigned int tc = combo_doc_class->get() - 1;
1428         if (textclasslist[tc].load()) {
1429                 // we use a copy of the bufferparams because we do not
1430                 // want to modify them yet.
1431                 BufferParams params = lv_->buffer()->params;
1432
1433                 if (lyxrc.auto_reset_options) {
1434                         params.textclass = tc;
1435                         params.useClassDefaults();
1436                         UpdateLayoutDocument(params);
1437                 }
1438         } else {
1439                 // unable to load new style
1440                 Alert::alert(_("Conversion Errors!"),
1441                            _("Unable to switch to new document class."),
1442                            _("Reverting to original document class."));
1443                 combo_doc_class->select(int(lv_->buffer()->params.textclass) + 1);
1444         }
1445         lv_->allowInput();
1446 }
1447
1448
1449 void FormDocument::UpdateLayoutDocument(BufferParams const & params)
1450 {
1451         if (!dialog_.get())
1452                 return;
1453
1454         checkReadOnly();
1455         class_update(params);
1456         paper_update(params);
1457         language_update(params);
1458         options_update(params);
1459         bullets_update(params);
1460 }