]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormDocument.C
1d0721f0c6368518880dded2964a5b83e1337920
[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  * \author Martin Vermeer
9  * \author Jürgen Spitzmüller
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "FormDocument.h"
17 #include "forms/form_document.h"
18
19 #include "controllers/ControlDocument.h"
20
21 #include "bmtable.h"
22 #include "checkedwidgets.h"
23 #include "ColorHandler.h"
24 #include "combox.h"
25 #include "FormColorpicker.h"
26 #include "input_validators.h" // fl_unsigned_float_filter
27 #include "Tooltips.h"
28 #include "xforms_helpers.h"
29 #include "xformsBC.h"
30
31 #include "controllers/ButtonController.h"
32 #include "controllers/frnt_lang.h"
33 #include "controllers/helper_funcs.h"
34
35 #include "Bullet.h"
36 #include "bufferparams.h"
37 #include "language.h"
38 #include "lyxrc.h"
39 #include "lyxtextclasslist.h"
40 #include "tex-strings.h"
41 #include "vspace.h"
42
43 #include "support/convert.h"
44 #include "support/lstrings.h" // contains, getStringFromVector
45 #include "support/filetools.h" // LibFileSearch
46
47 #include "lyx_xpm.h"
48
49 #include <boost/bind.hpp>
50
51 #include <iomanip>
52
53 using boost::bind;
54
55 using std::endl;
56 using std::string;
57 using std::vector;
58
59 namespace lyx {
60
61 using support::bformat;
62 using support::contains;
63 using lyx::support::findToken;
64 using support::getStringFromVector;
65 using support::getVectorFromString;
66 using support::libFileSearch;
67
68 namespace frontend {
69
70 namespace {
71
72 #if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL < 2)
73 bool const scalableTabfolders = false;
74 #else
75 bool const scalableTabfolders = true;
76 #endif
77
78 enum {
79         DEFCITE,
80         NATBIB,
81         JURABIB
82 };
83
84 enum GuiColors {
85         GUI_COLOR_CHOICE = FL_FREE_COL15
86 };
87
88 } // namespace anon
89
90
91 typedef FormController<ControlDocument, FormView<FD_document> > base_class;
92
93 FormDocument::FormDocument(Dialog & parent)
94         : base_class(parent, _("Document Settings"), scalableTabfolders),
95           ActCell(0), Confirmed(0),
96           current_bullet_panel(0), current_bullet_depth(0), fbullet(0)
97 {}
98
99
100 void FormDocument::redraw()
101 {
102         if (form() && form()->visible)
103                 fl_redraw_form(form());
104         else
105                 return;
106
107         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabfolder);
108         if (outer_form && outer_form->visible)
109                 fl_redraw_form(outer_form);
110 }
111
112
113 void FormDocument::build()
114 {
115         // the tabbed folder
116         dialog_.reset(build_document(this));
117
118         // Allow the base class to control messages
119         setMessageWidget(dialog_->text_warning);
120
121         // Manage the restore, ok, apply, restore and cancel/close buttons
122         bcview().setOK(dialog_->button_ok);
123         bcview().setApply(dialog_->button_apply);
124         bcview().setCancel(dialog_->button_close);
125         bcview().setRestore(dialog_->button_restore);
126
127         // the document class form
128         class_.reset(build_document_class(this));
129
130         // disable for read-only documents
131         bcview().addReadOnly(class_->combox_class);
132         bcview().addReadOnly(class_->radio_indent);
133         bcview().addReadOnly(class_->radio_skip);
134         bcview().addReadOnly(class_->choice_pagestyle);
135         bcview().addReadOnly(class_->radio_sides_one);
136         bcview().addReadOnly(class_->radio_sides_two);
137         bcview().addReadOnly(class_->radio_columns_one);
138         bcview().addReadOnly(class_->radio_columns_two);
139         bcview().addReadOnly(class_->input_extra);
140         bcview().addReadOnly(class_->input_skip);
141         bcview().addReadOnly(class_->choice_skip);
142         bcview().addReadOnly(class_->choice_spacing);
143         bcview().addReadOnly(class_->input_spacing);
144
145         // check validity of "length + unit" input
146         addCheckedGlueLength(bcview(), class_->input_skip,
147                              class_->choice_skip);
148
149         // trigger an input event for cut&paste with middle mouse button.
150         setPrehandler(class_->input_extra);
151         setPrehandler(class_->input_skip);
152         setPrehandler(class_->input_spacing);
153
154         fl_set_input_return(class_->input_extra, FL_RETURN_CHANGED);
155         fl_set_input_return(class_->input_skip, FL_RETURN_CHANGED);
156         fl_set_input_return(class_->input_spacing, FL_RETURN_CHANGED);
157
158         FL_OBJECT * obj;
159
160         // Fill the combox and choices.
161         obj = class_->combox_class;
162         LyXTextClassList::const_iterator tit  = textclasslist.begin();
163         LyXTextClassList::const_iterator tend = textclasslist.end();
164         for (; tit != tend; ++tit) {
165                 if (tit->isTeXClassAvailable()) {
166                         fl_addto_combox(obj, tit->description().c_str());
167                 } else {
168                         string item = bformat(_("Unavailable: %1$s"), tit->description());
169                         fl_addto_combox(obj, item.c_str());
170                 }
171         }
172         fl_set_combox_browser_height(obj, 400);
173
174         fl_addto_choice(class_->choice_spacing,
175                         _(" Single | OneHalf | Double | Custom ").c_str());
176
177         // Create the contents of the unit choices; don't include the
178         // "%" terms...
179         vector<string> units_vec = getLatexUnits();
180         vector<string>::iterator ret =
181                 std::remove_if(units_vec.begin(),
182                                units_vec.end(),
183                                bind(contains<char>, _1, '%'));
184         units_vec.erase(ret, units_vec.end());
185
186         string const units = getStringFromVector(units_vec, "|");
187
188         fl_addto_choice(class_->choice_pagestyle,
189                         "default|empty|plain|headings|fancy");
190         fl_addto_choice(class_->choice_skip,
191                         _(" SmallSkip | MedSkip | BigSkip | Length ").c_str());
192         fl_addto_choice(class_->choice_skip_units,  units.c_str());
193
194         // Set input filters on doc spacing to make it accept only
195         // unsigned numbers.
196         fl_set_input_filter(class_->input_spacing,
197                             fl_unsigned_float_filter);
198
199         // disable for read-only documents
200         bcview().addReadOnly(dialog_->button_save_defaults);
201         bcview().addReadOnly(dialog_->button_reset_defaults);
202
203         // the fonts form
204         font_.reset(build_document_font(this));
205
206         // disable for read-only documents
207         bcview().addReadOnly(font_->choice_fonts_roman);
208         bcview().addReadOnly(font_->choice_fontsize);
209         bcview().addReadOnly(font_->choice_fonts_sans);
210         bcview().addReadOnly(font_->choice_fonts_typewriter);
211         bcview().addReadOnly(font_->choice_fonts_defaultfamily);
212         bcview().addReadOnly(font_->counter_sf_scale);
213         bcview().addReadOnly(font_->counter_tt_scale);
214         bcview().addReadOnly(font_->check_use_sc);
215         bcview().addReadOnly(font_->check_use_osf);
216
217         fl_addto_choice(font_->choice_fontsize, "default|10|11|12");
218
219         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
220                 string font = tex_fonts_roman_gui[n];
221                 if (!controller().isFontAvailable(tex_fonts_roman[n]))
222                         font += _(" (not installed)");
223                 fl_addto_choice(font_->choice_fonts_roman,font.c_str());
224         }
225         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
226                 string font = tex_fonts_sans_gui[n];
227                 if (!controller().isFontAvailable(tex_fonts_sans[n]))
228                         font += _(" (not installed)");
229                 fl_addto_choice(font_->choice_fonts_sans,font.c_str());
230         }
231         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
232                 string font = tex_fonts_monospaced_gui[n];
233                 if (!controller().isFontAvailable(tex_fonts_monospaced[n]))
234                         font += _(" (not installed)");
235                 fl_addto_choice(font_->choice_fonts_typewriter,font.c_str());
236         }
237
238         for (int n = 0; ControlDocument::fontfamilies_gui[n][0]; ++n)
239                 fl_addto_choice(font_->choice_fonts_defaultfamily,
240                         _(ControlDocument::fontfamilies_gui[n]).c_str());
241
242         fl_set_counter_bounds(font_->counter_sf_scale, 10, 200);
243         fl_set_counter_bounds(font_->counter_tt_scale, 10, 200);
244
245         // the document paper form
246         paper_.reset(build_document_paper(this));
247
248         // disable for read-only documents
249         bcview().addReadOnly(paper_->radio_portrait);
250         bcview().addReadOnly(paper_->radio_landscape);
251         bcview().addReadOnly(paper_->choice_papersize);
252         bcview().addReadOnly(paper_->check_use_geometry);
253         bcview().addReadOnly(paper_->input_custom_width);
254         bcview().addReadOnly(paper_->input_custom_height);
255         bcview().addReadOnly(paper_->input_top_margin);
256         bcview().addReadOnly(paper_->input_bottom_margin);
257         bcview().addReadOnly(paper_->input_inner_margin);
258         bcview().addReadOnly(paper_->input_outer_margin);
259         bcview().addReadOnly(paper_->input_head_height);
260         bcview().addReadOnly(paper_->input_head_sep);
261         bcview().addReadOnly(paper_->input_foot_skip);
262
263         // check validity of "length + unit" input
264         addCheckedGlueLength(bcview(), paper_->input_custom_width);
265         addCheckedGlueLength(bcview(), paper_->input_custom_height);
266         addCheckedGlueLength(bcview(), paper_->input_top_margin);
267         addCheckedGlueLength(bcview(), paper_->input_bottom_margin);
268         addCheckedGlueLength(bcview(), paper_->input_inner_margin);
269         addCheckedGlueLength(bcview(), paper_->input_outer_margin);
270         addCheckedGlueLength(bcview(), paper_->input_head_height);
271         addCheckedGlueLength(bcview(), paper_->input_head_sep);
272         addCheckedGlueLength(bcview(), paper_->input_foot_skip);
273
274         // trigger an input event for cut&paste with middle mouse button.
275         setPrehandler(paper_->input_custom_width);
276         setPrehandler(paper_->input_custom_height);
277         setPrehandler(paper_->input_top_margin);
278         setPrehandler(paper_->input_bottom_margin);
279         setPrehandler(paper_->input_inner_margin);
280         setPrehandler(paper_->input_outer_margin);
281         setPrehandler(paper_->input_head_height);
282         setPrehandler(paper_->input_head_sep);
283         setPrehandler(paper_->input_foot_skip);
284
285         fl_set_input_return(paper_->input_custom_width,  FL_RETURN_CHANGED);
286         fl_set_input_return(paper_->input_custom_height, FL_RETURN_CHANGED);
287         fl_set_input_return(paper_->input_top_margin,    FL_RETURN_CHANGED);
288         fl_set_input_return(paper_->input_bottom_margin, FL_RETURN_CHANGED);
289         fl_set_input_return(paper_->input_inner_margin,  FL_RETURN_CHANGED);
290         fl_set_input_return(paper_->input_outer_margin,  FL_RETURN_CHANGED);
291         fl_set_input_return(paper_->input_head_height,   FL_RETURN_CHANGED);
292         fl_set_input_return(paper_->input_head_sep,      FL_RETURN_CHANGED);
293         fl_set_input_return(paper_->input_foot_skip,     FL_RETURN_CHANGED);
294
295         fl_addto_choice(paper_->choice_papersize,
296                         _(" Default | Custom | US letter | US legal "
297                           "| US executive | A3 | A4 | A5 "
298                           "| B3 | B4 | B5 ").c_str());
299
300         fl_addto_choice(paper_->choice_custom_width_units,  units.c_str());
301         fl_addto_choice(paper_->choice_custom_height_units, units.c_str());
302         fl_addto_choice(paper_->choice_top_margin_units,    units.c_str());
303         fl_addto_choice(paper_->choice_bottom_margin_units, units.c_str());
304         fl_addto_choice(paper_->choice_inner_margin_units,  units.c_str());
305         fl_addto_choice(paper_->choice_outer_margin_units,  units.c_str());
306         fl_addto_choice(paper_->choice_head_height_units,   units.c_str());
307         fl_addto_choice(paper_->choice_head_sep_units,      units.c_str());
308         fl_addto_choice(paper_->choice_foot_skip_units,     units.c_str());
309
310         // the document language form
311         language_.reset(build_document_language(this));
312
313         // disable for read-only documents
314         bcview().addReadOnly(language_->combox_language);
315         bcview().addReadOnly(language_->choice_inputenc);
316         bcview().addReadOnly(language_->choice_quotes_language);
317
318         fl_addto_choice(language_->choice_inputenc,
319                         "default|auto|latin1|latin2|latin3|latin4|latin5|latin9"
320                         "|koi8-r|koi8-u|cp866|cp1251|iso88595|pt154");
321
322         vector<LanguagePair> const langs = getLanguageData(false);
323         // Store the identifiers for later
324         lang_ = getSecond(langs);
325
326         vector<LanguagePair>::const_iterator lit  = langs.begin();
327         vector<LanguagePair>::const_iterator lend = langs.end();
328         for (; lit != lend; ++lit) {
329                 fl_addto_combox(language_->combox_language,
330                                 lit->first.c_str());
331         }
332         fl_set_combox_browser_height(language_->combox_language, 400);
333
334         fl_addto_choice(language_->choice_quotes_language,
335                         _(" ``text'' | ''text'' | ,,text`` | ,,text'' |"
336                           " <<text>> | >>text<< ").c_str());
337
338         // the document options form
339         options_.reset(build_document_options(this));
340
341         // disable for read-only documents
342         bcview().addReadOnly(options_->counter_secnumdepth);
343         bcview().addReadOnly(options_->counter_tocdepth);
344         bcview().addReadOnly(options_->choice_ams_math);
345         bcview().addReadOnly(options_->choice_cite_engine);
346         bcview().addReadOnly(options_->check_bibtopic);
347         bcview().addReadOnly(options_->input_float_placement);
348         bcview().addReadOnly(options_->choice_postscript_driver);
349
350         string const cite_choices =
351                 _(" Basic | Natbib author-year | Natbib numerical | Jurabib ");
352         fl_addto_choice(options_->choice_cite_engine, cite_choices.c_str());
353
354         // set up the tooltips for options form
355         string str = _("Natbib is used often for natural sciences and arts\n"
356                 "Jurabib is more common in law and humanities");
357         tooltips().init(options_->choice_cite_engine, str);
358         str = _("Select this if you want to split your bibliography into sections");
359         tooltips().init(options_->check_bibtopic, str);
360
361         // trigger an input event for cut&paste with middle mouse button.
362         setPrehandler(options_->input_float_placement);
363
364         fl_set_input_return(options_->input_float_placement, FL_RETURN_CHANGED);
365
366         fl_addto_choice(options_->choice_ams_math,
367                         _(" Never | Automatically | Yes ").c_str());
368
369         for (int n = 0; tex_graphics[n][0]; ++n) {
370                 fl_addto_choice(options_->choice_postscript_driver,
371                                 tex_graphics[n]);
372         }
373
374         // the document bullets form
375         bullets_.reset(build_document_bullet(this));
376
377         // disable for read-only documents
378         bcview().addReadOnly(bullets_->radio_depth_1);
379         bcview().addReadOnly(bullets_->radio_depth_2);
380         bcview().addReadOnly(bullets_->radio_depth_3);
381         bcview().addReadOnly(bullets_->radio_depth_4);
382         bcview().addReadOnly(bullets_->radio_panel_standard);
383         bcview().addReadOnly(bullets_->radio_panel_maths);
384         bcview().addReadOnly(bullets_->radio_panel_ding1);
385         bcview().addReadOnly(bullets_->radio_panel_ding2);
386         bcview().addReadOnly(bullets_->radio_panel_ding3);
387         bcview().addReadOnly(bullets_->radio_panel_ding4);
388         bcview().addReadOnly(bullets_->bmtable_panel);
389         bcview().addReadOnly(bullets_->choice_size);
390         bcview().addReadOnly(bullets_->input_latex);
391
392         // trigger an input event for cut&paste with middle mouse button.
393         setPrehandler(bullets_->input_latex);
394
395         fl_set_input_return(bullets_->input_latex, FL_RETURN_CHANGED);
396
397         fl_addto_choice(bullets_->choice_size,
398                         _(" Default | Tiny | Smallest | Smaller "
399                           "| Small | Normal | Large | Larger | Largest "
400                           "| Huge | Huger ").c_str());
401         fl_set_choice(bullets_->choice_size, 1);
402
403         fl_set_input_maxchars(bullets_->input_latex, 80);
404
405         string const bmtablefile = libFileSearch("images", "standard", "xpm");
406         fl_set_bmtable_pixmap_file(bullets_->bmtable_panel, 6, 6,
407                                    bmtablefile.c_str());
408
409         picker_.reset(new FormColorpicker);
410
411         // the document branches form
412         branch_.reset(build_document_branch(this));
413
414         fl_set_object_color(branch_->button_color,
415                 GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
416
417         bcview().addReadOnly(branch_->input_all_branches);
418         bcview().addReadOnly(branch_->button_add_branch);
419         bcview().addReadOnly(branch_->button_remove_branch);
420         bcview().addReadOnly(branch_->button_select);
421         bcview().addReadOnly(branch_->button_deselect);
422         bcview().addReadOnly(branch_->button_modify);
423         bcview().addReadOnly(branch_->browser_all_branches);
424
425         // set up the tooltips for branches form
426         str = _("Enter the name of a new branch.");
427         tooltips().init(branch_->input_all_branches, str);
428         str = _("Add a new branch to the document.");
429         tooltips().init(branch_->button_add_branch, str);
430         str = _("Remove the selected branch from the document.");
431         tooltips().init(branch_->button_remove_branch, str);
432         str = _("Activate the selected branch for output.");
433         tooltips().init(branch_->button_select, str);
434         str = _("Deactivate the selected activated branch.");
435         tooltips().init(branch_->button_deselect, str);
436         str = _("Available branches for this document.");
437         tooltips().init(branch_->browser_all_branches, str);
438         str = _("Activated branches. Content will occur in the document\'s output");
439         tooltips().init(branch_->browser_selection, str);
440         str = _("Modify background color of branch inset");
441         tooltips().init(branch_->button_modify, str);
442         str = _("Background color of branch inset");
443         tooltips().init(branch_->button_color, str);
444
445         // Handle middle mouse paint:
446         setPrehandler(branch_->input_all_branches);
447         fl_set_input_return(branch_->input_all_branches, FL_RETURN_CHANGED);
448
449         // Enable the tabfolder to be rescaled correctly.
450         if (scalableTabfolders)
451                 fl_set_tabfolder_autofit(dialog_->tabfolder, FL_FIT);
452
453         // Stack tabs
454         fl_addto_tabfolder(dialog_->tabfolder,_("Document").c_str(),
455                            class_->form);
456         fl_addto_tabfolder(dialog_->tabfolder,_("Fonts").c_str(),
457                            font_->form);
458         fl_addto_tabfolder(dialog_->tabfolder,_("Paper").c_str(),
459                            paper_->form);
460         fl_addto_tabfolder(dialog_->tabfolder,_("Language").c_str(),
461                            language_->form);
462         fl_addto_tabfolder(dialog_->tabfolder,_("Extra").c_str(),
463                            options_->form);
464         fbullet = fl_addto_tabfolder(dialog_->tabfolder,_("Bullets").c_str(),
465                                      bullets_->form);
466
467         if ((XpmVersion < 4) || (XpmVersion == 4 && XpmRevision < 7)) {
468                 lyxerr << _("Your version of libXpm is older than 4.7.\n"
469                             "The `bullet' tab of the document dialog "
470                             "has been disabled") << '\n';
471                 fl_deactivate_object(fbullet);
472                 fl_set_object_lcol(fbullet, FL_INACTIVE);
473         }
474
475         fl_addto_tabfolder(dialog_->tabfolder,_("Branches").c_str(),
476                                      branch_->form);
477 }
478
479
480 void FormDocument::apply()
481 {
482         BufferParams & params = controller().params();
483
484         class_apply(params);
485         font_apply(params);
486         paper_apply(params);
487         language_apply(params);
488         options_apply(params);
489         bullets_apply(params);
490         branch_apply(params);
491 }
492
493
494 void FormDocument::update()
495 {
496         if (!dialog_.get())
497                 return;
498
499         checkReadOnly();
500
501         BufferParams const & params = controller().params();
502
503         class_update(params);
504         font_update(params);
505         paper_update(params);
506         language_update(params);
507         options_update(params);
508         bullets_update(params);
509         branch_update(params);
510 }
511
512
513 ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
514 {
515         if (ob == bullets_->choice_size) {
516                 ChoiceBulletSize(ob, 0);
517
518         } else if (ob == bullets_->input_latex) {
519                 InputBulletLaTeX(ob, 0);
520
521         } else if (ob == bullets_->radio_depth_1 ||
522                    ob == bullets_->radio_depth_2 ||
523                    ob == bullets_->radio_depth_3 ||
524                    ob == bullets_->radio_depth_4) {
525                 BulletDepth(ob);
526
527         } else if (ob == bullets_->radio_panel_standard ||
528                    ob == bullets_->radio_panel_maths ||
529                    ob == bullets_->radio_panel_ding1 ||
530                    ob == bullets_->radio_panel_ding2 ||
531                    ob == bullets_->radio_panel_ding3 ||
532                    ob == bullets_->radio_panel_ding4) {
533                 BulletPanel(ob);
534
535         } else if (ob == bullets_->bmtable_panel) {
536                 BulletBMTable(ob, 0);
537
538         } else if (ob == class_->choice_spacing) {
539                 setEnabled(class_->input_spacing,
540                            fl_get_choice(class_->choice_spacing) == 4);
541
542         } else if (ob == class_->combox_class) {
543                 CheckChoiceClass();
544         } else if (ob == class_->radio_skip ||
545                    ob == class_->radio_indent ||
546                    ob == class_->choice_skip) {
547                 bool const skip_used = fl_get_button(class_->radio_skip);
548                 setEnabled(class_->choice_skip, skip_used);
549
550                 bool const length_input =
551                         fl_get_choice(class_->choice_skip) == 4;
552                 setEnabled(class_->input_skip,
553                            skip_used && length_input);
554                 setEnabled(class_->choice_skip_units,
555                            skip_used && length_input);
556
557                 // Default unit choice is cm if metric, inches if US paper.
558                 // If papersize is default, check the lyxrc-settings
559                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
560                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_USEXECUTIVE)
561                         || paperchoice == 2 || paperchoice > 5;
562                 string const default_unit = metric ? "cm" : "in";
563                 if (getString(class_->input_skip).empty())
564                         fl_set_choice_text(class_->choice_skip_units,
565                                            default_unit.c_str());
566
567         } else if (ob == branch_->browser_all_branches ||
568                         ob == branch_->browser_selection ||
569                         ob == branch_->button_add_branch ||
570                         ob == branch_->button_remove_branch ||
571                         ob == branch_->button_modify ||
572                         ob == branch_->button_select ||
573                         ob == branch_->button_deselect) {
574                 branch_input(ob);
575         } else if (ob == dialog_->button_save_defaults) {
576                 apply();
577                 controller().saveAsDefault();
578
579         } else if (ob == dialog_->button_reset_defaults) {
580                 BufferParams & params = controller().params();
581                 params.textclass = fl_get_combox(class_->combox_class) - 1;
582                 params.useClassDefaults();
583                 UpdateLayoutDocument(params);
584
585         } else if (ob == font_->choice_fonts_roman) {
586                 string const font =
587                         tex_fonts_roman[fl_get_choice(
588                                 font_->choice_fonts_roman) - 1];
589                 setEnabled(font_->check_use_sc,
590                         controller().providesSC(font));
591                 setEnabled(font_->check_use_osf,
592                         controller().providesOSF(font));
593
594         } else if (ob == font_->choice_fonts_sans) {
595                 string const font =
596                         tex_fonts_sans[fl_get_choice(
597                                 font_->choice_fonts_sans) - 1];
598                 setEnabled(font_->counter_sf_scale,
599                         controller().providesScale(font));
600
601         } else if (ob == font_->choice_fonts_typewriter) {
602                 string const font =
603                         tex_fonts_monospaced[fl_get_choice(
604                                 font_->choice_fonts_typewriter) - 1];
605                 setEnabled(font_->counter_tt_scale,
606                         controller().providesScale(font));
607
608         } else if (ob == paper_->choice_papersize) {
609                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
610                 bool const defsize = paperchoice == 1;
611                 bool const custom = paperchoice == 2;
612                 bool const a3size = paperchoice == 6;
613                 bool const b3size = paperchoice == 9;
614                 bool const b4size = paperchoice == 10;
615
616                 if (custom)
617                         fl_set_button(paper_->radio_portrait, 1);
618
619                 bool const use_geom = (custom || a3size || b3size || b4size);
620
621                 fl_set_button(paper_->check_use_geometry, int(use_geom));
622
623                 setEnabled(paper_->input_top_margin,    use_geom);
624                 setEnabled(paper_->input_bottom_margin, use_geom);
625                 setEnabled(paper_->input_inner_margin,  use_geom);
626                 setEnabled(paper_->input_outer_margin,  use_geom);
627                 setEnabled(paper_->input_head_height,   use_geom);
628                 setEnabled(paper_->input_head_sep,      use_geom);
629                 setEnabled(paper_->input_foot_skip,     use_geom);
630                 setEnabled(paper_->choice_top_margin_units,    use_geom);
631                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
632                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
633                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
634                 setEnabled(paper_->choice_head_height_units,   use_geom);
635                 setEnabled(paper_->choice_head_sep_units,      use_geom);
636                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
637                 setEnabled(paper_->choice_custom_width_units,  use_geom);
638                 setEnabled(paper_->choice_custom_height_units, use_geom);
639
640                 setEnabled(paper_->input_custom_width,  custom);
641                 setEnabled(paper_->input_custom_height, custom);
642                 setEnabled(paper_->choice_custom_width_units,  custom);
643                 setEnabled(paper_->choice_custom_height_units, custom);
644                 setEnabled(paper_->radio_portrait,  !custom);
645                 setEnabled(paper_->radio_landscape, !custom);
646
647                 // Default unit choice is cm if metric, inches if US paper.
648                 // If papersize is default, use the lyxrc-settings
649                 bool const metric = (defsize && lyxrc.default_papersize > PAPER_USEXECUTIVE)
650                         || paperchoice == 2 || paperchoice > 5;
651                 string const default_unit = metric ? "cm" : "in";
652                 if (getString(paper_->input_custom_width).empty())
653                         fl_set_choice_text(paper_->choice_custom_width_units,
654                                            default_unit.c_str());
655                 if (getString(paper_->input_custom_height).empty())
656                         fl_set_choice_text(paper_->choice_custom_height_units,
657                                            default_unit.c_str());
658                 if (getString(paper_->input_top_margin).empty())
659                         fl_set_choice_text(paper_->choice_top_margin_units,
660                                            default_unit.c_str());
661                 if (getString(paper_->input_bottom_margin).empty())
662                         fl_set_choice_text(paper_->choice_bottom_margin_units,
663                                            default_unit.c_str());
664                 if (getString(paper_->input_inner_margin).empty())
665                         fl_set_choice_text(paper_->choice_inner_margin_units,
666                                            default_unit.c_str());
667                 if (getString(paper_->input_outer_margin).empty())
668                         fl_set_choice_text(paper_->choice_outer_margin_units,
669                                            default_unit.c_str());
670                 if (getString(paper_->input_head_height).empty())
671                         fl_set_choice_text(paper_->choice_head_height_units,
672                                            default_unit.c_str());
673                 if (getString(paper_->input_head_sep).empty())
674                         fl_set_choice_text(paper_->choice_head_sep_units,
675                                            default_unit.c_str());
676                 if (getString(paper_->input_foot_skip).empty())
677                         fl_set_choice_text(paper_->choice_foot_skip_units,
678                                            default_unit.c_str());
679
680         } else if (ob == paper_->check_use_geometry) {
681                 // don't allow switching geometry off in custom papersize
682                 // mode nor in A3, B3, and B4
683                 int const choice = fl_get_choice(paper_->choice_papersize);
684                 if (choice == 2 || choice == 6 || choice == 9 || choice == 10)
685                         fl_set_button(paper_->check_use_geometry, 1);
686
687                 bool const use_geom = fl_get_button(paper_->check_use_geometry);
688                 setEnabled(paper_->input_top_margin,    use_geom);
689                 setEnabled(paper_->input_bottom_margin, use_geom);
690                 setEnabled(paper_->input_inner_margin,  use_geom);
691                 setEnabled(paper_->input_outer_margin,  use_geom);
692                 setEnabled(paper_->input_head_height,   use_geom);
693                 setEnabled(paper_->input_head_sep,      use_geom);
694                 setEnabled(paper_->input_foot_skip,     use_geom);
695                 setEnabled(paper_->choice_top_margin_units,    use_geom);
696                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
697                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
698                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
699                 setEnabled(paper_->choice_head_height_units,   use_geom);
700                 setEnabled(paper_->choice_head_sep_units,      use_geom);
701                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
702         }
703
704         return ButtonPolicy::SMI_VALID;
705 }
706
707
708 void FormDocument::rebuild_all_branches_browser()
709 {
710         typedef BranchList::const_iterator const_iterator;
711
712         fl_clear_browser(branch_->browser_all_branches);
713
714         const_iterator const begin = branchlist_.begin();
715         const_iterator const end = branchlist_.end();
716         for (const_iterator it = begin; it != end; ++it) {
717                 fl_addto_browser(branch_->browser_all_branches,
718                                  it->getBranch().c_str());
719         }
720 }
721
722
723 void FormDocument::rebuild_selected_branches_browser()
724 {
725         typedef BranchList::const_iterator const_iterator;
726
727         fl_clear_browser(branch_->browser_selection);
728
729         const_iterator const begin = branchlist_.begin();
730         const_iterator const end = branchlist_.end();
731         for (const_iterator it = begin; it != end; ++it) {
732                 if (it->getSelected())
733                         fl_addto_browser(branch_->browser_selection,
734                                          it->getBranch().c_str());
735         }
736 }
737
738
739 namespace {
740
741 RGBColor get_current_color(FL_OBJECT * browser, BranchList const & branchlist)
742 {
743         BOOST_ASSERT(browser && browser->objclass == FL_BROWSER);
744
745         int const i = fl_get_browser(browser);
746         string const branch_name = fl_get_browser_line(browser, i);
747         Branch const * branch = branchlist.find(branch_name);
748         if (!branch)
749                 return RGBColor();
750
751         return branch->getColor();
752 }
753
754 } // namespace anon
755
756
757 void FormDocument::branch_input(FL_OBJECT * ob)
758 {
759         if (ob == branch_->button_add_branch) {
760                 string const new_branch =
761                         getString(branch_->input_all_branches);
762
763                 if (!new_branch.empty() && branchlist_.add(new_branch)) {
764
765                         fl_set_input(branch_->input_all_branches, "");
766                         rebuild_all_branches_browser();
767                 }
768
769         } else if (ob == branch_->button_remove_branch) {
770                 unsigned i = fl_get_browser(branch_->browser_all_branches);
771                 string const current_branch =
772                         fl_get_browser_line(branch_->browser_all_branches, i);
773                 if (!current_branch.empty() &&
774                     branchlist_.remove(current_branch)) {
775
776                         rebuild_all_branches_browser();
777                         rebuild_selected_branches_browser();
778                 }
779
780         } else if (ob == branch_->button_select ||
781                    ob == branch_->button_deselect) {
782
783                 bool const selecting = ob == branch_->button_select;
784                 string current_branch;
785
786                 // When selecting, take highlighted item from left browser,
787                 // when deselecting, from right browser:
788                 if (selecting) {
789                         int const i = fl_get_browser(branch_->browser_all_branches);
790                         current_branch =
791                                 fl_get_browser_line(branch_->browser_all_branches, i);
792                 } else {
793                         int const i = fl_get_browser(branch_->browser_selection);
794                         current_branch =
795                                 fl_get_browser_line(branch_->browser_selection, i);
796                 }
797                 Branch * branch = branchlist_.find(current_branch);
798
799                 if (branch && branch->setSelected(selecting))
800                         rebuild_selected_branches_browser();
801
802         } else if (ob == branch_->button_modify) {
803                 RGBColor const before =
804                         get_current_color(branch_->browser_all_branches,
805                                           branchlist_);
806                 RGBColor const after = picker_->requestColor(before);
807                 if (before != after) {
808                         fl_mapcolor(GUI_COLOR_CHOICE,
809                                     after.r, after.g, after.b);
810                         fl_redraw_object(branch_->button_color);
811
812                         string const branch_name =
813                                 getString(branch_->browser_all_branches);
814                         Branch * branch = branchlist_.find(branch_name);
815                         if (branch)
816                                 branch->setColor(X11hexname(after));
817                 }
818
819         } else if (ob == branch_->browser_all_branches) {
820                 RGBColor rgb =
821                         get_current_color(branch_->browser_all_branches,
822                                           branchlist_);
823
824                 fl_mapcolor(GUI_COLOR_CHOICE, rgb.r, rgb.g, rgb.b);
825                 fl_redraw_object(branch_->button_color);
826         }
827         setEnabled(branch_->button_select,
828                 (fl_get_browser(branch_->browser_all_branches) > 0));
829         setEnabled(branch_->button_deselect,
830                 (fl_get_browser(branch_->browser_selection) > 0));
831         setEnabled(branch_->button_remove_branch,
832                 (fl_get_browser(branch_->browser_all_branches) > 0));
833         setEnabled(branch_->button_modify,
834                 (fl_get_browser(branch_->browser_all_branches) > 0));
835 }
836
837
838 bool FormDocument::class_apply(BufferParams &params)
839 {
840         bool redo = false;
841
842         // If default skip is a "Length" but there's no text in the
843         // input field, reset the kind to "MedSkip", which is the default.
844         if (fl_get_choice(class_->choice_skip) == 4 &&
845             getString(class_->input_skip).empty()) {
846                 fl_set_choice(class_->choice_skip, 2);
847         }
848         params.pagestyle = getString(class_->choice_pagestyle);
849
850         params.textclass = fl_get_combox(class_->combox_class) - 1;
851
852         BufferParams::PARSEP tmpsep = params.paragraph_separation;
853         if (fl_get_button(class_->radio_indent))
854                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
855         else
856                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
857         if (tmpsep != params.paragraph_separation)
858                 redo = true;
859
860         VSpace tmpdefskip = params.getDefSkip();
861         switch (fl_get_choice(class_->choice_skip)) {
862         case 1:
863                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
864                 break;
865         case 2:
866                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
867                 break;
868         case 3:
869                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
870                 break;
871         case 4:
872         {
873                 string const length =
874                         getLengthFromWidgets(class_->input_skip,
875                                              class_->choice_skip_units);
876
877                 params.setDefSkip(VSpace(LyXGlueLength(length)));
878                 break;
879         }
880         default:
881                 // DocumentDefskipCB assures that this never happens
882                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
883                 break;
884         }
885         if (!(tmpdefskip == params.getDefSkip()))
886                 redo = true;
887
888         if (fl_get_button(class_->radio_columns_two))
889                 params.columns = 2;
890         else
891                 params.columns = 1;
892         if (fl_get_button(class_->radio_sides_two))
893                 params.sides = LyXTextClass::TwoSides;
894         else
895                 params.sides = LyXTextClass::OneSide;
896
897         Spacing tmpSpacing = params.spacing();
898         switch (fl_get_choice(class_->choice_spacing)) {
899         case 1:
900                 lyxerr[Debug::INFO] << "Spacing: SINGLE" << endl;
901                 params.spacing().set(Spacing::Single);
902                 break;
903         case 2:
904                 lyxerr[Debug::INFO] << "Spacing: ONEHALF" << endl;
905                 params.spacing().set(Spacing::Onehalf);
906                 break;
907         case 3:
908                 lyxerr[Debug::INFO] << "Spacing: DOUBLE" << endl;
909                 params.spacing().set(Spacing::Double);
910                 break;
911         case 4:
912                 lyxerr[Debug::INFO] << "Spacing: OTHER" << endl;
913                 params.spacing().set(Spacing::Other,
914                                    getString(class_->input_spacing));
915                 break;
916         }
917         if (tmpSpacing != params.spacing())
918                 redo = true;
919
920         params.options = getString(class_->input_extra);
921
922         return redo;
923 }
924
925
926 void FormDocument::font_apply(BufferParams & params)
927 {
928         params.fontsRoman =
929                 tex_fonts_roman[fl_get_choice(font_->choice_fonts_roman) - 1];
930
931         params.fontsSans =
932                 tex_fonts_sans[fl_get_choice(font_->choice_fonts_sans) - 1];
933
934         params.fontsTypewriter =
935                 tex_fonts_monospaced[fl_get_choice(font_->choice_fonts_typewriter) - 1];
936
937         params.fontsSansScale = int(fl_get_counter_value(font_->counter_sf_scale));
938
939         params.fontsTypewriterScale = int(fl_get_counter_value(font_->counter_tt_scale));
940
941         params.fontsSC = fl_get_button(font_->check_use_sc);
942
943         params.fontsOSF = fl_get_button(font_->check_use_osf);
944
945         params.fontsDefaultFamily = ControlDocument::fontfamilies[
946                 fl_get_choice(font_->choice_fonts_defaultfamily) - 1];
947
948         params.fontsize =
949                         params.fontsize = getString(font_->choice_fontsize);
950 }
951
952
953 void FormDocument::paper_apply(BufferParams & params)
954 {
955         params.papersize = PAPER_SIZE(fl_get_choice(paper_->choice_papersize) - 1);
956
957         params.use_geometry = fl_get_button(paper_->check_use_geometry);
958
959         if (fl_get_button(paper_->radio_landscape))
960                 params.orientation = ORIENTATION_LANDSCAPE;
961         else
962                 params.orientation = ORIENTATION_PORTRAIT;
963
964         params.paperwidth =
965                 getLengthFromWidgets(paper_->input_custom_width,
966                                      paper_->choice_custom_width_units);
967
968         params.paperheight =
969                 getLengthFromWidgets(paper_->input_custom_height,
970                                      paper_->choice_custom_height_units);
971
972         params.leftmargin =
973                 getLengthFromWidgets(paper_->input_inner_margin,
974                                      paper_->choice_inner_margin_units);
975
976         params.topmargin =
977                 getLengthFromWidgets(paper_->input_top_margin,
978                                      paper_->choice_top_margin_units);
979
980         params.rightmargin =
981                 getLengthFromWidgets(paper_->input_outer_margin,
982                                      paper_->choice_outer_margin_units);
983
984         params.bottommargin =
985                 getLengthFromWidgets(paper_->input_bottom_margin,
986                                      paper_->choice_bottom_margin_units);
987
988         params.headheight =
989                 getLengthFromWidgets(paper_->input_head_height,
990                                      paper_->choice_head_height_units);
991
992         params.headsep =
993                 getLengthFromWidgets(paper_->input_head_sep,
994                                      paper_->choice_head_sep_units);
995
996         params.footskip =
997                 getLengthFromWidgets(paper_->input_foot_skip,
998                                      paper_->choice_foot_skip_units);
999 }
1000
1001
1002 bool FormDocument::language_apply(BufferParams & params)
1003 {
1004         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
1005         bool redo = false;
1006
1007         switch (fl_get_choice(language_->choice_quotes_language) - 1) {
1008         case 0:
1009                 lga = InsetQuotes::EnglishQ;
1010                 break;
1011         case 1:
1012                 lga = InsetQuotes::SwedishQ;
1013                 break;
1014         case 2:
1015                 lga = InsetQuotes::GermanQ;
1016                 break;
1017         case 3:
1018                 lga = InsetQuotes::PolishQ;
1019                 break;
1020         case 4:
1021                 lga = InsetQuotes::FrenchQ;
1022                 break;
1023         case 5:
1024                 lga = InsetQuotes::DanishQ;
1025                 break;
1026         }
1027         params.quotes_language = lga;
1028
1029         int const pos = fl_get_combox(language_->combox_language);
1030         Language const * new_language = languages.getLanguage(lang_[pos-1]);
1031         if (!new_language)
1032                 new_language = default_language;
1033
1034         params.language = new_language;
1035         params.inputenc = getString(language_->choice_inputenc);
1036
1037         return redo;
1038 }
1039
1040
1041 void FormDocument::options_apply(BufferParams & params)
1042 {
1043         params.graphicsDriver = getString(options_->choice_postscript_driver);
1044         params.use_amsmath = static_cast<BufferParams::AMS>(
1045                 fl_get_choice(options_->choice_ams_math) - 1);
1046
1047         int const cite_choice = fl_get_choice(options_->choice_cite_engine);
1048         switch (cite_choice) {
1049         case 1:
1050                 params.cite_engine = biblio::ENGINE_BASIC;
1051                 break;
1052         case 2:
1053                 params.cite_engine = biblio::ENGINE_NATBIB_AUTHORYEAR;
1054                 break;
1055         case 3:
1056                 params.cite_engine = biblio::ENGINE_NATBIB_NUMERICAL;
1057                 break;
1058         case 4:
1059                 params.cite_engine = biblio::ENGINE_JURABIB;
1060                 break;
1061         }
1062
1063         params.use_bibtopic  = fl_get_button(options_->check_bibtopic);
1064
1065         if (params.getLyXTextClass().hasTocLevels()) {
1066                 params.secnumdepth = int(fl_get_counter_value(options_->counter_secnumdepth));
1067                 params.tocdepth = int(fl_get_counter_value(options_->counter_tocdepth));
1068         }
1069
1070         params.float_placement =
1071                 getString(options_->input_float_placement);
1072
1073 }
1074
1075
1076 void FormDocument::bullets_apply(BufferParams & params)
1077 {
1078         /* update the bullet settings */
1079         BufferParams & buf_params = controller().params();
1080
1081         for (int i = 0; i < 4; ++i) {
1082                 params.user_defined_bullet(i) = buf_params.temp_bullet(i);
1083         }
1084 }
1085
1086
1087 void FormDocument::branch_apply(BufferParams & params)
1088 {
1089         params.branchlist() = branchlist_;
1090 }
1091
1092
1093 void FormDocument::UpdateClassParams(BufferParams const & params)
1094 {
1095         // These are the params that have to be updated on any class change
1096         // (even if the class defaults are not used) (JSpitzm 2002-04-08)
1097
1098         LyXTextClass const & tclass = params.getLyXTextClass();
1099
1100         fl_set_combox(class_->combox_class, params.textclass + 1);
1101         fl_clear_choice(font_->choice_fontsize);
1102         fl_addto_choice(font_->choice_fontsize, "default");
1103         fl_addto_choice(font_->choice_fontsize,
1104                         tclass.opt_fontsize().c_str());
1105         fl_set_choice_text(font_->choice_fontsize,
1106                            params.fontsize.c_str());
1107         fl_clear_choice(class_->choice_pagestyle);
1108         fl_addto_choice(class_->choice_pagestyle, "default");
1109         fl_addto_choice(class_->choice_pagestyle,
1110                         tclass.opt_pagestyle().c_str());
1111         fl_set_choice_text(class_->choice_pagestyle,
1112                            params.pagestyle.c_str());
1113
1114         fl_set_input(class_->input_extra, tclass.options().c_str());
1115         setEnabled(options_->counter_secnumdepth, tclass.hasTocLevels());
1116         setEnabled(options_->counter_tocdepth, tclass.hasTocLevels());
1117 }
1118
1119 void FormDocument::class_update(BufferParams const & params)
1120 {
1121         if (!class_.get())
1122                 return;
1123
1124         UpdateClassParams(params);
1125
1126         bool const indent = params.paragraph_separation == BufferParams::PARSEP_INDENT;
1127         fl_set_button(class_->radio_indent, indent);
1128         fl_set_button(class_->radio_skip, !indent);
1129
1130         int pos;
1131         if (indent) {
1132                 pos = 2; // VSpace::MEDSKIP is default
1133         } else {
1134                 switch (params.getDefSkip().kind()) {
1135                 case VSpace::LENGTH:
1136                         pos = 4;
1137                         break;
1138                 case VSpace::BIGSKIP:
1139                         pos = 3;
1140                         break;
1141                 case VSpace::SMALLSKIP:
1142                         pos = 1;
1143                         break;
1144                 case VSpace::MEDSKIP:
1145                 default:
1146                         pos = 2;
1147                         break;
1148                 }
1149         }
1150         fl_set_choice (class_->choice_skip, pos);
1151
1152         bool const length_input = pos == 4;
1153         if (length_input) {
1154                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
1155                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_USEXECUTIVE)
1156                         || paperchoice == 2 || paperchoice > 5;
1157                 string const default_unit = metric ? "cm" : "in";
1158                 string const length = params.getDefSkip().asLyXCommand();
1159                 updateWidgetsFromLengthString(class_->input_skip,
1160                                               class_->choice_skip_units,
1161                                               length, default_unit);
1162
1163         } else {
1164                 fl_set_input(class_->input_skip, "");
1165         }
1166         setEnabled(class_->choice_skip, !indent);
1167         setEnabled(class_->input_skip, length_input);
1168         setEnabled(class_->choice_skip_units, length_input);
1169
1170         bool const two_sides = params.sides == LyXTextClass::TwoSides;
1171         fl_set_button(class_->radio_sides_one, !two_sides);
1172         fl_set_button(class_->radio_sides_two, two_sides);
1173
1174         bool const two_columns = params.columns == 2;
1175         fl_set_button(class_->radio_columns_one, !two_columns);
1176         fl_set_button(class_->radio_columns_two, two_columns);
1177
1178         fl_set_input(class_->input_extra, params.options.c_str());
1179
1180         switch (params.spacing().getSpace()) {
1181         case Spacing::Other:
1182                 pos = 4;
1183                 break;
1184         case Spacing::Double: // \doublespacing
1185                 pos = 3;
1186                 break;
1187         case Spacing::Onehalf: // \onehalfspacing
1188                 pos = 2;
1189                 break;
1190         case Spacing::Single: // \singlespacing
1191         case Spacing::Default: // nothing bad should happen with this
1192         default:
1193                 pos = 1;
1194                 break;
1195         }
1196         fl_set_choice(class_->choice_spacing, pos);
1197
1198         bool const spacing_input = pos == 4;
1199         setEnabled(class_->input_spacing, spacing_input);
1200         string const input = spacing_input ? params.spacing().getValueAsString() : string();
1201         fl_set_input(class_->input_spacing, input.c_str());
1202 }
1203
1204
1205 void FormDocument::font_update(BufferParams const & params)
1206 {
1207         if (!font_.get())
1208                 return;
1209
1210         int n = findToken(tex_fonts_roman, params.fontsRoman);
1211         if (n >= 0)
1212                 fl_set_choice(font_->choice_fonts_roman, n + 1);
1213
1214         n = findToken(tex_fonts_sans, params.fontsSans);
1215         if (n >= 0)
1216                 fl_set_choice(font_->choice_fonts_sans, n + 1);
1217
1218         n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
1219         if (n >= 0)
1220                 fl_set_choice(font_->choice_fonts_typewriter, n + 1);
1221
1222         fl_set_button(font_->check_use_sc, params.fontsSC);
1223         fl_set_button(font_->check_use_osf, params.fontsOSF);
1224         setEnabled(font_->check_use_sc,
1225                 controller().providesSC(params.fontsRoman));
1226         setEnabled(font_->check_use_osf,
1227                 controller().providesOSF(params.fontsRoman));
1228         fl_set_counter_value(font_->counter_sf_scale, params.fontsSansScale);
1229         fl_set_counter_value(font_->counter_tt_scale,
1230                         params.fontsTypewriterScale);
1231         setEnabled(font_->counter_sf_scale,
1232                 controller().providesScale(params.fontsSans));
1233         setEnabled(font_->counter_tt_scale,
1234                 controller().providesScale(params.fontsTypewriter));
1235
1236         n = findToken(ControlDocument::fontfamilies, params.fontsDefaultFamily);
1237         if (n >= 0)
1238                 fl_set_choice(font_->choice_fonts_defaultfamily, n + 1);
1239 }
1240
1241
1242 void FormDocument::language_update(BufferParams const & params)
1243 {
1244         if (!language_.get())
1245                 return;
1246
1247         int const pos = int(findPos(lang_, params.language->lang()));
1248         fl_set_combox(language_->combox_language, pos+1);
1249
1250         fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
1251         fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
1252 }
1253
1254
1255 void FormDocument::options_update(BufferParams const & params)
1256 {
1257         if (!options_.get())
1258                 return;
1259
1260         fl_set_choice_text(options_->choice_postscript_driver,
1261                            params.graphicsDriver.c_str());
1262         fl_set_choice(options_->choice_ams_math, params.use_amsmath + 1);
1263
1264         int cite_choice = 1;
1265         switch (params.cite_engine) {
1266         case biblio::ENGINE_BASIC:
1267                 cite_choice = 1;
1268                 break;
1269         case biblio::ENGINE_NATBIB_AUTHORYEAR:
1270                 cite_choice = 2;
1271                 break;
1272         case biblio::ENGINE_NATBIB_NUMERICAL:
1273                 cite_choice = 3;
1274                 break;
1275         case biblio::ENGINE_JURABIB:
1276                 cite_choice = 4;
1277                 break;
1278         }
1279         fl_set_choice(options_->choice_cite_engine, cite_choice);
1280
1281         fl_set_button(options_->check_bibtopic,  params.use_bibtopic);
1282
1283         if (params.getLyXTextClass().hasTocLevels()) {
1284                 fl_set_counter_value(options_->counter_secnumdepth, params.secnumdepth);
1285                 fl_set_counter_value(options_->counter_tocdepth, params.tocdepth);
1286         }
1287
1288         if (!params.float_placement.empty())
1289                 fl_set_input(options_->input_float_placement,
1290                              params.float_placement.c_str());
1291         else
1292                 fl_set_input(options_->input_float_placement, "");
1293 }
1294
1295
1296 void FormDocument::paper_update(BufferParams const & params)
1297 {
1298         if (!paper_.get())
1299                 return;
1300
1301         fl_set_choice(paper_->choice_papersize, params.papersize + 1);
1302         fl_set_button(paper_->check_use_geometry, params.use_geometry);
1303
1304         int const paperchoice = fl_get_choice(paper_->choice_papersize);
1305         bool const useCustom = paperchoice == 2;
1306         bool const useGeom = fl_get_button(paper_->check_use_geometry);
1307
1308         fl_set_button(paper_->radio_portrait, 0);
1309         setEnabled(paper_->radio_portrait, !useCustom);
1310         fl_set_button(paper_->radio_landscape, 0);
1311         setEnabled(paper_->radio_landscape, !useCustom);
1312
1313         if (params.orientation == ORIENTATION_LANDSCAPE)
1314                 fl_set_button(paper_->radio_landscape, 1);
1315         else
1316                 fl_set_button(paper_->radio_portrait, 1);
1317
1318         // Default unit choice is cm if metric, inches if US paper.
1319         bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_USEXECUTIVE)
1320                 || paperchoice == 2 || paperchoice > 5;
1321         string const default_unit = metric ? "cm" : "in";
1322         updateWidgetsFromLengthString(paper_->input_custom_width,
1323                                       paper_->choice_custom_width_units,
1324                                       params.paperwidth, default_unit);
1325         setEnabled(paper_->input_custom_width, useCustom);
1326         setEnabled(paper_->choice_custom_width_units, useCustom);
1327
1328         updateWidgetsFromLengthString(paper_->input_custom_height,
1329                                       paper_->choice_custom_height_units,
1330                                       params.paperheight, default_unit);
1331         setEnabled(paper_->input_custom_height, useCustom);
1332         setEnabled(paper_->choice_custom_height_units, useCustom);
1333
1334         updateWidgetsFromLengthString(paper_->input_inner_margin,
1335                                       paper_->choice_inner_margin_units,
1336                                       params.leftmargin, default_unit);
1337         setEnabled(paper_->input_inner_margin, useGeom);
1338         setEnabled(paper_->choice_inner_margin_units, useGeom);
1339
1340         updateWidgetsFromLengthString(paper_->input_top_margin,
1341                                       paper_->choice_top_margin_units,
1342                                       params.topmargin, default_unit);
1343         setEnabled(paper_->input_top_margin, useGeom);
1344         setEnabled(paper_->choice_top_margin_units, useGeom);
1345
1346         updateWidgetsFromLengthString(paper_->input_outer_margin,
1347                                       paper_->choice_outer_margin_units,
1348                                       params.rightmargin, default_unit);
1349         setEnabled(paper_->input_outer_margin, useGeom);
1350         setEnabled(paper_->choice_outer_margin_units, useGeom);
1351
1352         updateWidgetsFromLengthString(paper_->input_bottom_margin,
1353                                       paper_->choice_bottom_margin_units,
1354                                       params.bottommargin, default_unit);
1355         setEnabled(paper_->input_bottom_margin, useGeom);
1356         setEnabled(paper_->choice_bottom_margin_units, useGeom);
1357
1358         updateWidgetsFromLengthString(paper_->input_head_height,
1359                                       paper_->choice_head_height_units,
1360                                       params.headheight, default_unit);
1361         setEnabled(paper_->input_head_height, useGeom);
1362         setEnabled(paper_->choice_head_height_units, useGeom);
1363
1364         updateWidgetsFromLengthString(paper_->input_head_sep,
1365                                       paper_->choice_head_sep_units,
1366                                       params.headsep, default_unit);
1367         setEnabled(paper_->input_head_sep, useGeom);
1368         setEnabled(paper_->choice_head_sep_units, useGeom);
1369
1370         updateWidgetsFromLengthString(paper_->input_foot_skip,
1371                                       paper_->choice_foot_skip_units,
1372                                       params.footskip, default_unit);
1373         setEnabled(paper_->input_foot_skip, useGeom);
1374         setEnabled(paper_->choice_foot_skip_units, useGeom);
1375
1376         fl_set_focus_object(paper_->form, paper_->choice_papersize);
1377 }
1378
1379
1380 void FormDocument::bullets_update(BufferParams const & params)
1381 {
1382         if (!bullets_.get() ||
1383             ((XpmVersion<4) ||
1384              (XpmVersion==4 && XpmRevision<7)))
1385                 return;
1386
1387         bool const isLinuxDoc = kernel().docType() == Kernel::LINUXDOC;
1388         setEnabled(fbullet, !isLinuxDoc);
1389
1390         if (isLinuxDoc) return;
1391
1392         fl_set_button(bullets_->radio_depth_1, 1);
1393         fl_set_input(bullets_->input_latex,
1394                      params.user_defined_bullet(0).getText().c_str());
1395         fl_set_choice(bullets_->choice_size,
1396                       params.user_defined_bullet(0).getSize() + 2);
1397 }
1398
1399
1400 void FormDocument::branch_update(BufferParams const & params)
1401 {
1402         if (!branch_.get())
1403                 return;
1404
1405         branchlist_ = params.branchlist();
1406
1407         rebuild_all_branches_browser();
1408         string const current_branch =
1409                 fl_get_browser_maxline(branch_->browser_all_branches) == 0 ?
1410                 "none" :
1411                 fl_get_browser_line(branch_->browser_all_branches, 1);
1412
1413         // display proper selection...
1414         rebuild_selected_branches_browser();
1415
1416         // display proper colour...
1417         RGBColor rgb;
1418         if (current_branch == "none")
1419                 fl_getmcolor(FL_COL1, &rgb.r, &rgb.g, &rgb.b);
1420         else {
1421                 Branch * branch = branchlist_.find(current_branch);
1422                 if (branch)
1423                         rgb = branch->getColor();
1424                 else
1425                         fl_getmcolor(FL_COL1, &rgb.r, &rgb.g, &rgb.b);
1426         }
1427
1428         fl_mapcolor(GUI_COLOR_CHOICE, rgb.r, rgb.g, rgb.b);
1429         fl_redraw_object(branch_->button_color);
1430
1431         setEnabled(branch_->button_select,
1432                 (fl_get_browser(branch_->browser_all_branches) > 0));
1433         setEnabled(branch_->button_deselect,
1434                 (fl_get_browser(branch_->browser_selection) > 0));
1435         setEnabled(branch_->button_remove_branch,
1436                 (fl_get_browser(branch_->browser_all_branches) > 0));
1437         setEnabled(branch_->button_modify,
1438                 (fl_get_browser(branch_->browser_all_branches) > 0));
1439 }
1440
1441
1442 void FormDocument::checkReadOnly()
1443 {
1444         if (bc().readOnly(kernel().isBufferReadonly())) {
1445                 postWarning(_("Document is read-only."
1446                               " No changes to layout permitted."));
1447         } else {
1448                 clearMessage();
1449         }
1450 }
1451
1452
1453 void FormDocument::ChoiceBulletSize(FL_OBJECT * ob, long /*data*/)
1454 {
1455         BufferParams & param = controller().params();
1456
1457         // convert from 1-6 range to -1-4
1458         param.temp_bullet(current_bullet_depth).setSize(fl_get_choice(ob) - 2);
1459         fl_set_input(bullets_->input_latex,
1460                      param.temp_bullet(current_bullet_depth).getText().c_str());
1461 }
1462
1463
1464 void FormDocument::InputBulletLaTeX(FL_OBJECT *, long)
1465 {
1466         BufferParams & param = controller().params();
1467
1468         param.temp_bullet(current_bullet_depth).
1469                 setText(getString(bullets_->input_latex));
1470 }
1471
1472
1473 void FormDocument::BulletDepth(FL_OBJECT * ob)
1474 {
1475         /* Should I do the following:                                 */
1476         /*  1. change to the panel that the current bullet belongs in */
1477         /*  2. show that bullet as selected                           */
1478         /*  3. change the size setting to the size of the bullet in Q.*/
1479         /*  4. display the latex equivalent in the latex box          */
1480         /*                                                            */
1481         /* I'm inclined to just go with 3 and 4 at the moment and     */
1482         /* maybe try to support the others later                      */
1483         BufferParams & param = controller().params();
1484
1485         int data = 0;
1486         if (ob == bullets_->radio_depth_1)
1487                 data = 0;
1488         else if (ob == bullets_->radio_depth_2)
1489                 data = 1;
1490         else if (ob == bullets_->radio_depth_3)
1491                 data = 2;
1492         else if (ob == bullets_->radio_depth_4)
1493                 data = 3;
1494
1495         switch (fl_get_button_numb(ob)) {
1496         case 3:
1497                 // right mouse button resets to default
1498                 param.temp_bullet(data) = ITEMIZE_DEFAULTS[data];
1499         default:
1500                 current_bullet_depth = data;
1501                 fl_set_input(bullets_->input_latex,
1502                              param.temp_bullet(data).getText().c_str());
1503                 fl_set_choice(bullets_->choice_size,
1504                               param.temp_bullet(data).getSize() + 2);
1505         }
1506 }
1507
1508
1509 void FormDocument::BulletPanel(FL_OBJECT * ob)
1510 {
1511         /* Here we have to change the background pixmap to that selected */
1512         /* by the user. (eg. standard.xpm, psnfss1.xpm etc...)           */
1513
1514         int data = 0;
1515         if (ob == bullets_->radio_panel_standard)
1516                 data = 0;
1517         else if (ob == bullets_->radio_panel_maths)
1518                 data = 1;
1519         else if (ob == bullets_->radio_panel_ding2)
1520                 data = 2;
1521         else if (ob == bullets_->radio_panel_ding3)
1522                 data = 3;
1523         else if (ob == bullets_->radio_panel_ding4)
1524                 data = 4;
1525         else if (ob == bullets_->radio_panel_ding1)
1526                 data = 5;
1527
1528         if (data != current_bullet_panel) {
1529                 fl_freeze_form(bullets_->form);
1530                 current_bullet_panel = data;
1531
1532                 /* free the current pixmap */
1533                 fl_free_bmtable_pixmap(bullets_->bmtable_panel);
1534                 string new_panel;
1535                 if (ob == bullets_->radio_panel_standard) {
1536                         new_panel = "standard";
1537                 } else if (ob == bullets_->radio_panel_maths ) {
1538                         new_panel = "amssymb";
1539                 } else if (ob == bullets_->radio_panel_ding2) {
1540                         new_panel = "psnfss1";
1541                 } else if (ob == bullets_->radio_panel_ding3) {
1542                         new_panel = "psnfss2";
1543                 } else if (ob == bullets_->radio_panel_ding4) {
1544                         new_panel = "psnfss3";
1545                 } else if (ob == bullets_->radio_panel_ding1) {
1546                         new_panel = "psnfss4";
1547                 } else {
1548                         /* something very wrong happened */
1549                         // play it safe for now but should be an exception
1550                         current_bullet_panel = 0;  // standard panel
1551                         new_panel = "standard";
1552                 }
1553                 new_panel += ".xpm";
1554                 fl_set_bmtable_pixmap_file(bullets_->bmtable_panel, 6, 6,
1555                                            libFileSearch("images", new_panel).c_str());
1556                 fl_redraw_object(bullets_->bmtable_panel);
1557                 fl_unfreeze_form(bullets_->form);
1558         }
1559 }
1560
1561
1562 void FormDocument::BulletBMTable(FL_OBJECT * ob, long /*data*/)
1563 {
1564         /* handle the user input by setting the current bullet depth's pixmap */
1565         /* to that extracted from the current chosen position of the BMTable  */
1566         /* Don't forget to free the button's old pixmap first.                */
1567
1568         BufferParams & param = controller().params();
1569         int bmtable_button = fl_get_bmtable(ob);
1570
1571         /* try to keep the button held down till another is pushed */
1572         /*  fl_set_bmtable(ob, 1, bmtable_button); */
1573         param.temp_bullet(current_bullet_depth).setFont(current_bullet_panel);
1574         param.temp_bullet(current_bullet_depth).setCharacter(bmtable_button);
1575         fl_set_input(bullets_->input_latex,
1576                      param.temp_bullet(current_bullet_depth).getText().c_str());
1577 }
1578
1579
1580 void FormDocument::CheckChoiceClass()
1581 {
1582         BufferParams & params = controller().params();
1583
1584         textclass_type const tc = fl_get_combox(class_->combox_class) - 1;
1585
1586         if (controller().loadTextclass(tc)) {
1587                 params.textclass = tc;
1588
1589                 if (lyxrc.auto_reset_options) {
1590                         params.useClassDefaults();
1591                         UpdateLayoutDocument(params);
1592                 } else {
1593                         // update the params which are needed in any case
1594                         // (fontsizes, pagestyle)
1595                         UpdateClassParams(params);
1596                 }
1597
1598         } else {
1599                 int const revert = int(params.textclass);
1600                 fl_set_combox(class_->combox_class, revert + 1);
1601         }
1602 }
1603
1604
1605 void FormDocument::UpdateLayoutDocument(BufferParams const & params)
1606 {
1607         if (!dialog_.get())
1608                 return;
1609
1610         checkReadOnly();
1611         class_update(params);
1612         font_update(params);
1613         paper_update(params);
1614         language_update(params);
1615         options_update(params);
1616         bullets_update(params);
1617 }
1618
1619 } // namespace frontend
1620 } // namespace lyx