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