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