]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormPreferences.C
b7f30e41731dddb65b08d04d8baf60f3f562160c
[features.git] / src / frontends / xforms / FormPreferences.C
1 /**
2  * \file FormPreferences.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "FormPreferences.h"
14 #include "ControlPrefs.h"
15 #include "forms/form_preferences.h"
16
17 #include "FormColorpicker.h"
18 #include "forms_gettext.h"
19 #include "input_validators.h"
20 #include "xformsBC.h"
21
22 #include "controllers/helper_funcs.h" // getSecond
23
24 #include "buffer.h"
25 #include "converter.h"
26 #include "format.h"
27 #include "frnt_lang.h"
28 #include "lyxfont.h"
29
30 #include "support/lstrings.h"
31 #include "support/tostr.h"
32 #include "support/path_defines.h"
33 #include "support/filetools.h"
34
35 #include "lyx_forms.h"
36 #include "combox.h"
37
38 #include <iomanip>
39
40 using lyx::support::AddName;
41 using lyx::support::ChangeExtension;
42 using lyx::support::rtrim;
43 using lyx::support::strToDbl;
44 using lyx::support::trim;
45 using lyx::support::user_lyxdir;
46
47 using std::endl;
48 using std::make_pair;
49 using std::max;
50 using std::min;
51
52 using std::pair;
53 using std::vector;
54
55
56 namespace {
57
58 // These should probably go inside the class definition...
59 Formats    local_formats;
60 Converters local_converters;
61
62 string makeFontName(string const & family, string const & foundry)
63 {
64         if (foundry.empty())
65                 return family;
66         return family + ',' + foundry;
67 }
68
69
70 pair<string,string> parseFontName(string const & name)
71 {
72         string::size_type const idx = name.find(',');
73         if (idx == string::npos)
74                 return make_pair(name, string());
75         return make_pair(name.substr(0, idx),
76                          name.substr(idx+1));
77 }
78
79
80
81 #if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL < 2)
82 bool const scalableTabfolders = false;
83 #else
84 bool const scalableTabfolders = true;
85 #endif
86
87 } // namespace anon
88
89
90 typedef FormCB<ControlPrefs, FormDB<FD_preferences> > base_class;
91
92
93 FormPreferences::FormPreferences()
94         : base_class(_("Preferences"), scalableTabfolders),
95           colors_(*this), converters_(*this), inputs_misc_(*this),
96           formats_(*this), interface_(*this), language_(*this),
97           lnf_misc_(*this), identity_(*this), outputs_misc_(*this),
98           paths_(*this), printer_(*this), screen_fonts_(*this),
99           spelloptions_(*this)
100 {
101 }
102
103
104 void FormPreferences::redraw()
105 {
106         if (!(form() && form()->visible))
107                 return;
108         fl_redraw_form(form());
109
110         FL_FORM * form2 = fl_get_active_folder(dialog_->tabfolder_prefs);
111         if (!(form2 && form2->visible))
112                 return;
113         fl_redraw_form(form2);
114
115         FL_FORM * form3 = 0;
116         if (form2 == converters_tab_->form)
117                 form3 = fl_get_active_folder(converters_tab_->tabfolder_inner);
118
119         else if (form2 == look_n_feel_tab_->form)
120                 form3 = fl_get_active_folder(look_n_feel_tab_->tabfolder_inner);
121
122         else if (form2 == inputs_tab_->form)
123                 form3 = fl_get_active_folder(inputs_tab_->tabfolder_inner);
124
125         else if (form2 == outputs_tab_->form)
126                 form3 = fl_get_active_folder(outputs_tab_->tabfolder_inner);
127
128         else if (form2 == lang_opts_tab_->form)
129                 form3 = fl_get_active_folder(lang_opts_tab_->tabfolder_inner);
130
131         if (form3 && form3->visible)
132                 fl_redraw_form(form3);
133 }
134
135
136 void FormPreferences::hide()
137 {
138         // We need to hide the active tabfolder otherwise we get a
139         // BadDrawable error from X window and LyX crashes without saving.
140         FL_FORM * inner_form = fl_get_active_folder(dialog_->tabfolder_prefs);
141         if (inner_form && inner_form->visible)
142                 fl_hide_form(inner_form);
143         FormBase::hide();
144 }
145
146
147 void FormPreferences::build()
148 {
149         dialog_.reset(build_preferences(this));
150
151         // Manage the restore, save, apply and cancel/close buttons
152         bcview().setOK(dialog_->button_ok);
153         bcview().setApply(dialog_->button_apply);
154         bcview().setCancel(dialog_->button_close);
155         bcview().setRestore(dialog_->button_restore);
156
157         // Allow the base class to control messages
158         setMessageWidget(dialog_->text_warning);
159
160         // build the tab folders
161         converters_tab_.reset(build_preferences_inner_tab(this));
162         look_n_feel_tab_.reset(build_preferences_inner_tab(this));
163         inputs_tab_.reset(build_preferences_inner_tab(this));
164         outputs_tab_.reset(build_preferences_inner_tab(this));
165         lang_opts_tab_.reset(build_preferences_inner_tab(this));
166
167         // build actual tabfolder contents
168         // these will become nested tabfolders
169         colors_.build();
170         converters_.build();
171         formats_.build();
172         inputs_misc_.build();
173         interface_.build();
174         language_.build();
175         lnf_misc_.build();
176         identity_.build();
177         outputs_misc_.build();
178         paths_.build();
179         printer_.build();
180         screen_fonts_.build();
181         spelloptions_.build();
182
183         // Enable the tabfolders to be rescaled correctly.
184         if (scalableTabfolders) {
185                 FL_OBJECT * folder = dialog_->tabfolder_prefs;
186                 fl_set_tabfolder_autofit(folder, FL_FIT);
187
188                 folder = look_n_feel_tab_->tabfolder_inner;
189                 fl_set_tabfolder_autofit(folder, FL_FIT);
190
191                 folder = converters_tab_->tabfolder_inner;
192                 fl_set_tabfolder_autofit(folder, FL_FIT);
193
194                 folder = inputs_tab_->tabfolder_inner;
195                 fl_set_tabfolder_autofit(folder, FL_FIT);
196
197                 folder = outputs_tab_->tabfolder_inner;
198                 fl_set_tabfolder_autofit(folder, FL_FIT);
199
200                 folder = lang_opts_tab_->tabfolder_inner;
201                 fl_set_tabfolder_autofit(folder, FL_FIT);
202         }
203
204         // Stack tabs
205         // Now add them to the tabfolder
206         fl_addto_tabfolder(dialog_->tabfolder_prefs,
207                            _("Look & Feel").c_str(),
208                            look_n_feel_tab_->form);
209         fl_addto_tabfolder(dialog_->tabfolder_prefs,
210                            _("Lang Opts").c_str(),
211                            lang_opts_tab_->form);
212         fl_addto_tabfolder(dialog_->tabfolder_prefs,
213                            _("Conversion").c_str(),
214                            converters_tab_->form);
215         fl_addto_tabfolder(dialog_->tabfolder_prefs,
216                            _("Inputs").c_str(),
217                            inputs_tab_->form);
218         fl_addto_tabfolder(dialog_->tabfolder_prefs,
219                            _("Outputs").c_str(),
220                            outputs_tab_->form);
221
222         // now build the nested tabfolders
223         // Starting with look and feel
224         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
225                            _("Screen Fonts").c_str(),
226                            screen_fonts_.dialog()->form);
227         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
228                            _("Interface").c_str(),
229                            interface_.dialog()->form);
230         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
231                            _("Colors").c_str(),
232                            colors_.dialog()->form);
233         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
234                            _("Misc").c_str(),
235                            lnf_misc_.dialog()->form);
236         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
237                            _("Identity").c_str(),
238                            identity_.dialog()->form);
239
240         // then build converters
241         fl_addto_tabfolder(converters_tab_->tabfolder_inner,
242                            _("Formats").c_str(),
243                            formats_.dialog()->form);
244         fl_addto_tabfolder(converters_tab_->tabfolder_inner,
245                            _("Converters").c_str(),
246                            converters_.dialog()->form);
247
248         // then build inputs
249         // Paths should probably go in a few inner_tab called Files
250         fl_addto_tabfolder(inputs_tab_->tabfolder_inner,
251                            _("Paths").c_str(),
252                            paths_.dialog()->form);
253         fl_addto_tabfolder(inputs_tab_->tabfolder_inner,
254                            _("Misc").c_str(),
255                            inputs_misc_.dialog()->form);
256
257         // then building outputs
258         fl_addto_tabfolder(outputs_tab_->tabfolder_inner,
259                            _("Printer").c_str(),
260                            printer_.dialog()->form);
261         fl_addto_tabfolder(outputs_tab_->tabfolder_inner,
262                            _("Misc").c_str(),
263                            outputs_misc_.dialog()->form);
264
265         // then building usage
266         fl_addto_tabfolder(lang_opts_tab_->tabfolder_inner,
267                            _("Spell checker").c_str(),
268                            spelloptions_.dialog()->form);
269         fl_addto_tabfolder(lang_opts_tab_->tabfolder_inner,
270                            _("Language").c_str(),
271                            language_.dialog()->form);
272 }
273
274
275 void FormPreferences::apply()
276 {
277         // set the new lyxrc entries
278         // many of these need to trigger other functions when the assignment
279         // is made.  For example, screen zoom and font types.  These could be
280         // handled either by signals/slots in lyxrc or just directly call the
281         // associated functions here.
282         // There are other problems with this scheme.  We really should check
283         // what we copy to make sure that it really is necessary to do things
284         // like update the screen fonts because that flushes the textcache
285         // and other stuff which may cost us a lot on slower/high-load
286         // machines.
287
288         LyXRC & rc(controller().rc());
289
290         colors_.apply();
291         formats_.apply();    // Must be before converters_.apply()
292         converters_.apply();
293         inputs_misc_.apply(rc);
294         interface_.apply(rc);
295         language_.apply(rc);
296         lnf_misc_.apply(rc);
297         identity_.apply(rc);
298         outputs_misc_.apply(rc);
299         paths_.apply(rc);
300         printer_.apply(rc);
301         screen_fonts_.apply(rc);
302         spelloptions_.apply(rc);
303
304         // The "Save" button has been pressed.
305         if (controller().isClosing() && colors_.modifiedXformsPrefs) {
306                 string const filename =
307                         AddName(user_lyxdir(), "preferences.xform");
308                 colors_.modifiedXformsPrefs = !XformsColor::write(filename);
309         }
310 }
311
312
313 string const FormPreferences::getFeedback(FL_OBJECT * ob)
314 {
315         BOOST_ASSERT(ob);
316
317         if (ob->form->fdui == colors_.dialog())
318                 return colors_.feedback(ob);
319         if (ob->form->fdui == converters_.dialog())
320                 return converters_.feedback(ob);
321         if (ob->form->fdui == formats_.dialog())
322                 return formats_.feedback(ob);
323         if (ob->form->fdui == inputs_misc_.dialog())
324                 return inputs_misc_.feedback(ob);
325         if (ob->form->fdui == interface_.dialog())
326                 return interface_.feedback(ob);
327         if (ob->form->fdui == language_.dialog())
328                 return language_.feedback(ob);
329         if (ob->form->fdui == lnf_misc_.dialog())
330                 return lnf_misc_.feedback(ob);
331         if (ob->form->fdui == outputs_misc_.dialog())
332                 return outputs_misc_.feedback(ob);
333         if (ob->form->fdui == paths_.dialog())
334                 return paths_.feedback(ob);
335         if (ob->form->fdui == printer_.dialog())
336                 return printer_.feedback(ob);
337         if (ob->form->fdui == screen_fonts_.dialog())
338                 return screen_fonts_.feedback(ob);
339         if (ob->form->fdui == spelloptions_.dialog())
340                 return spelloptions_.feedback(ob);
341
342         return string();
343 }
344
345
346 ButtonPolicy::SMInput FormPreferences::input(FL_OBJECT * ob, long)
347 {
348         BOOST_ASSERT(ob);
349
350         bool valid = true;
351
352         // whatever checks you need to ensure the user hasn't entered
353         // some totally ridiculous value somewhere.  Change activate to suit.
354         // comments before each test describe what is _valid_
355
356         if (ob->form->fdui == colors_.dialog()) {
357                 colors_.input(ob);
358         } else if (ob->form->fdui == converters_.dialog()) {
359                 valid = converters_.input(ob);
360         } else if (ob->form->fdui == formats_.dialog()) {
361                 valid = formats_.input(ob);
362         } else if  (ob->form->fdui == interface_.dialog()) {
363                 valid = interface_.input(ob);
364         } else if  (ob->form->fdui == language_.dialog()) {
365                 valid = language_.input(ob);
366         } else if  (ob->form->fdui == paths_.dialog()) {
367                 valid = paths_.input(ob);
368         } else if  (ob->form->fdui == screen_fonts_.dialog()) {
369                 valid = screen_fonts_.input();
370         } else if  (ob->form->fdui == spelloptions_.dialog()) {
371                 valid = spelloptions_.input(ob);
372         }
373
374         return valid ? ButtonPolicy::SMI_VALID : ButtonPolicy::SMI_INVALID;
375 }
376
377
378 void FormPreferences::update()
379 {
380         if (!dialog_.get()) return;
381
382         LyXRC const & rc(controller().rc());
383
384         // read lyxrc entries
385         colors_.update();
386         formats_.update();   // Must be before converters_.update()
387         converters_.update();
388         inputs_misc_.update(rc);
389         interface_.update(rc);
390         language_.update(rc);
391         lnf_misc_.update(rc);
392         identity_.update(rc);
393         outputs_misc_.update(rc);
394         paths_.update(rc);
395         printer_.update(rc);
396         screen_fonts_.update(rc);
397         spelloptions_.update(rc);
398 }
399
400
401 FormPreferences::Colors::Colors(FormPreferences & p)
402         : modifiedXformsPrefs(false), parent_(p)
403 {}
404
405
406 FD_preferences_colors const * FormPreferences::Colors::dialog()
407 {
408         return dialog_.get();
409 }
410
411
412 void FormPreferences::Colors::apply()
413 {
414         bool modifiedText = false;
415         bool modifiedBackground = false;
416
417         for (vector<XformsColor>::const_iterator cit = xformsColorDB.begin();
418              cit != xformsColorDB.end(); ++cit) {
419                 RGBColor col;
420                 fl_getmcolor(cit->colorID, &col.r, &col.g, &col.b);
421                 if (col != cit->color()) {
422                         modifiedXformsPrefs = true;
423                         if (cit->colorID == FL_BLACK)
424                                 modifiedText = true;
425                         if (cit->colorID == FL_COL1)
426                                 modifiedBackground = true;
427                 }
428         }
429
430         if (modifiedXformsPrefs) {
431                 for (vector<XformsColor>::const_iterator cit =
432                              xformsColorDB.begin();
433                      cit != xformsColorDB.end(); ++cit) {
434                         fl_mapcolor(cit->colorID, cit->r, cit->g, cit->b);
435
436                         if (modifiedText && cit->colorID == FL_BLACK) {
437                                 AdjustVal(FL_INACTIVE, FL_BLACK, 0.5);
438                         }
439
440                         if (modifiedBackground && cit->colorID == FL_COL1) {
441                                 AdjustVal(FL_MCOL,      FL_COL1, 0.1);
442                                 AdjustVal(FL_TOP_BCOL,  FL_COL1, 0.1);
443                                 AdjustVal(FL_LEFT_BCOL, FL_COL1, 0.1);
444
445                                 AdjustVal(FL_RIGHT_BCOL,  FL_COL1, -0.5);
446                                 AdjustVal(FL_BOTTOM_BCOL, FL_COL1, -0.5);
447                         }
448
449                         if (cit->colorID == GUI_COLOR_CURSOR) {
450                                 fl_mapcolor(GUI_COLOR_CURSOR,
451                                             cit->r, cit->g, cit->b);
452                                 setCursorColor(GUI_COLOR_CURSOR);
453                         }
454                 }
455                 parent_.controller().redrawGUI();
456         }
457
458         // Now do the same for the LyX LColors...
459         for (vector<NamedColor>::const_iterator cit = lyxColorDB.begin();
460              cit != lyxColorDB.end(); ++cit) {
461                 LColor::color lc = lcolor.getFromGUIName(cit->getname());
462                 if (lc == LColor::inherit) continue;
463
464                 // Create a valid X11 name of the form "#rrggbb"
465                 string const hexname = X11hexname(cit->color());
466
467                 if (lcolor.getX11Name(lc) != hexname) {
468                         lyxerr[Debug::GUI]
469                                 << "FormPreferences::Colors::apply: "
470                                 << "resetting LColor " << lcolor.getGUIName(lc)
471                                 << " from \"" << lcolor.getX11Name(lc)
472                                 << "\" to \"" << hexname << "\"."
473                                 << endl;
474
475                         parent_.controller().setColor(lc, hexname);
476                 }
477         }
478 }
479
480
481 void FormPreferences::Colors::build()
482 {
483         picker_.reset(new FormColorpicker);
484         dialog_.reset(build_preferences_colors(&parent_));
485
486         fl_set_object_color(dialog_->button_color,
487                             GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
488
489         // set up the feedback mechanism
490         setPrehandler(dialog_->browser_lyx_objs);
491         setPrehandler(dialog_->button_color);
492         setPrehandler(dialog_->button_modify);
493 }
494
495
496 string const
497 FormPreferences::Colors::feedback(FL_OBJECT const * const ob) const
498 {
499         if (ob == dialog_->browser_lyx_objs)
500                 return _("LyX objects that can be assigned a color.");
501
502         if (ob == dialog_->button_modify)
503                 return _("Modify the LyX object's color. Note: you must then \"Apply\" the change.");
504
505         return string();
506 }
507
508
509 void FormPreferences::Colors::input(FL_OBJECT const * const ob)
510 {
511         if (ob == dialog_->browser_lyx_objs) {
512                 InputBrowserLyX();
513
514         } else if (ob == dialog_->button_modify) {
515                 Modify();
516         }
517 }
518
519
520 void FormPreferences::Colors::AdjustVal(int colAdjust, int colParent,
521                                         double addVal) const
522 {
523         RGBColor rgb;
524         fl_getmcolor(colParent, &rgb.r, &rgb.g, &rgb.b);
525
526         HSVColor hsv(rgb);
527         hsv.v += addVal;
528         hsv.v = min(1.0, max(0.0, hsv.v));
529
530         rgb = RGBColor(hsv);
531         fl_mapcolor(colAdjust, rgb.r, rgb.g, rgb.b);
532 }
533
534
535 void FormPreferences::Colors::InputBrowserLyX() const
536 {
537         vector<NamedColor>::size_type const selLyX =
538                 fl_get_browser(dialog_->browser_lyx_objs);
539         if (selLyX < 1) return;
540
541         // Is the choice an Xforms color...
542         RGBColor col;
543
544         if (selLyX - 1 < xformsColorDB.size()) {
545                 vector<XformsColor>::size_type const i = selLyX - 1;
546                 col = xformsColorDB[i].color();
547         }
548         // or a LyX Logical color?
549         else {
550                 vector<NamedColor>::size_type const i = selLyX - 1 -
551                         xformsColorDB.size();
552                 col = lyxColorDB[i].color();
553         }
554
555         fl_freeze_form(dialog_->form);
556
557         fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
558         fl_redraw_object(dialog_->button_color);
559
560         fl_unfreeze_form(dialog_->form);
561 }
562
563
564 void FormPreferences::Colors::LoadBrowserLyX()
565 {
566         if (!dialog_->browser_lyx_objs->visible)
567                 return;
568
569         // First, define the modifiable xforms colors
570         xformsColorDB.clear();
571         XformsColor xcol;
572
573         xcol.name = _("GUI background");
574         xcol.colorID = FL_COL1;
575         fl_getmcolor(FL_COL1, &xcol.r, &xcol.g, &xcol.b);
576
577         xformsColorDB.push_back(xcol);
578
579         xcol.name = _("GUI text");
580         xcol.colorID = FL_BLACK;
581         fl_getmcolor(FL_BLACK, &xcol.r, &xcol.g, &xcol.b);
582
583         xformsColorDB.push_back(xcol);
584
585         xcol.name = _("GUI selection");
586         xcol.colorID = FL_YELLOW;
587         fl_getmcolor(FL_YELLOW, &xcol.r, &xcol.g, &xcol.b);
588
589         xformsColorDB.push_back(xcol);
590
591         xcol.name = _("GUI pointer");
592         xcol.colorID = GUI_COLOR_CURSOR;
593         fl_getmcolor(GUI_COLOR_CURSOR, &xcol.r, &xcol.g, &xcol.b);
594
595         xformsColorDB.push_back(xcol);
596
597         // Now create the the LyX LColors database
598         lyxColorDB.clear();
599         for (int i=0; i<LColor::ignore; ++i) {
600                 LColor::color lc = static_cast<LColor::color>(i);
601                 if (lc == LColor::none
602                     || lc == LColor::black
603                     || lc == LColor::white
604                     || lc == LColor::red
605                     || lc == LColor::green
606                     || lc == LColor::blue
607                     || lc == LColor::cyan
608                     || lc == LColor::magenta
609                     || lc == LColor::yellow
610                     || lc == LColor::inherit
611                     || lc == LColor::ignore) continue;
612
613                 RGBColor col;
614                 bool const success = getRGBColor(lc, col.r, col.g, col.b);
615                 if (!success) {
616                         lyxerr << "FormPreferences::Colors::LoadBrowserLyX:\n"
617                                << "LColor " << lcolor.getLyXName(lc)
618                                << ": X can't find color \""
619                                << lcolor.getX11Name(lc)
620                                << "\". Set to \"black\"!" << endl;
621
622                         string const arg = lcolor.getLyXName(lc) + " black";
623                         parent_.controller().setColor(lc, "black");
624                         continue;
625                 }
626
627                 // Create a valid X11 name of the form "#rrggbb" and change the
628                 // LColor X11name to this. Don't want to trigger a redraw,
629                 // as we're just changing the name not the RGB values.
630                 // Also reset the system_lcolor names, so that we don't output
631                 // unnecessary changes.
632                 string const hexname = X11hexname(col);
633
634                 if (lcolor.getX11Name(lc) != hexname) {
635                         lcolor.setColor(lc, hexname);
636                         system_lcolor.setColor(lc, hexname);
637                 }
638
639                 // Finally, push the color onto the database
640                 NamedColor ncol(lcolor.getGUIName(lc), col);
641                 lyxColorDB.push_back(ncol);
642         }
643
644         // Now construct the browser
645         FL_OBJECT * colbr = dialog_->browser_lyx_objs;
646         fl_freeze_form(dialog_->form);
647         fl_clear_browser(colbr);
648         for (vector<XformsColor>::const_iterator cit = xformsColorDB.begin();
649              cit != xformsColorDB.end(); ++cit) {
650                 fl_addto_browser(colbr, cit->getname().c_str());
651         }
652         for (vector<NamedColor>::const_iterator cit = lyxColorDB.begin();
653              cit != lyxColorDB.end(); ++cit) {
654                 fl_addto_browser(colbr, cit->getname().c_str());
655         }
656
657         // just to be safe...
658         fl_set_browser_topline(dialog_->browser_lyx_objs, 1);
659         fl_select_browser_line(dialog_->browser_lyx_objs, 1);
660         fl_unfreeze_form(dialog_->form);
661
662         InputBrowserLyX();
663 }
664
665
666 void FormPreferences::Colors::Modify()
667 {
668         vector<NamedColor>::size_type const selLyX =
669                 fl_get_browser(dialog_->browser_lyx_objs);
670         if (selLyX < 1)
671                 return;
672
673         RGBColor before;
674         fl_getmcolor(GUI_COLOR_CHOICE, &before.r, &before.g, &before.b);
675
676         RGBColor col = picker_->requestColor(before);
677         if (before == col)
678                 return;
679
680         fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
681         fl_redraw_object(dialog_->button_color);
682
683         // Is the choice an Xforms color...
684         if (selLyX - 1 < xformsColorDB.size()) {
685                 vector<XformsColor>::size_type const i = selLyX - 1;
686                 xformsColorDB[i].r  = col.r;
687                 xformsColorDB[i].g  = col.g;
688                 xformsColorDB[i].b  = col.b;
689         }
690         // or a LyX Logical color?
691         else {
692                 vector<NamedColor>::size_type const i = selLyX - 1 -
693                         xformsColorDB.size();
694                 lyxColorDB[i].r  = col.r;
695                 lyxColorDB[i].g  = col.g;
696                 lyxColorDB[i].b  = col.b;
697         }
698 }
699
700
701 FormPreferences::Converters::Converters(FormPreferences & p)
702         : parent_(p)
703 {}
704
705
706 FD_preferences_converters const * FormPreferences::Converters::dialog()
707 {
708         return dialog_.get();
709 }
710
711
712 void FormPreferences::Converters::apply() const
713 {
714         parent_.controller().setConverters(local_converters);
715 }
716
717
718 void FormPreferences::Converters::build()
719 {
720         dialog_.reset(build_preferences_converters(&parent_));
721
722         fl_set_input_return(dialog_->input_converter, FL_RETURN_CHANGED);
723         fl_set_input_return(dialog_->input_flags, FL_RETURN_CHANGED);
724
725         // set up the feedback mechanism
726         setPrehandler(dialog_->browser_all);
727         setPrehandler(dialog_->button_delete);
728         setPrehandler(dialog_->button_add);
729         setPrehandler(dialog_->input_converter);
730         setPrehandler(dialog_->choice_from);
731         setPrehandler(dialog_->choice_to);
732         setPrehandler(dialog_->input_flags);
733 }
734
735
736 string const
737 FormPreferences::Converters::feedback(FL_OBJECT const * const ob) const
738 {
739         if (ob == dialog_->browser_all)
740                 return _("All explicitly defined converters for LyX");
741
742         if (ob == dialog_->choice_from)
743                 return _("Convert \"from\" this format");
744
745         if (ob == dialog_->choice_to)
746                 return _("Convert \"to\" this format");
747
748         if (ob == dialog_->input_converter)
749                 return _("The conversion command. $$i is the input file name, "
750                          "$$b is the file name without its extension and $$o is "
751                          "the name of the output file. $$s can be used as path to "
752                          "LyX's own collection of conversion scripts.");
753
754         if (ob == dialog_->input_flags)
755                 return _("Extra information for the Converter class, whether and "
756                          "how to parse the result, and various other things.");
757
758         if (ob == dialog_->button_delete)
759                 return _("Remove the current converter from the list of available "
760                          "converters. Note: you must then \"Apply\" the change.");
761
762         if (ob == dialog_->button_add) {
763                 if (string(ob->label) == _("Add"))
764                         return _("Add the current converter to the list of available "
765                                  "converters. Note: you must then \"Apply\" the change.");
766                 else
767                         return _("Modify the contents of the current converter. "
768                                  "Note: you must then \"Apply\" the change.");
769         }
770
771         return string();
772 }
773
774
775 bool FormPreferences::Converters::input(FL_OBJECT const * const ob)
776 {
777         if (ob == dialog_->browser_all)
778                 return Browser();
779
780         if (ob == dialog_->choice_from
781             || ob == dialog_->choice_to
782             || ob == dialog_->input_converter
783             || ob == dialog_->input_flags)
784                 return Input();
785
786         if (ob == dialog_->button_add)
787                 return Add();
788
789         if (ob == dialog_->button_delete)
790                 return erase();
791
792         return true;
793 }
794
795
796 void FormPreferences::Converters::update()
797 {
798         local_converters = converters;
799         local_converters.update(local_formats);
800         UpdateBrowser();
801 }
802
803
804 void FormPreferences::Converters::UpdateBrowser()
805 {
806         local_converters.sort();
807
808         fl_freeze_form(dialog_->form);
809         fl_clear_browser(dialog_->browser_all);
810         for (::Converters::const_iterator cit = local_converters.begin();
811              cit != local_converters.end(); ++cit) {
812                 string const name = cit->From->prettyname() + " -> "
813                         + cit->To->prettyname();
814                 fl_addto_browser(dialog_->browser_all, name.c_str());
815         }
816         Input();
817         fl_unfreeze_form(dialog_->form);
818 }
819
820
821 bool FormPreferences::Converters::Add()
822 {
823         string const from = GetFrom();
824         string const to = GetTo();
825         string const command = fl_get_input(dialog_->input_converter);
826         string const flags = fl_get_input(dialog_->input_flags);
827
828         Converter const * old = local_converters.getConverter(from, to);
829         local_converters.add(from, to, command, flags);
830         if (!old) {
831                 local_converters.updateLast(local_formats);
832                 UpdateBrowser();
833         }
834         setEnabled(dialog_->button_add, false);
835
836         return true;
837 }
838
839
840 bool FormPreferences::Converters::Browser()
841 {
842         int const i = fl_get_browser(dialog_->browser_all);
843         if (i <= 0) return false;
844
845         fl_freeze_form(dialog_->form);
846
847         Converter const & c = local_converters.get(i - 1);
848         int j = local_formats.getNumber(c.from);
849         if (j >= 0)
850                 fl_set_choice(dialog_->choice_from, j + 1);
851
852         j = local_formats.getNumber(c.to);
853         if (j >= 0)
854                 fl_set_choice(dialog_->choice_to, j + 1);
855
856         fl_set_input(dialog_->input_converter, c.command.c_str());
857         fl_set_input(dialog_->input_flags, c.flags.c_str());
858
859         fl_set_object_label(dialog_->button_add, idex(_("Modify|#M")).c_str());
860         fl_set_button_shortcut(dialog_->button_add,
861                                scex(_("Modify|#M")).c_str(), 1);
862
863         setEnabled(dialog_->button_add,    false);
864         setEnabled(dialog_->button_delete, true);
865
866         fl_unfreeze_form(dialog_->form);
867         return false;
868 }
869
870
871 bool FormPreferences::Converters::erase()
872 {
873         string const from = GetFrom();
874         string const to = GetTo();
875
876         local_converters.erase(from, to);
877         UpdateBrowser();
878         return true;
879 }
880
881
882 bool FormPreferences::Converters::Input()
883 {
884         string const from = GetFrom();
885         string const to = GetTo();
886         int const sel = local_converters.getNumber(from, to);
887
888         fl_freeze_form(dialog_->form);
889
890         if (sel < 0) {
891                 fl_set_object_label(dialog_->button_add,
892                                     idex(_("Add|#A")).c_str());
893                 fl_set_button_shortcut(dialog_->button_add,
894                                        scex(_("Add|#A")).c_str(), 1);
895
896                 fl_deselect_browser(dialog_->browser_all);
897                 setEnabled(dialog_->button_delete, false);
898
899         } else {
900                 fl_set_object_label(dialog_->button_add,
901                                     idex(_("Modify|#M")).c_str());
902                 fl_set_button_shortcut(dialog_->button_add,
903                                        scex(_("Modify|#M")).c_str(), 1);
904
905                 int top = max(sel-5, 0);
906                 fl_set_browser_topline(dialog_->browser_all, top);
907                 fl_select_browser_line(dialog_->browser_all, sel+1);
908                 setEnabled(dialog_->button_delete, true);
909         }
910
911         string const command = rtrim(fl_get_input(dialog_->input_converter));
912         bool const enable = !(command.empty() || from == to);
913         setEnabled(dialog_->button_add, enable);
914
915         fl_unfreeze_form(dialog_->form);
916         return false;
917 }
918
919
920 string const FormPreferences::Converters::GetFrom() const
921 {
922         ::Formats::FormatList::size_type const i =
923                   fl_get_choice(dialog_->choice_from);
924
925         if (i > 0 && i <= local_formats.size())
926                 return local_formats.get(i - 1).name();
927
928         lyxerr << "FormPreferences::Converters::GetFrom: No choice!" << endl;
929         return "???";
930 }
931
932
933 string const FormPreferences::Converters::GetTo() const
934 {
935         ::Formats::FormatList::size_type const i =
936                   fl_get_choice(dialog_->choice_to);
937
938         if (i > 0 && i <= local_formats.size())
939                 return local_formats.get(i - 1).name();
940
941         lyxerr << "FormPreferences::Converters::GetTo: No choice!" << endl;
942         return "???";
943 }
944
945
946 void FormPreferences::Converters::UpdateChoices() const
947 {
948         string choice;
949         for (::Formats::const_iterator cit = local_formats.begin();
950              cit != local_formats.end(); ++cit) {
951                 if (!choice.empty())
952                         choice += " | ";
953                 else
954                         choice += ' ';
955                 choice += cit->prettyname();
956         }
957         choice += ' ';
958
959         fl_clear_choice(dialog_->choice_from);
960         fl_addto_choice(dialog_->choice_from, choice.c_str());
961
962         fl_clear_choice(dialog_->choice_to);
963         fl_addto_choice(dialog_->choice_to, choice.c_str());
964 }
965
966
967 FormPreferences::Formats::Formats(FormPreferences &  p)
968         : parent_(p)
969 {}
970
971
972 FD_preferences_formats const * FormPreferences::Formats::dialog()
973 {
974         return dialog_.get();
975 }
976
977
978 void FormPreferences::Formats::apply() const
979 {
980         parent_.controller().setFormats(local_formats);
981 }
982
983
984 void FormPreferences::Formats::build()
985 {
986         dialog_.reset(build_preferences_formats(&parent_));
987
988         fl_set_input_return(dialog_->input_format, FL_RETURN_CHANGED);
989         fl_set_input_return(dialog_->input_viewer, FL_RETURN_CHANGED);
990         fl_set_input_return(dialog_->input_shrtcut, FL_RETURN_CHANGED);
991         fl_set_input_return(dialog_->input_gui_name, FL_RETURN_CHANGED);
992         fl_set_input_return(dialog_->input_extension, FL_RETURN_CHANGED);
993
994         fl_set_input_filter(dialog_->input_format, fl_lowercase_filter);
995
996         // set up the feedback mechanism
997         setPrehandler(dialog_->browser_all);
998         setPrehandler(dialog_->input_format);
999         setPrehandler(dialog_->input_gui_name);
1000         setPrehandler(dialog_->button_delete);
1001         setPrehandler(dialog_->button_add);
1002         setPrehandler(dialog_->input_extension);
1003         setPrehandler(dialog_->input_viewer);
1004         setPrehandler(dialog_->input_shrtcut);
1005 }
1006
1007
1008 string const
1009 FormPreferences::Formats::feedback(FL_OBJECT const * const ob) const
1010 {
1011         if (ob == dialog_->browser_all)
1012                 return  _("All the currently defined formats known to LyX.");
1013
1014         if (ob == dialog_->input_format)
1015                 return  _("The format identifier.");
1016
1017         if (ob == dialog_->input_gui_name)
1018                 return  _("The format name as it will appear in the menus.");
1019
1020         if (ob == dialog_->input_shrtcut)
1021                 return  _("The keyboard accelerator. Use a letter in the GUI name. "
1022                           "Case sensitive.");
1023
1024         if (ob == dialog_->input_extension)
1025                 return  _("Used to recognize the file. E.g., ps, pdf, tex.");
1026
1027         if (ob == dialog_->input_viewer)
1028                 return  _("The command used to launch the viewer application.");
1029
1030         if (ob == dialog_->button_delete)
1031                 return  _("Remove the current format from the list of available "
1032                           "formats. Note: you must then \"Apply\" the change.");
1033
1034         if (ob == dialog_->button_add) {
1035                 if (string(ob->label) == _("Add"))
1036                         return  _("Add the current format to the list of available "
1037                                   "formats. Note: you must then \"Apply\" the change.");
1038                 else
1039                         return  _("Modify the contents of the current format. Note: "
1040                                   "you must then \"Apply\" the change.");
1041         }
1042
1043         return string();
1044 }
1045
1046
1047 bool FormPreferences::Formats::input(FL_OBJECT const * const ob)
1048 {
1049         if (ob == dialog_->browser_all)
1050                 return Browser();
1051
1052         if (ob == dialog_->input_format
1053             || ob == dialog_->input_gui_name
1054             || ob == dialog_->input_shrtcut
1055             || ob == dialog_->input_extension
1056             || ob == dialog_->input_viewer)
1057                 return Input();
1058
1059         if (ob == dialog_->button_add)
1060                 return Add();
1061
1062         if (ob == dialog_->button_delete)
1063                 return erase();
1064
1065         return false;
1066 }
1067
1068
1069 void FormPreferences::Formats::update()
1070 {
1071         local_formats = formats;
1072         UpdateBrowser();
1073 }
1074
1075
1076 void FormPreferences::Formats::UpdateBrowser()
1077 {
1078         local_formats.sort();
1079
1080         fl_freeze_form(dialog_->form);
1081         fl_deselect_browser(dialog_->browser_all);
1082         fl_clear_browser(dialog_->browser_all);
1083         for (::Formats::const_iterator cit = local_formats.begin();
1084              cit != local_formats.end(); ++cit)
1085                 fl_addto_browser(dialog_->browser_all,
1086                                  cit->prettyname().c_str());
1087
1088         Input();
1089         fl_unfreeze_form(dialog_->form);
1090
1091         // Mustn't forget to update the Formats available to the converters_
1092         parent_.converters_.UpdateChoices();
1093         local_converters.update(local_formats);
1094 }
1095
1096
1097 bool FormPreferences::Formats::Add()
1098 {
1099         string const name = fl_get_input(dialog_->input_format);
1100         string const prettyname = fl_get_input(dialog_->input_gui_name);
1101         string const extension = fl_get_input(dialog_->input_extension);
1102         string const shortcut =  fl_get_input(dialog_->input_shrtcut);
1103         string const viewer =  fl_get_input(dialog_->input_viewer);
1104
1105         Format const * old = local_formats.getFormat(name);
1106         string const old_prettyname = old ? old->prettyname() : string();
1107         local_formats.add(name, extension, prettyname, shortcut);
1108         local_formats.setViewer(name, viewer);
1109         if (!old || prettyname != old_prettyname) {
1110                 UpdateBrowser();
1111                 if (old)
1112                         parent_.converters_.UpdateBrowser();
1113         }
1114         setEnabled(dialog_->button_add, false);
1115
1116         return true;
1117 }
1118
1119
1120 bool FormPreferences::Formats::Browser()
1121 {
1122         int const i = fl_get_browser(dialog_->browser_all);
1123         if (i <= 0)
1124                 return false;
1125
1126         fl_freeze_form(dialog_->form);
1127
1128         Format const & f = local_formats.get(i - 1);
1129
1130         fl_set_input(dialog_->input_format, f.name().c_str());
1131         fl_set_input(dialog_->input_gui_name, f.prettyname().c_str());
1132         fl_set_input(dialog_->input_shrtcut, f.shortcut().c_str());
1133         fl_set_input(dialog_->input_extension, f.extension().c_str());
1134         fl_set_input(dialog_->input_viewer, f.viewer().c_str());
1135
1136         fl_set_object_label(dialog_->button_add,
1137                             idex(_("Modify|#M")).c_str());
1138         fl_set_button_shortcut(dialog_->button_add,
1139                                scex(_("Modify|#M")).c_str(), 1);
1140
1141         setEnabled(dialog_->button_add,    false);
1142         setEnabled(dialog_->button_delete, true);
1143
1144         fl_unfreeze_form(dialog_->form);
1145         return false;
1146 }
1147
1148
1149 bool FormPreferences::Formats::erase()
1150 {
1151         string const name = fl_get_input(dialog_->input_format);
1152
1153         if (local_converters.formatIsUsed(name)) {
1154                 parent_.postWarning(_("Cannot remove a Format used by a Converter. "
1155                                       "Remove the converter first."));
1156                 setEnabled(dialog_->button_delete, false);
1157                 return false;
1158         }
1159
1160         local_formats.erase(name);
1161         UpdateBrowser();
1162         return true;
1163 }
1164
1165
1166 bool FormPreferences::Formats::Input()
1167 {
1168         string const name = fl_get_input(dialog_->input_format);
1169         int const sel = local_formats.getNumber(name);
1170         fl_freeze_form(dialog_->form);
1171
1172         if (sel < 0) {
1173                 fl_set_object_label(dialog_->button_add,
1174                                     idex(_("Add|#A")).c_str());
1175                 fl_set_button_shortcut(dialog_->button_add,
1176                                        scex(_("Add|#A")).c_str(), 1);
1177
1178                 fl_deselect_browser(dialog_->browser_all);
1179                 setEnabled(dialog_->button_delete, false);
1180
1181         } else {
1182                 fl_set_object_label(dialog_->button_add,
1183                                     idex(_("Modify|#M")).c_str());
1184                 fl_set_button_shortcut(dialog_->button_add,
1185                                        scex(_("Modify|#M")).c_str(), 1);
1186
1187                 int const top = max(sel-5, 0);
1188                 fl_set_browser_topline(dialog_->browser_all, top);
1189                 fl_select_browser_line(dialog_->browser_all, sel+1);
1190
1191                 setEnabled(dialog_->button_add, true);
1192                 setEnabled(dialog_->button_delete, true);
1193         }
1194
1195         string const prettyname = fl_get_input(dialog_->input_gui_name);
1196         bool const enable = !(name.empty() || prettyname.empty());
1197         setEnabled(dialog_->button_add, enable);
1198
1199         fl_unfreeze_form(dialog_->form);
1200         return false;
1201 }
1202
1203
1204 FormPreferences::Identity::Identity(FormPreferences & p)
1205         : parent_(p)
1206 {}
1207
1208
1209 FD_preferences_identity const * FormPreferences::Identity::dialog()
1210 {
1211         return dialog_.get();
1212 }
1213
1214
1215 void FormPreferences::Identity::apply(LyXRC & rc) const
1216 {
1217         rc.user_name = fl_get_input(dialog_->input_user_name);
1218         rc.user_email = fl_get_input(dialog_->input_user_email);
1219 }
1220
1221
1222 void FormPreferences::Identity::build()
1223 {
1224         dialog_.reset(build_preferences_identity(&parent_));
1225         fl_set_input_return(dialog_->input_user_name, FL_RETURN_CHANGED);
1226         fl_set_input_return(dialog_->input_user_email, FL_RETURN_CHANGED);
1227 }
1228
1229
1230 void FormPreferences::Identity::update(LyXRC const & rc)
1231 {
1232         fl_set_input(dialog_->input_user_name, rc.user_name.c_str());
1233         fl_set_input(dialog_->input_user_email, rc.user_email.c_str());
1234 }
1235
1236
1237 FormPreferences::InputsMisc::InputsMisc(FormPreferences &  p)
1238         : parent_(p)
1239 {}
1240
1241
1242 FD_preferences_inputs_misc const * FormPreferences::InputsMisc::dialog()
1243 {
1244         return dialog_.get();
1245 }
1246
1247
1248 void FormPreferences::InputsMisc::apply(LyXRC & rc) const
1249 {
1250         rc.date_insert_format =
1251                 fl_get_input(dialog_->input_date_format);
1252 }
1253
1254
1255 void FormPreferences::InputsMisc::build()
1256 {
1257         dialog_.reset(build_preferences_inputs_misc(&parent_));
1258
1259         fl_set_input_return(dialog_->input_date_format, FL_RETURN_CHANGED);
1260
1261         // set up the feedback mechanism
1262         setPrehandler(dialog_->input_date_format);
1263 }
1264
1265
1266 string const
1267 FormPreferences::InputsMisc::feedback(FL_OBJECT const * const ob) const
1268 {
1269         if (ob == dialog_->input_date_format)
1270                 return LyXRC::getDescription(LyXRC::RC_DATE_INSERT_FORMAT);
1271         return string();
1272 }
1273
1274
1275 void FormPreferences::InputsMisc::update(LyXRC const & rc)
1276 {
1277         fl_set_input(dialog_->input_date_format,
1278                      rc.date_insert_format.c_str());
1279 }
1280
1281
1282 FormPreferences::Interface::Interface(FormPreferences &  p)
1283         : parent_(p)
1284 {}
1285
1286
1287 FD_preferences_interface const * FormPreferences::Interface::dialog()
1288 {
1289         return dialog_.get();
1290 }
1291
1292
1293 void FormPreferences::Interface::apply(LyXRC & rc) const
1294 {
1295         rc.popup_normal_font =
1296                 fl_get_input(dialog_->input_popup_normal_font);
1297         rc.popup_bold_font = fl_get_input(dialog_->input_popup_bold_font);
1298         rc.popup_font_encoding =
1299                 fl_get_input(dialog_->input_popup_font_encoding);
1300         rc.bind_file = fl_get_input(dialog_->input_bind_file);
1301         rc.ui_file = fl_get_input(dialog_->input_ui_file);
1302 }
1303
1304
1305 void FormPreferences::Interface::build()
1306 {
1307         dialog_.reset(build_preferences_interface(&parent_));
1308
1309         fl_set_input_return(dialog_->input_popup_normal_font, FL_RETURN_CHANGED);
1310         fl_set_input_return(dialog_->input_popup_bold_font, FL_RETURN_CHANGED);
1311         fl_set_input_return(dialog_->input_popup_font_encoding, FL_RETURN_CHANGED);
1312         fl_set_input_return(dialog_->input_bind_file, FL_RETURN_CHANGED);
1313         fl_set_input_return(dialog_->input_ui_file, FL_RETURN_CHANGED);
1314
1315         // set up the feedback mechanism
1316         setPrehandler(dialog_->input_popup_normal_font);
1317         setPrehandler(dialog_->input_popup_bold_font);
1318         setPrehandler(dialog_->input_popup_font_encoding);
1319         setPrehandler(dialog_->input_bind_file);
1320         setPrehandler(dialog_->button_bind_file_browse);
1321         setPrehandler(dialog_->input_ui_file);
1322         setPrehandler(dialog_->button_ui_file_browse);
1323 }
1324
1325
1326 string const
1327 FormPreferences::Interface::feedback(FL_OBJECT const * const ob) const
1328 {
1329         if (ob == dialog_->input_popup_normal_font)
1330                 return LyXRC::getDescription(LyXRC::RC_POPUP_NORMAL_FONT);
1331         if (ob == dialog_->input_popup_bold_font)
1332                 return LyXRC::getDescription(LyXRC::RC_POPUP_BOLD_FONT);
1333         if (ob == dialog_->input_popup_font_encoding)
1334                 return LyXRC::getDescription(LyXRC::RC_POPUP_FONT_ENCODING);
1335         if (ob == dialog_->input_bind_file)
1336                 return LyXRC::getDescription(LyXRC::RC_BINDFILE);
1337         if (ob == dialog_->input_ui_file)
1338                 return LyXRC::getDescription(LyXRC::RC_UIFILE);
1339         return string();
1340 }
1341
1342
1343 bool FormPreferences::Interface::input(FL_OBJECT const * const ob)
1344 {
1345         if (ob == dialog_->button_bind_file_browse) {
1346                 string f = parent_.controller().browsebind(
1347                         fl_get_input(dialog_->input_bind_file));
1348
1349                 fl_set_input(dialog_->input_bind_file, f.c_str());
1350         } else if (ob == dialog_->button_ui_file_browse) {
1351                 string f = parent_.controller().browseUI(
1352                         fl_get_input(dialog_->input_ui_file));
1353
1354                 fl_set_input(dialog_->input_ui_file, f.c_str());
1355         }
1356
1357         return true;
1358 }
1359
1360
1361 void FormPreferences::Interface::update(LyXRC const & rc)
1362 {
1363         fl_set_input(dialog_->input_popup_normal_font,
1364                      rc.popup_normal_font.c_str());
1365         fl_set_input(dialog_->input_popup_bold_font,
1366                      rc.popup_bold_font.c_str());
1367         fl_set_input(dialog_->input_popup_font_encoding,
1368                      rc.popup_font_encoding.c_str());
1369         fl_set_input(dialog_->input_bind_file,
1370                      rc.bind_file.c_str());
1371         fl_set_input(dialog_->input_ui_file,
1372                      rc.ui_file.c_str());
1373 }
1374
1375
1376 FormPreferences::Language::Language(FormPreferences &  p)
1377         : parent_(p)
1378 {}
1379
1380
1381 FD_preferences_language const * FormPreferences::Language::dialog()
1382 {
1383         return dialog_.get();
1384 }
1385
1386
1387 void FormPreferences::Language::apply(LyXRC & rc)
1388 {
1389         int const pos = fl_get_combox(dialog_->combox_default_lang);
1390         rc.default_language = lang_[pos-1];
1391
1392         int button = fl_get_button(dialog_->check_use_kbmap);
1393         string const name_1 = fl_get_input(dialog_->input_kbmap1);
1394         string const name_2 = fl_get_input(dialog_->input_kbmap2);
1395         if (button)
1396                 button = !(name_1.empty() && name_2.empty());
1397         rc.use_kbmap = static_cast<bool>(button);
1398
1399         if (rc.use_kbmap) {
1400                 rc.primary_kbmap = name_1;
1401                 rc.secondary_kbmap = name_2;
1402         }
1403
1404         button = fl_get_button(dialog_->check_rtl_support);
1405         rc.rtl_support = static_cast<bool>(button);
1406
1407         button = fl_get_button(dialog_->check_mark_foreign);
1408         rc.mark_foreign_language = static_cast<bool>(button);
1409
1410         button = fl_get_button(dialog_->check_auto_begin);
1411         rc.language_auto_begin = static_cast<bool>(button);
1412
1413         button = fl_get_button(dialog_->check_auto_end);
1414         rc.language_auto_end = static_cast<bool>(button);
1415
1416         button = fl_get_button(dialog_->check_use_babel);
1417         rc.language_use_babel = static_cast<bool>(button);
1418
1419         button = fl_get_button(dialog_->check_global_options);
1420         rc.language_global_options = static_cast<bool>(button);
1421
1422         rc.language_package = fl_get_input(dialog_->input_package);
1423         rc.language_command_begin = fl_get_input(dialog_->input_command_begin);
1424         rc.language_command_end = fl_get_input(dialog_->input_command_end);
1425
1426         // Ensure that all is self-consistent.
1427         update(rc);
1428 }
1429
1430
1431 void FormPreferences::Language::build()
1432 {
1433         dialog_.reset(build_preferences_language(&parent_));
1434
1435         fl_set_input_return(dialog_->input_package, FL_RETURN_CHANGED);
1436         fl_set_input_return(dialog_->input_command_begin, FL_RETURN_CHANGED);
1437         fl_set_input_return(dialog_->input_command_end, FL_RETURN_CHANGED);
1438
1439         // Store the lang identifiers for later
1440         vector<frnt::LanguagePair> const langs = frnt::getLanguageData(false);
1441         lang_ = getSecond(langs);
1442
1443         FL_OBJECT * obj = dialog_->combox_default_lang;
1444         vector<frnt::LanguagePair>::const_iterator lit  = langs.begin();
1445         vector<frnt::LanguagePair>::const_iterator lend = langs.end();
1446         for (; lit != lend; ++lit) {
1447                 fl_addto_combox(obj, lit->first.c_str());
1448         }
1449         fl_set_combox_browser_height(obj, 400);
1450
1451         // set up the feedback mechanism
1452         setPrehandler(dialog_->input_package);
1453         setPrehandler(dialog_->check_use_kbmap);
1454         setPrehandler(dialog_->combox_default_lang);
1455         setPrehandler(dialog_->input_kbmap1);
1456         setPrehandler(dialog_->input_kbmap2);
1457         setPrehandler(dialog_->check_rtl_support);
1458         setPrehandler(dialog_->check_mark_foreign);
1459         setPrehandler(dialog_->check_auto_begin);
1460         setPrehandler(dialog_->check_auto_end);
1461         setPrehandler(dialog_->check_use_babel);
1462         setPrehandler(dialog_->check_global_options);
1463         setPrehandler(dialog_->input_command_begin);
1464         setPrehandler(dialog_->input_command_end);
1465
1466         // Activate/Deactivate the input fields dependent on the state of the
1467         // buttons.
1468         input(0);
1469 }
1470
1471
1472 string const
1473 FormPreferences::Language::feedback(FL_OBJECT const * const ob) const
1474 {
1475         if (ob == dialog_->combox_default_lang)
1476                 return LyXRC::getDescription(LyXRC::RC_DEFAULT_LANGUAGE);
1477         if (ob == dialog_->check_use_kbmap)
1478                 return LyXRC::getDescription(LyXRC::RC_KBMAP);
1479         if (ob == dialog_->input_kbmap1)
1480                 return LyXRC::getDescription(LyXRC::RC_KBMAP_PRIMARY);
1481         if (ob == dialog_->input_kbmap2)
1482                 return LyXRC::getDescription(LyXRC::RC_KBMAP_SECONDARY);
1483         if (ob == dialog_->check_rtl_support)
1484                 return LyXRC::getDescription(LyXRC::RC_RTL_SUPPORT);
1485         if (ob == dialog_->check_mark_foreign)
1486                 return LyXRC::getDescription(LyXRC::RC_MARK_FOREIGN_LANGUAGE);
1487         if (ob == dialog_->check_auto_begin)
1488                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_AUTO_BEGIN);
1489         if (ob == dialog_->check_auto_end)
1490                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_AUTO_END);
1491         if (ob == dialog_->check_use_babel)
1492                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_USE_BABEL);
1493         if (ob == dialog_->check_global_options)
1494                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS);
1495         if (ob == dialog_->input_package)
1496                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_PACKAGE);
1497         if (ob == dialog_->input_command_begin)
1498                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_COMMAND_BEGIN);
1499         if (ob == dialog_->input_command_end)
1500                 return LyXRC::getDescription(LyXRC::RC_LANGUAGE_COMMAND_END);
1501         return string();
1502 }
1503
1504
1505 bool FormPreferences::Language::input(FL_OBJECT const * const ob)
1506 {
1507         bool activate = true;
1508
1509         // !ob if function is called from Language::build() to de/activate
1510         // objects,
1511         // otherwise the function is called by an xforms CB via input().
1512         if (!ob || ob == dialog_->check_use_kbmap) {
1513                 bool const enable = fl_get_button(dialog_->check_use_kbmap);
1514                 setEnabled(dialog_->button_kbmap1_browse, enable);
1515                 setEnabled(dialog_->button_kbmap2_browse, enable);
1516                 setEnabled(dialog_->input_kbmap1, enable);
1517                 setEnabled(dialog_->input_kbmap2, enable);
1518         }
1519
1520         if (ob == dialog_->button_kbmap1_browse) {
1521                 string f = parent_.controller().browsekbmap(
1522                         fl_get_input(dialog_->input_kbmap1));
1523
1524                 fl_set_input(dialog_->input_kbmap1, f.c_str());
1525         } else if (ob == dialog_->button_kbmap2_browse) {
1526                 string f = parent_.controller().browsekbmap(
1527                         fl_get_input(dialog_->input_kbmap2));
1528
1529                 fl_set_input(dialog_->input_kbmap2, f.c_str());
1530         }
1531
1532         return activate;
1533 }
1534
1535
1536 void FormPreferences::Language::update(LyXRC const & rc)
1537 {
1538         fl_set_button(dialog_->check_use_kbmap,
1539                       rc.use_kbmap);
1540
1541         int const pos = int(findPos(lang_, rc.default_language));
1542         fl_set_combox(dialog_->combox_default_lang, pos + 1);
1543
1544         if (rc.use_kbmap) {
1545                 fl_set_input(dialog_->input_kbmap1,
1546                              rc.primary_kbmap.c_str());
1547                 fl_set_input(dialog_->input_kbmap2,
1548                              rc.secondary_kbmap.c_str());
1549         } else {
1550                 fl_set_input(dialog_->input_kbmap1, "");
1551                 fl_set_input(dialog_->input_kbmap2, "");
1552         }
1553
1554         fl_set_button(dialog_->check_rtl_support, rc.rtl_support);
1555         fl_set_button(dialog_->check_mark_foreign,
1556                       rc.mark_foreign_language);
1557         fl_set_button(dialog_->check_auto_begin, rc.language_auto_begin);
1558         fl_set_button(dialog_->check_auto_end, rc.language_auto_end);
1559         fl_set_button(dialog_->check_use_babel, rc.language_use_babel);
1560         fl_set_button(dialog_->check_global_options,
1561                       rc.language_global_options);
1562
1563         fl_set_input(dialog_->input_package,
1564                      rc.language_package.c_str());
1565         fl_set_input(dialog_->input_command_begin,
1566                      rc.language_command_begin.c_str());
1567         fl_set_input(dialog_->input_command_end,
1568                      rc.language_command_end.c_str());
1569
1570         // Activate/Deactivate the input fields dependent on the state of the
1571         // buttons.
1572         input(0);
1573 }
1574
1575
1576 FormPreferences::LnFmisc::LnFmisc(FormPreferences &  p)
1577         : parent_(p)
1578 {}
1579
1580
1581 FD_preferences_lnf_misc const * FormPreferences::LnFmisc::dialog()
1582 {
1583         return dialog_.get();
1584 }
1585
1586
1587 void FormPreferences::LnFmisc::apply(LyXRC & rc) const
1588 {
1589         rc.auto_region_delete =
1590                 fl_get_button(dialog_->check_auto_region_delete);
1591         rc.cursor_follows_scrollbar =
1592                 fl_get_button(dialog_->check_cursor_follows_scrollbar);
1593         rc.dialogs_iconify_with_main =
1594                 fl_get_button(dialog_->check_dialogs_iconify_with_main);
1595         rc.preview = fl_get_button(dialog_->check_preview_latex);
1596         rc.autosave = static_cast<unsigned int>
1597                 (fl_get_counter_value(dialog_->counter_autosave));
1598         rc.wheel_jump = static_cast<unsigned int>
1599                 (fl_get_counter_value(dialog_->counter_wm_jump));
1600
1601         // See FIXME below
1602         // lyx::graphics::DisplayType old_value = rc.display_graphics;
1603         switch (fl_get_choice(dialog_->choice_display)) {
1604         case 4:
1605                 rc.display_graphics = lyx::graphics::NoDisplay;
1606                 break;
1607         case 3:
1608                 rc.display_graphics = lyx::graphics::ColorDisplay;
1609                 break;
1610         case 2:
1611                 rc.display_graphics = lyx::graphics::GrayscaleDisplay;
1612                 break;
1613         case 1:
1614                 rc.display_graphics = lyx::graphics::MonochromeDisplay;
1615                 break;
1616         default:
1617                 rc.display_graphics = lyx::graphics::ColorDisplay;
1618                 break;
1619         }
1620
1621 #ifdef WITH_WARNINGS
1622 #warning FIXME!! The graphics cache no longer has a changeDisplay method.
1623 #endif
1624 #if 0
1625         if (old_value != rc.display_graphics) {
1626                 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
1627                 gc.changeDisplay();
1628         }
1629 #endif
1630 }
1631
1632
1633 void FormPreferences::LnFmisc::build()
1634 {
1635         dialog_.reset(build_preferences_lnf_misc(&parent_));
1636
1637         fl_set_counter_step(dialog_->counter_autosave, 1, 10);
1638         fl_set_counter_step(dialog_->counter_wm_jump, 1, 10);
1639
1640         fl_set_counter_return(dialog_->counter_autosave, FL_RETURN_CHANGED);
1641         fl_set_counter_return(dialog_->counter_wm_jump, FL_RETURN_CHANGED);
1642
1643         // set up the feedback mechanism
1644         setPrehandler(dialog_->check_auto_region_delete);
1645         setPrehandler(dialog_->counter_autosave);
1646         setPrehandler(dialog_->check_cursor_follows_scrollbar);
1647         setPrehandler(dialog_->check_dialogs_iconify_with_main);
1648         setPrehandler(dialog_->check_preview_latex);
1649         setPrehandler(dialog_->counter_wm_jump);
1650
1651         fl_addto_choice(dialog_->choice_display,
1652                         _("Monochrome|Grayscale|Color|Do not display").c_str());
1653 }
1654
1655
1656 string const
1657 FormPreferences::LnFmisc::feedback(FL_OBJECT const * const ob) const
1658 {
1659         if (ob == dialog_->check_auto_region_delete)
1660                 return LyXRC::getDescription(LyXRC::RC_AUTOREGIONDELETE);
1661         if (ob == dialog_->check_cursor_follows_scrollbar)
1662                 return LyXRC::getDescription(LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR);
1663         if (ob == dialog_->check_dialogs_iconify_with_main)
1664                 return LyXRC::getDescription(LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN);
1665         if (ob == dialog_->check_preview_latex)
1666                 return LyXRC::getDescription(LyXRC::RC_PREVIEW);
1667         if (ob == dialog_->counter_autosave)
1668                 return LyXRC::getDescription(LyXRC::RC_AUTOSAVE);
1669         if (ob == dialog_->counter_wm_jump)
1670                 return LyXRC::getDescription(LyXRC::RC_WHEEL_JUMP);
1671         if (ob == dialog_->choice_display)
1672                 return LyXRC::getDescription(LyXRC::RC_DISPLAY_GRAPHICS);
1673         return string();
1674 }
1675
1676
1677 void FormPreferences::LnFmisc::update(LyXRC const & rc)
1678 {
1679         fl_set_button(dialog_->check_auto_region_delete,
1680                       rc.auto_region_delete);
1681         fl_set_button(dialog_->check_cursor_follows_scrollbar,
1682                       rc.cursor_follows_scrollbar);
1683         fl_set_button(dialog_->check_dialogs_iconify_with_main,
1684                       rc.dialogs_iconify_with_main);
1685         fl_set_button(dialog_->check_preview_latex,
1686                       rc.preview);
1687         fl_set_counter_value(dialog_->counter_autosave, rc.autosave);
1688         fl_set_counter_value(dialog_->counter_wm_jump, rc.wheel_jump);
1689
1690         switch (rc.display_graphics) {
1691         case lyx::graphics::NoDisplay:
1692                 fl_set_choice(dialog_->choice_display, 4);
1693                 break;
1694         case lyx::graphics::ColorDisplay:
1695                 fl_set_choice(dialog_->choice_display, 3);
1696                 break;
1697         case lyx::graphics::GrayscaleDisplay:
1698                 fl_set_choice(dialog_->choice_display, 2);
1699                 break;
1700         case lyx::graphics::MonochromeDisplay:
1701                 fl_set_choice(dialog_->choice_display, 1);
1702                 break;
1703         default:
1704                 fl_set_choice(dialog_->choice_display, 3);
1705                 break;
1706         }
1707 }
1708
1709
1710 FormPreferences::OutputsMisc::OutputsMisc(FormPreferences &  p)
1711         : parent_(p)
1712 {}
1713
1714
1715 FD_preferences_outputs_misc const * FormPreferences::OutputsMisc::dialog()
1716 {
1717         return dialog_.get();
1718 }
1719
1720
1721 void FormPreferences::OutputsMisc::apply(LyXRC & rc) const
1722 {
1723         rc.ascii_linelen = static_cast<unsigned int>
1724                 (fl_get_counter_value(dialog_->counter_line_len));
1725         rc.fontenc = fl_get_input(dialog_->input_tex_encoding);
1726
1727         int const choice =
1728                 fl_get_choice(dialog_->choice_default_papersize) - 1;
1729         rc.default_papersize = static_cast<PAPER_SIZE>(choice);
1730
1731         rc.ascii_roff_command = fl_get_input(dialog_->input_ascii_roff);
1732         rc.chktex_command = fl_get_input(dialog_->input_checktex);
1733         rc.view_dvi_paper_option = fl_get_input(dialog_->input_paperoption);
1734         rc.auto_reset_options = fl_get_button(dialog_->check_autoreset_classopt);
1735 }
1736
1737
1738 void FormPreferences::OutputsMisc::build()
1739 {
1740         dialog_.reset(build_preferences_outputs_misc(&parent_));
1741
1742         fl_set_counter_step(dialog_->counter_line_len, 1, 10);
1743
1744         fl_set_counter_return(dialog_->counter_line_len, FL_RETURN_CHANGED);
1745         fl_set_input_return(dialog_->input_tex_encoding, FL_RETURN_CHANGED);
1746         fl_set_input_return(dialog_->input_ascii_roff,   FL_RETURN_CHANGED);
1747         fl_set_input_return(dialog_->input_checktex,     FL_RETURN_CHANGED);
1748         fl_set_input_return(dialog_->input_paperoption,  FL_RETURN_CHANGED);
1749
1750         fl_addto_choice(dialog_->choice_default_papersize,
1751                         _(" default | US letter | US legal "
1752                           "| US executive | A3 | A4 | A5 | B5 ").c_str());
1753
1754         // set up the feedback mechanism
1755         setPrehandler(dialog_->counter_line_len);
1756         setPrehandler(dialog_->input_tex_encoding);
1757         setPrehandler(dialog_->choice_default_papersize);
1758         setPrehandler(dialog_->input_ascii_roff);
1759         setPrehandler(dialog_->input_checktex);
1760         setPrehandler(dialog_->input_paperoption);
1761         setPrehandler(dialog_->check_autoreset_classopt);
1762 }
1763
1764
1765 string const
1766 FormPreferences::OutputsMisc::feedback(FL_OBJECT const * const ob) const
1767 {
1768         if (ob == dialog_->counter_line_len)
1769                 return LyXRC::getDescription(LyXRC::RC_ASCII_LINELEN);
1770         if (ob == dialog_->input_tex_encoding)
1771                 return LyXRC::getDescription(LyXRC::RC_FONT_ENCODING);
1772         if (ob == dialog_->input_ascii_roff)
1773                 return LyXRC::getDescription(LyXRC::RC_ASCIIROFF_COMMAND);
1774         if (ob == dialog_->input_checktex)
1775                 return LyXRC::getDescription(LyXRC::RC_CHKTEX_COMMAND);
1776         if (ob == dialog_->choice_default_papersize)
1777                 return LyXRC::getDescription(LyXRC::RC_DEFAULT_PAPERSIZE);
1778         if (ob == dialog_->input_paperoption)
1779                 return LyXRC::getDescription(LyXRC::RC_VIEWDVI_PAPEROPTION);
1780         if (ob == dialog_->check_autoreset_classopt)
1781                 return LyXRC::getDescription(LyXRC::RC_AUTORESET_OPTIONS);
1782         return string();
1783 }
1784
1785
1786 void FormPreferences::OutputsMisc::update(LyXRC const & rc)
1787 {
1788         fl_set_counter_value(dialog_->counter_line_len,
1789                              rc.ascii_linelen);
1790         fl_set_input(dialog_->input_tex_encoding,
1791                      rc.fontenc.c_str());
1792         fl_set_choice(dialog_->choice_default_papersize,
1793                       rc.default_papersize + 1);
1794         fl_set_input(dialog_->input_ascii_roff,
1795                      rc.ascii_roff_command.c_str());
1796         fl_set_input(dialog_->input_checktex,
1797                      rc.chktex_command.c_str());
1798         fl_set_input(dialog_->input_paperoption,
1799                      rc.view_dvi_paper_option.c_str());
1800         fl_set_button(dialog_->check_autoreset_classopt,
1801                       rc.auto_reset_options);
1802
1803 }
1804
1805
1806 FormPreferences::Paths::Paths(FormPreferences &  p)
1807         : parent_(p)
1808 {}
1809
1810
1811 FD_preferences_paths const * FormPreferences::Paths::dialog()
1812 {
1813         return dialog_.get();
1814 }
1815
1816
1817 void FormPreferences::Paths::apply(LyXRC & rc)
1818 {
1819         rc.document_path = fl_get_input(dialog_->input_default_path);
1820         rc.template_path = fl_get_input(dialog_->input_template_path);
1821
1822         int button = fl_get_button(dialog_->check_use_temp_dir);
1823         string str  = fl_get_input(dialog_->input_temp_dir);
1824         if (!button)
1825                 str.erase();
1826
1827         rc.use_tempdir = button;
1828         rc.tempdir_path = str;
1829
1830         button = fl_get_button(dialog_->check_last_files);
1831         str = fl_get_input(dialog_->input_lastfiles);
1832         if (!button) str.erase();
1833
1834         rc.check_lastfiles = button;
1835         rc.lastfiles = str;
1836         rc.num_lastfiles = static_cast<unsigned int>
1837                 (fl_get_counter_value(dialog_->counter_lastfiles));
1838
1839         button = fl_get_button(dialog_->check_make_backups);
1840         str = fl_get_input(dialog_->input_backup_path);
1841         if (!button)
1842                 str.erase();
1843
1844         rc.make_backup = button;
1845         rc.backupdir_path = str;
1846
1847         rc.lyxpipes = fl_get_input(dialog_->input_serverpipe);
1848
1849         // update view
1850         update(rc);
1851 }
1852
1853
1854 void FormPreferences::Paths::build()
1855 {
1856         dialog_.reset(build_preferences_paths(&parent_));
1857
1858         fl_set_input_return(dialog_->input_default_path, FL_RETURN_CHANGED);
1859         fl_set_input_return(dialog_->input_template_path, FL_RETURN_CHANGED);
1860         fl_set_input_return(dialog_->input_temp_dir, FL_RETURN_CHANGED);
1861         fl_set_input_return(dialog_->input_lastfiles, FL_RETURN_CHANGED);
1862         fl_set_input_return(dialog_->input_backup_path, FL_RETURN_CHANGED);
1863         fl_set_counter_return(dialog_->counter_lastfiles, FL_RETURN_CHANGED);
1864         fl_set_input_return(dialog_->input_serverpipe, FL_RETURN_CHANGED);
1865
1866         // set up the feedback mechanism
1867         setPrehandler(dialog_->input_default_path);
1868         setPrehandler(dialog_->counter_lastfiles);
1869         setPrehandler(dialog_->input_template_path);
1870         setPrehandler(dialog_->check_last_files);
1871         setPrehandler(dialog_->input_lastfiles);
1872         setPrehandler(dialog_->check_make_backups);
1873         setPrehandler(dialog_->input_backup_path);
1874         setPrehandler(dialog_->input_serverpipe);
1875         setPrehandler(dialog_->input_temp_dir);
1876         setPrehandler(dialog_->check_use_temp_dir);
1877 }
1878
1879
1880 string const
1881 FormPreferences::Paths::feedback(FL_OBJECT const * const ob) const
1882 {
1883         if (ob == dialog_->input_default_path)
1884                 return LyXRC::getDescription(LyXRC::RC_DOCUMENTPATH);
1885         if (ob == dialog_->input_template_path)
1886                 return LyXRC::getDescription(LyXRC::RC_TEMPLATEPATH);
1887         if (ob == dialog_->check_use_temp_dir)
1888                 return LyXRC::getDescription(LyXRC::RC_USETEMPDIR);
1889         if (ob == dialog_->input_temp_dir)
1890                 return LyXRC::getDescription(LyXRC::RC_TEMPDIRPATH);
1891         if (ob == dialog_->check_last_files)
1892                 return LyXRC::getDescription(LyXRC::RC_CHECKLASTFILES);
1893         if (ob == dialog_->input_lastfiles)
1894                 return LyXRC::getDescription(LyXRC::RC_LASTFILES);
1895         if (ob == dialog_->counter_lastfiles)
1896                 return LyXRC::getDescription(LyXRC::RC_NUMLASTFILES);
1897         if (ob == dialog_->check_make_backups)
1898                 return LyXRC::getDescription(LyXRC::RC_MAKE_BACKUP);
1899         if (ob == dialog_->input_backup_path)
1900                 return LyXRC::getDescription(LyXRC::RC_BACKUPDIR_PATH);
1901         if (ob == dialog_->input_serverpipe)
1902                 return LyXRC::getDescription(LyXRC::RC_SERVERPIPE);
1903         return string();
1904 }
1905
1906
1907 bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
1908 {
1909         bool activate = true;
1910
1911         // !ob if function is called from Paths::update() to de/activate
1912         // objects,
1913         // otherwise the function is called by an xforms CB via input().
1914         if (!ob || ob == dialog_->check_use_temp_dir) {
1915                 bool const enable = fl_get_button(dialog_->check_use_temp_dir);
1916                 setEnabled(dialog_->input_temp_dir, enable);
1917         }
1918
1919         if (!ob || ob == dialog_->check_last_files) {
1920                 bool const enable = fl_get_button(dialog_->check_last_files);
1921                 setEnabled(dialog_->input_lastfiles, enable);
1922         }
1923
1924         if (!ob || ob == dialog_->check_make_backups) {
1925                 bool const enable = fl_get_button(dialog_->check_make_backups);
1926                 setEnabled(dialog_->input_backup_path, enable);
1927         }
1928
1929         if (!ob || ob == dialog_->input_default_path) {
1930                 string const name = fl_get_input(dialog_->input_default_path);
1931                 if (!name.empty() && !RWInfo::WriteableDir(name)) {
1932                         parent_.postWarning(RWInfo::ErrorMessage());
1933                         return false;
1934                 }
1935         }
1936
1937         if (!ob || ob == dialog_->input_template_path) {
1938                 string const name = fl_get_input(dialog_->input_template_path);
1939                 if (!name.empty() && !RWInfo::ReadableDir(name)) {
1940                         parent_.postWarning(RWInfo::ErrorMessage());
1941                         return false;
1942                 }
1943         }
1944
1945         if (!ob || ob == dialog_->input_temp_dir) {
1946                 string const name = fl_get_input(dialog_->input_temp_dir);
1947                 if (fl_get_button(dialog_->check_make_backups)
1948                     && !name.empty()
1949                     && !RWInfo::WriteableDir(name)) {
1950                         parent_.postWarning(RWInfo::ErrorMessage());
1951                         return false;
1952                 }
1953         }
1954
1955         if (!ob || ob == dialog_->input_backup_path) {
1956                 string const name = fl_get_input(dialog_->input_backup_path);
1957                 if (fl_get_button(dialog_->check_make_backups)
1958                     && !name.empty()
1959                     && !RWInfo::WriteableDir(name)) {
1960                         parent_.postWarning(RWInfo::ErrorMessage());
1961                         return false;
1962                 }
1963         }
1964
1965         if (!ob || ob == dialog_->input_lastfiles) {
1966                 string const name = fl_get_input(dialog_->input_lastfiles);
1967                 if (fl_get_button(dialog_->check_last_files)
1968                     && !name.empty()
1969                     && !RWInfo::WriteableFile(name)) {
1970                         parent_.postWarning(RWInfo::ErrorMessage());
1971                         return false;
1972                 }
1973         }
1974
1975         if (!ob || ob == dialog_->input_serverpipe) {
1976                 string const name = fl_get_input(dialog_->input_serverpipe);
1977                 if (!name.empty()) {
1978                         // strip off the extension
1979                         string const str = ChangeExtension(name, "");
1980                         if (!RWInfo::WriteableFile(str + ".in")) {
1981                                 parent_.postWarning(RWInfo::ErrorMessage());
1982                                 return false;
1983                         }
1984                         if (!RWInfo::WriteableFile(str + ".out")) {
1985                                 parent_.postWarning(RWInfo::ErrorMessage());
1986                                 return false;
1987                         }
1988                 }
1989         }
1990
1991         if (ob == dialog_->button_default_path_browse) {
1992                 string f = parent_.controller().browsedir(
1993                         fl_get_input(dialog_->input_default_path), _("Default path"));
1994                 if (!f.empty())
1995                         fl_set_input(dialog_->input_default_path, f.c_str());
1996         } else if (ob == dialog_->button_template_path_browse) {
1997                 string f = parent_.controller().browsedir(
1998                         fl_get_input(dialog_->input_template_path), _("Template path"));
1999                 if (!f.empty())
2000                         fl_set_input(dialog_->input_template_path, f.c_str());
2001         } else if (ob == dialog_->button_temp_dir_browse) {
2002                 string f = parent_.controller().browsedir(
2003                         fl_get_input(dialog_->input_temp_dir), _("Temporary dir"));
2004                 if (!f.empty())
2005                         fl_set_input(dialog_->input_temp_dir, f.c_str());
2006         } else if (ob == dialog_->button_lastfiles_browse) {
2007                 string f = parent_.controller().browse(
2008                         fl_get_input(dialog_->input_lastfiles), _("Last files"));
2009                 if (!f.empty())
2010                         fl_set_input(dialog_->input_lastfiles, f.c_str());
2011         } else if (ob == dialog_->button_backup_path_browse) {
2012                 string f = parent_.controller().browsedir(
2013                         fl_get_input(dialog_->input_backup_path), _("Backup path"));
2014                 if (!f.empty())
2015                         fl_set_input(dialog_->input_backup_path, f.c_str());
2016         } else if (ob == dialog_->button_serverpipe_browse) {
2017                 string f = parent_.controller().browse(
2018                         fl_get_input(dialog_->input_serverpipe), _("LyX server pipes"));
2019                 if (!f.empty())
2020                         fl_set_input(dialog_->input_serverpipe, f.c_str());
2021         }
2022
2023         return activate;
2024 }
2025
2026
2027 void FormPreferences::Paths::update(LyXRC const & rc)
2028 {
2029         fl_set_input(dialog_->input_default_path,
2030                      rc.document_path.c_str());
2031         fl_set_input(dialog_->input_template_path,
2032                      rc.template_path.c_str());
2033
2034         string str;
2035         if (rc.make_backup)
2036                 str = rc.backupdir_path;
2037
2038         fl_set_button(dialog_->check_make_backups,
2039                       rc.make_backup);
2040         fl_set_input(dialog_->input_backup_path, str.c_str());
2041
2042         str.erase();
2043         if (rc.use_tempdir)
2044                 str = rc.tempdir_path;
2045
2046         fl_set_button(dialog_->check_use_temp_dir,
2047                       rc.use_tempdir);
2048         fl_set_input(dialog_->input_temp_dir, str.c_str());
2049
2050         str.erase();
2051         if (rc.check_lastfiles)
2052                 str = rc.lastfiles;
2053
2054         fl_set_button(dialog_->check_last_files,
2055                       rc.check_lastfiles);
2056         fl_set_input(dialog_->input_lastfiles, str.c_str());
2057         fl_set_counter_value(dialog_->counter_lastfiles,
2058                              rc.num_lastfiles);
2059
2060         fl_set_input(dialog_->input_serverpipe, rc.lyxpipes.c_str());
2061
2062         // Activate/Deactivate the input fields dependent on the state of the
2063         // buttons.
2064         input(0);
2065 }
2066
2067
2068 FormPreferences::Printer::Printer(FormPreferences &  p)
2069         : parent_(p)
2070 {}
2071
2072
2073 FD_preferences_printer const * FormPreferences::Printer::dialog()
2074 {
2075         return dialog_.get();
2076 }
2077
2078
2079 void FormPreferences::Printer::apply(LyXRC & rc) const
2080 {
2081         rc.print_adapt_output = fl_get_button(dialog_->check_adapt_output);
2082         rc.print_command = fl_get_input(dialog_->input_command);
2083         rc.print_pagerange_flag = fl_get_input(dialog_->input_page_range);
2084         rc.print_copies_flag = fl_get_input(dialog_->input_copies);
2085         rc.print_reverse_flag = fl_get_input(dialog_->input_reverse);
2086         rc.print_to_printer = fl_get_input(dialog_->input_to_printer);
2087         rc.print_file_extension =
2088                 fl_get_input(dialog_->input_file_extension);
2089         rc.print_spool_command =
2090                 fl_get_input(dialog_->input_spool_command);
2091         rc.print_paper_flag = fl_get_input(dialog_->input_paper_type);
2092         rc.print_evenpage_flag = fl_get_input(dialog_->input_even_pages);
2093         rc.print_oddpage_flag = fl_get_input(dialog_->input_odd_pages);
2094         rc.print_collcopies_flag = fl_get_input(dialog_->input_collated);
2095         rc.print_landscape_flag = fl_get_input(dialog_->input_landscape);
2096         rc.print_to_file = fl_get_input(dialog_->input_to_file);
2097         rc.print_extra_options =
2098                 fl_get_input(dialog_->input_extra_options);
2099         rc.print_spool_printerprefix =
2100                 fl_get_input(dialog_->input_spool_prefix);
2101         rc.print_paper_dimension_flag =
2102                 fl_get_input(dialog_->input_paper_size);
2103         rc.printer = fl_get_input(dialog_->input_name);
2104 }
2105
2106
2107 string const
2108 FormPreferences::Printer::feedback(FL_OBJECT const * const ob) const
2109 {
2110         if (ob == dialog_->input_command)
2111                 return LyXRC::getDescription(LyXRC::RC_PRINT_COMMAND);
2112         if (ob == dialog_->check_adapt_output)
2113                 return LyXRC::getDescription(LyXRC::RC_PRINT_ADAPTOUTPUT);
2114         if (ob == dialog_->input_to_printer)
2115                 return LyXRC::getDescription(LyXRC::RC_PRINTTOPRINTER);
2116         if (ob == dialog_->input_to_file)
2117                 return LyXRC::getDescription(LyXRC::RC_PRINTTOFILE);
2118         if (ob == dialog_->input_file_extension)
2119                 return LyXRC::getDescription(LyXRC::RC_PRINTFILEEXTENSION);
2120         if (ob == dialog_->input_extra_options)
2121                 return LyXRC::getDescription(LyXRC::RC_PRINTEXSTRAOPTIONS);
2122         if (ob == dialog_->input_spool_command)
2123                 return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_COMMAND);
2124         if (ob == dialog_->input_spool_prefix)
2125                 return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_PRINTERPREFIX);
2126         if (ob == dialog_->input_name)
2127                 return LyXRC::getDescription(LyXRC::RC_PRINTER);
2128         if (ob == dialog_->input_even_pages)
2129                 return LyXRC::getDescription(LyXRC::RC_PRINTEVENPAGEFLAG);
2130         if (ob == dialog_->input_odd_pages)
2131                 return LyXRC::getDescription(LyXRC::RC_PRINTODDPAGEFLAG);
2132         if (ob == dialog_->input_page_range)
2133                 return LyXRC::getDescription(LyXRC::RC_PRINTPAGERANGEFLAG);
2134         if (ob == dialog_->input_reverse)
2135                 return LyXRC::getDescription(LyXRC::RC_PRINTREVERSEFLAG);
2136         if (ob == dialog_->input_landscape)
2137                 return LyXRC::getDescription(LyXRC::RC_PRINTLANDSCAPEFLAG);
2138         if (ob == dialog_->input_copies)
2139                 return LyXRC::getDescription(LyXRC::RC_PRINTCOPIESFLAG);
2140         if (ob == dialog_->input_collated)
2141                 return LyXRC::getDescription(LyXRC::RC_PRINTCOLLCOPIESFLAG);
2142         if (ob == dialog_->input_paper_type)
2143                 return LyXRC::getDescription(LyXRC::RC_PRINTPAPERFLAG);
2144         if (ob == dialog_->input_paper_size)
2145                 return LyXRC::getDescription(LyXRC::RC_PRINTPAPERDIMENSIONFLAG);
2146         return string();
2147 }
2148
2149
2150 void FormPreferences::Printer::build()
2151 {
2152         dialog_.reset(build_preferences_printer(&parent_));
2153
2154         fl_set_input_return(dialog_->input_command, FL_RETURN_CHANGED);
2155         fl_set_input_return(dialog_->input_page_range, FL_RETURN_CHANGED);
2156         fl_set_input_return(dialog_->input_copies, FL_RETURN_CHANGED);
2157         fl_set_input_return(dialog_->input_reverse, FL_RETURN_CHANGED);
2158         fl_set_input_return(dialog_->input_to_printer, FL_RETURN_CHANGED);
2159         fl_set_input_return(dialog_->input_file_extension, FL_RETURN_CHANGED);
2160         fl_set_input_return(dialog_->input_spool_command, FL_RETURN_CHANGED);
2161         fl_set_input_return(dialog_->input_paper_type, FL_RETURN_CHANGED);
2162         fl_set_input_return(dialog_->input_even_pages, FL_RETURN_CHANGED);
2163         fl_set_input_return(dialog_->input_odd_pages, FL_RETURN_CHANGED);
2164         fl_set_input_return(dialog_->input_collated, FL_RETURN_CHANGED);
2165         fl_set_input_return(dialog_->input_landscape, FL_RETURN_CHANGED);
2166         fl_set_input_return(dialog_->input_to_file, FL_RETURN_CHANGED);
2167         fl_set_input_return(dialog_->input_extra_options, FL_RETURN_CHANGED);
2168         fl_set_input_return(dialog_->input_spool_prefix, FL_RETURN_CHANGED);
2169         fl_set_input_return(dialog_->input_paper_size, FL_RETURN_CHANGED);
2170         fl_set_input_return(dialog_->input_name, FL_RETURN_CHANGED);
2171
2172         // set up the feedback mechanism
2173         setPrehandler(dialog_->input_command);
2174         setPrehandler(dialog_->input_page_range);
2175         setPrehandler(dialog_->input_copies);
2176         setPrehandler(dialog_->input_reverse);
2177         setPrehandler(dialog_->input_to_printer);
2178         setPrehandler(dialog_->input_file_extension);
2179         setPrehandler(dialog_->input_spool_command);
2180         setPrehandler(dialog_->input_paper_type);
2181         setPrehandler(dialog_->input_even_pages);
2182         setPrehandler(dialog_->input_odd_pages);
2183         setPrehandler(dialog_->input_collated);
2184         setPrehandler(dialog_->input_landscape);
2185         setPrehandler(dialog_->input_to_file);
2186         setPrehandler(dialog_->input_extra_options);
2187         setPrehandler(dialog_->input_spool_prefix);
2188         setPrehandler(dialog_->input_paper_size);
2189         setPrehandler(dialog_->input_name);
2190         setPrehandler(dialog_->check_adapt_output);
2191 }
2192
2193
2194 void FormPreferences::Printer::update(LyXRC const & rc)
2195 {
2196         fl_set_button(dialog_->check_adapt_output,
2197                       rc.print_adapt_output);
2198         fl_set_input(dialog_->input_command,
2199                      rc.print_command.c_str());
2200         fl_set_input(dialog_->input_page_range,
2201                      rc.print_pagerange_flag.c_str());
2202         fl_set_input(dialog_->input_copies,
2203                      rc.print_copies_flag.c_str());
2204         fl_set_input(dialog_->input_reverse,
2205                      rc.print_reverse_flag.c_str());
2206         fl_set_input(dialog_->input_to_printer,
2207                      rc.print_to_printer.c_str());
2208         fl_set_input(dialog_->input_file_extension,
2209                      rc.print_file_extension.c_str());
2210         fl_set_input(dialog_->input_spool_command,
2211                      rc.print_spool_command.c_str());
2212         fl_set_input(dialog_->input_paper_type,
2213                      rc.print_paper_flag.c_str());
2214         fl_set_input(dialog_->input_even_pages,
2215                      rc.print_evenpage_flag.c_str());
2216         fl_set_input(dialog_->input_odd_pages,
2217                      rc.print_oddpage_flag.c_str());
2218         fl_set_input(dialog_->input_collated,
2219                      rc.print_collcopies_flag.c_str());
2220         fl_set_input(dialog_->input_landscape,
2221                      rc.print_landscape_flag.c_str());
2222         fl_set_input(dialog_->input_to_file,
2223                      rc.print_to_file.c_str());
2224         fl_set_input(dialog_->input_extra_options,
2225                      rc.print_extra_options.c_str());
2226         fl_set_input(dialog_->input_spool_prefix,
2227                      rc.print_spool_printerprefix.c_str());
2228         fl_set_input(dialog_->input_paper_size,
2229                      rc.print_paper_dimension_flag.c_str());
2230         fl_set_input(dialog_->input_name,
2231                      rc.printer.c_str());
2232 }
2233
2234
2235 FormPreferences::ScreenFonts::ScreenFonts(FormPreferences &  p)
2236         : parent_(p)
2237 {}
2238
2239
2240 FD_preferences_screen_fonts const * FormPreferences::ScreenFonts::dialog()
2241 {
2242         return dialog_.get();
2243 }
2244
2245
2246 void FormPreferences::ScreenFonts::apply(LyXRC & rc) const
2247 {
2248         bool changed = false;
2249
2250         pair<string, string> tmp =
2251                 parseFontName(fl_get_input(dialog_->input_roman));
2252         if (rc.roman_font_name != tmp.first ||
2253             rc.roman_font_foundry != tmp.second) {
2254                 changed = true;
2255                 rc.roman_font_name = tmp.first;
2256                 rc.roman_font_foundry = tmp.second;
2257         }
2258
2259         tmp = parseFontName(fl_get_input(dialog_->input_sans));
2260         if (rc.sans_font_name != tmp.first ||
2261             rc.sans_font_foundry != tmp.second) {
2262                 changed = true;
2263                 rc.sans_font_name = tmp.first;
2264                 rc.sans_font_foundry = tmp.second;
2265         }
2266
2267         tmp = parseFontName(fl_get_input(dialog_->input_typewriter));
2268         if (rc.typewriter_font_name != tmp.first ||
2269             rc.typewriter_font_foundry != tmp.second) {
2270                 changed = true;
2271                 rc.typewriter_font_name = tmp.first;
2272                 rc.typewriter_font_foundry = tmp.second;
2273         }
2274
2275         string str = fl_get_input(dialog_->input_screen_encoding);
2276         if (rc.font_norm != str) {
2277                 changed = true;
2278                 rc.font_norm = str;
2279                 rc.set_font_norm_type();
2280         }
2281
2282         bool button = fl_get_button(dialog_->check_scalable);
2283         if (rc.use_scalable_fonts != button) {
2284                 changed = true;
2285                 rc.use_scalable_fonts = button;
2286         }
2287
2288         unsigned int ivalue = static_cast<unsigned int>
2289                 (fl_get_counter_value(dialog_->counter_zoom));
2290         if (rc.zoom != ivalue) {
2291                 changed = true;
2292                 rc.zoom = ivalue;
2293         }
2294
2295         ivalue = static_cast<unsigned int>
2296                 (fl_get_counter_value(dialog_->counter_dpi));
2297         if (rc.dpi != ivalue) {
2298                 changed = true;
2299                 rc.dpi = ivalue;
2300         }
2301
2302         double dvalue = strToDbl(fl_get_input(dialog_->input_tiny));
2303         if (rc.font_sizes[LyXFont::SIZE_TINY] != dvalue) {
2304                 changed = true;
2305                 rc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
2306         }
2307
2308         dvalue = strToDbl(fl_get_input(dialog_->input_script));
2309         if (rc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue) {
2310                 changed = true;
2311                 rc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
2312         }
2313
2314         dvalue = strToDbl(fl_get_input(dialog_->input_footnote));
2315         if (rc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue) {
2316                 changed = true;
2317                 rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
2318         }
2319
2320         dvalue = strToDbl(fl_get_input(dialog_->input_small));
2321         if (rc.font_sizes[LyXFont::SIZE_SMALL] != dvalue) {
2322                 changed = true;
2323                 rc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
2324         }
2325
2326         dvalue = strToDbl(fl_get_input(dialog_->input_normal));
2327         if (rc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue) {
2328                 changed = true;
2329                 rc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
2330         }
2331
2332         dvalue = strToDbl(fl_get_input(dialog_->input_large));
2333         if (rc.font_sizes[LyXFont::SIZE_LARGE] != dvalue) {
2334                 changed = true;
2335                 rc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
2336         }
2337
2338         dvalue = strToDbl(fl_get_input(dialog_->input_larger));
2339         if (rc.font_sizes[LyXFont::SIZE_LARGER] != dvalue) {
2340                 changed = true;
2341                 rc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
2342         }
2343
2344         dvalue = strToDbl(fl_get_input(dialog_->input_largest));
2345         if (rc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue) {
2346                 changed = true;
2347                 rc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
2348         }
2349
2350         dvalue = strToDbl(fl_get_input(dialog_->input_huge));
2351         if (rc.font_sizes[LyXFont::SIZE_HUGE] != dvalue) {
2352                 changed = true;
2353                 rc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
2354         }
2355
2356         dvalue = strToDbl(fl_get_input(dialog_->input_huger));
2357         if (rc.font_sizes[LyXFont::SIZE_HUGER] != dvalue) {
2358                 changed = true;
2359                 rc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
2360         }
2361
2362         if (changed) {
2363                 // Now update the buffers
2364                 // Can anything below here affect the redraw process?
2365                 parent_.controller().updateScreenFonts();
2366         }
2367 }
2368
2369
2370 void FormPreferences::ScreenFonts::build()
2371 {
2372         dialog_.reset(build_preferences_screen_fonts(&parent_));
2373
2374         fl_set_counter_step(dialog_->counter_zoom, 1, 10);
2375         fl_set_counter_step(dialog_->counter_dpi,  1, 10);
2376
2377         fl_set_input_return(dialog_->input_roman,           FL_RETURN_CHANGED);
2378         fl_set_input_return(dialog_->input_sans,            FL_RETURN_CHANGED);
2379         fl_set_input_return(dialog_->input_typewriter,      FL_RETURN_CHANGED);
2380         fl_set_input_return(dialog_->input_screen_encoding, FL_RETURN_CHANGED);
2381         fl_set_counter_return(dialog_->counter_zoom,        FL_RETURN_CHANGED);
2382         fl_set_counter_return(dialog_->counter_dpi,         FL_RETURN_CHANGED);
2383         fl_set_input_return(dialog_->input_tiny,            FL_RETURN_CHANGED);
2384         fl_set_input_return(dialog_->input_script,          FL_RETURN_CHANGED);
2385         fl_set_input_return(dialog_->input_footnote,        FL_RETURN_CHANGED);
2386         fl_set_input_return(dialog_->input_small,           FL_RETURN_CHANGED);
2387         fl_set_input_return(dialog_->input_normal,          FL_RETURN_CHANGED);
2388         fl_set_input_return(dialog_->input_large,           FL_RETURN_CHANGED);
2389         fl_set_input_return(dialog_->input_larger,          FL_RETURN_CHANGED);
2390         fl_set_input_return(dialog_->input_largest,         FL_RETURN_CHANGED);
2391         fl_set_input_return(dialog_->input_huge,            FL_RETURN_CHANGED);
2392         fl_set_input_return(dialog_->input_huger,           FL_RETURN_CHANGED);
2393
2394         fl_set_input_filter(dialog_->input_tiny,     fl_unsigned_float_filter);
2395         fl_set_input_filter(dialog_->input_script,   fl_unsigned_float_filter);
2396         fl_set_input_filter(dialog_->input_footnote, fl_unsigned_float_filter);
2397         fl_set_input_filter(dialog_->input_small,    fl_unsigned_float_filter);
2398         fl_set_input_filter(dialog_->input_normal,   fl_unsigned_float_filter);
2399         fl_set_input_filter(dialog_->input_large,    fl_unsigned_float_filter);
2400         fl_set_input_filter(dialog_->input_larger,   fl_unsigned_float_filter);
2401         fl_set_input_filter(dialog_->input_largest,  fl_unsigned_float_filter);
2402         fl_set_input_filter(dialog_->input_huge,     fl_unsigned_float_filter);
2403         fl_set_input_filter(dialog_->input_huger,    fl_unsigned_float_filter);
2404
2405         // set up the feedback mechanism
2406         setPrehandler(dialog_->input_roman);
2407         setPrehandler(dialog_->input_sans);
2408         setPrehandler(dialog_->input_typewriter);
2409         setPrehandler(dialog_->counter_zoom);
2410         setPrehandler(dialog_->counter_dpi);
2411         setPrehandler(dialog_->check_scalable);
2412         setPrehandler(dialog_->input_screen_encoding);
2413         setPrehandler(dialog_->input_tiny);
2414         setPrehandler(dialog_->input_script);
2415         setPrehandler(dialog_->input_footnote);
2416         setPrehandler(dialog_->input_small);
2417         setPrehandler(dialog_->input_large);
2418         setPrehandler(dialog_->input_larger);
2419         setPrehandler(dialog_->input_largest);
2420         setPrehandler(dialog_->input_normal);
2421         setPrehandler(dialog_->input_huge);
2422         setPrehandler(dialog_->input_huger);
2423 }
2424
2425
2426 string const
2427 FormPreferences::ScreenFonts::feedback(FL_OBJECT const * const ob) const
2428 {
2429         if (ob == dialog_->input_roman)
2430                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ROMAN);
2431         if (ob == dialog_->input_sans)
2432                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SANS);
2433         if (ob == dialog_->input_typewriter)
2434                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_TYPEWRITER);
2435         if (ob == dialog_->check_scalable)
2436                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SCALABLE);
2437         if (ob == dialog_->input_screen_encoding)
2438                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ENCODING);
2439         if (ob == dialog_->counter_zoom)
2440                 return LyXRC::getDescription(LyXRC::RC_SCREEN_ZOOM);
2441         if (ob == dialog_->counter_dpi)
2442                 return LyXRC::getDescription(LyXRC::RC_SCREEN_DPI);
2443         if (ob == dialog_->input_tiny
2444             || ob == dialog_->input_script
2445             || ob == dialog_->input_footnote
2446             || ob == dialog_->input_small
2447             || ob == dialog_->input_large
2448             || ob == dialog_->input_larger
2449             || ob == dialog_->input_larger
2450             || ob == dialog_->input_largest
2451             || ob == dialog_->input_normal
2452             || ob == dialog_->input_huge
2453             || ob == dialog_->input_huger)
2454                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SIZES);
2455         return string();
2456 }
2457
2458
2459 bool FormPreferences::ScreenFonts::input()
2460 {
2461         bool activate = true;
2462         string str;
2463
2464         // Make sure that all fonts all have positive entries
2465         // Also note that an empty entry is returned as 0.0 by strToDbl
2466         if (0.0 >= strToDbl(fl_get_input(dialog_->input_tiny))
2467             || 0.0 >= strToDbl(fl_get_input(dialog_->input_script))
2468             || 0.0 >= strToDbl(fl_get_input(dialog_->input_footnote))
2469             || 0.0 >= strToDbl(fl_get_input(dialog_->input_small))
2470             || 0.0 >= strToDbl(fl_get_input(dialog_->input_normal))
2471             || 0.0 >= strToDbl(fl_get_input(dialog_->input_large))
2472             || 0.0 >= strToDbl(fl_get_input(dialog_->input_larger))
2473             || 0.0 >= strToDbl(fl_get_input(dialog_->input_largest))
2474             || 0.0 >= strToDbl(fl_get_input(dialog_->input_huge))
2475             || 0.0 >= strToDbl(fl_get_input(dialog_->input_huger))) {
2476                 activate = false;
2477                 str = _("Fonts must be positive!");
2478
2479         } else if (strToDbl(fl_get_input(dialog_->input_tiny)) >
2480                    // Fontsizes -- tiny < script < footnote etc.
2481                    strToDbl(fl_get_input(dialog_->input_script)) ||
2482                    strToDbl(fl_get_input(dialog_->input_script)) >
2483                    strToDbl(fl_get_input(dialog_->input_footnote)) ||
2484                    strToDbl(fl_get_input(dialog_->input_footnote)) >
2485                    strToDbl(fl_get_input(dialog_->input_small)) ||
2486                    strToDbl(fl_get_input(dialog_->input_small)) >
2487                    strToDbl(fl_get_input(dialog_->input_normal)) ||
2488                    strToDbl(fl_get_input(dialog_->input_normal)) >
2489                    strToDbl(fl_get_input(dialog_->input_large)) ||
2490                    strToDbl(fl_get_input(dialog_->input_large)) >
2491                    strToDbl(fl_get_input(dialog_->input_larger)) ||
2492                    strToDbl(fl_get_input(dialog_->input_larger)) >
2493                    strToDbl(fl_get_input(dialog_->input_largest)) ||
2494                    strToDbl(fl_get_input(dialog_->input_largest)) >
2495                    strToDbl(fl_get_input(dialog_->input_huge)) ||
2496                    strToDbl(fl_get_input(dialog_->input_huge)) >
2497                    strToDbl(fl_get_input(dialog_->input_huger))) {
2498                 activate = false;
2499
2500                 str = _("Fonts must be input in the order Tiny > Smallest > Smaller > Small > Normal > Large > Larger > Largest > Huge > Huger.");
2501         }
2502
2503         if (!activate)
2504                 parent_.postWarning(str);
2505
2506         return activate;
2507 }
2508
2509
2510 void FormPreferences::ScreenFonts::update(LyXRC const & rc)
2511 {
2512         fl_set_input(dialog_->input_roman,
2513                      makeFontName(rc.roman_font_name,
2514                                   rc.roman_font_foundry).c_str());
2515         fl_set_input(dialog_->input_sans,
2516                      makeFontName(rc.sans_font_name,
2517                                   rc.sans_font_foundry).c_str());
2518         fl_set_input(dialog_->input_typewriter,
2519                      makeFontName(rc.typewriter_font_name,
2520                                   rc.typewriter_font_foundry).c_str());
2521         fl_set_input(dialog_->input_screen_encoding,
2522                      rc.font_norm.c_str());
2523         fl_set_button(dialog_->check_scalable,
2524                       rc.use_scalable_fonts);
2525         fl_set_counter_value(dialog_->counter_zoom, rc.zoom);
2526         fl_set_counter_value(dialog_->counter_dpi,  rc.dpi);
2527         fl_set_input(dialog_->input_tiny,
2528                      tostr(rc.font_sizes[LyXFont::SIZE_TINY]).c_str());
2529         fl_set_input(dialog_->input_script,
2530                      tostr(rc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
2531         fl_set_input(dialog_->input_footnote,
2532                      tostr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
2533         fl_set_input(dialog_->input_small,
2534                      tostr(rc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
2535         fl_set_input(dialog_->input_normal,
2536                      tostr(rc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
2537         fl_set_input(dialog_->input_large,
2538                      tostr(rc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
2539         fl_set_input(dialog_->input_larger,
2540                      tostr(rc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
2541         fl_set_input(dialog_->input_largest,
2542                      tostr(rc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
2543         fl_set_input(dialog_->input_huge,
2544                      tostr(rc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
2545         fl_set_input(dialog_->input_huger,
2546                      tostr(rc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
2547 }
2548
2549
2550
2551 FormPreferences::SpellOptions::SpellOptions(FormPreferences &  p)
2552         : parent_(p)
2553 {}
2554
2555
2556 FD_preferences_spelloptions const * FormPreferences::SpellOptions::dialog()
2557 {
2558         return dialog_.get();
2559 }
2560
2561
2562 void FormPreferences::SpellOptions::apply(LyXRC & rc)
2563 {
2564         string choice = fl_get_choice_text(dialog_->choice_spell_command);
2565         choice = trim(choice);
2566
2567         rc.isp_command = choice;
2568
2569 #if 0
2570         // If spell checker == "none", all other input set to off.
2571         if (fl_get_choice(dialog_->choice_spell_command) == 1) {
2572                 rc.isp_use_alt_lang = false;
2573                 rc.isp_alt_lang.erase();
2574
2575                 rc.isp_use_esc_chars = false;
2576                 rc.isp_esc_chars.erase();
2577
2578                 rc.isp_use_pers_dict = false;
2579                 rc.isp_pers_dict.erase();
2580
2581                 rc.isp_accept_compound = false;
2582                 rc.isp_use_input_encoding = false;
2583         } else {
2584 #else
2585                 int button = fl_get_button(dialog_->check_alt_lang);
2586                 choice = fl_get_input(dialog_->input_alt_lang);
2587                 if (button && choice.empty()) button = 0;
2588                 if (!button) choice.erase();
2589
2590                 rc.isp_use_alt_lang = static_cast<bool>(button);
2591                 rc.isp_alt_lang = choice;
2592
2593                 button = fl_get_button(dialog_->check_escape_chars);
2594                 choice = fl_get_input(dialog_->input_escape_chars);
2595                 if (button && choice.empty()) button = 0;
2596                 if (!button) choice.erase();
2597
2598                 rc.isp_use_esc_chars = static_cast<bool>(button);
2599                 rc.isp_esc_chars = choice;
2600
2601                 button = fl_get_button(dialog_->check_personal_dict);
2602                 choice = fl_get_input(dialog_->input_personal_dict);
2603                 if (button && choice.empty()) button = 0;
2604                 if (!button) choice.erase();
2605
2606                 rc.isp_use_pers_dict = static_cast<bool>(button);
2607                 rc.isp_pers_dict = choice;
2608
2609                 button = fl_get_button(dialog_->check_compound_words);
2610                 rc.isp_accept_compound = static_cast<bool>(button);
2611
2612                 button = fl_get_button(dialog_->check_input_enc);
2613                 rc.isp_use_input_encoding = static_cast<bool>(button);
2614 #endif
2615 #if 0
2616         }
2617 #endif
2618
2619         // Reset view
2620         update(rc);
2621 }
2622
2623
2624 void FormPreferences::SpellOptions::build()
2625 {
2626         dialog_.reset(build_preferences_spelloptions(&parent_));
2627
2628         fl_addto_choice(dialog_->choice_spell_command,
2629                         _(" ispell | aspell ").c_str());
2630         fl_set_input_return(dialog_->input_alt_lang,      FL_RETURN_CHANGED);
2631         fl_set_input_return(dialog_->input_escape_chars,  FL_RETURN_CHANGED);
2632         fl_set_input_return(dialog_->input_personal_dict, FL_RETURN_CHANGED);
2633
2634         // set up the feedback mechanism
2635         setPrehandler(dialog_->choice_spell_command);
2636         setPrehandler(dialog_->check_alt_lang);
2637         setPrehandler(dialog_->input_alt_lang);
2638         setPrehandler(dialog_->check_escape_chars);
2639         setPrehandler(dialog_->input_escape_chars);
2640         setPrehandler(dialog_->check_personal_dict);
2641         setPrehandler(dialog_->input_personal_dict);
2642         setPrehandler(dialog_->button_personal_dict);
2643         setPrehandler(dialog_->check_compound_words);
2644         setPrehandler(dialog_->check_input_enc);
2645 }
2646
2647
2648 string const
2649 FormPreferences::SpellOptions::feedback(FL_OBJECT const * const ob) const
2650 {
2651         if (ob == dialog_->choice_spell_command)
2652                 return LyXRC::getDescription(LyXRC::RC_SPELL_COMMAND);
2653         if (ob == dialog_->check_alt_lang)
2654                 return LyXRC::getDescription(LyXRC::RC_USE_ALT_LANG);
2655         if (ob == dialog_->input_alt_lang)
2656                 return LyXRC::getDescription(LyXRC::RC_ALT_LANG);
2657         if (ob == dialog_->check_escape_chars)
2658                 return LyXRC::getDescription(LyXRC::RC_USE_ESC_CHARS);
2659         if (ob == dialog_->input_escape_chars)
2660                 return LyXRC::getDescription(LyXRC::RC_ESC_CHARS);
2661         if (ob == dialog_->check_personal_dict)
2662                 return LyXRC::getDescription(LyXRC::RC_USE_PERS_DICT);
2663         if (ob == dialog_->input_personal_dict)
2664                 return LyXRC::getDescription(LyXRC::RC_PERS_DICT);
2665         if (ob == dialog_->check_compound_words)
2666                 return LyXRC::getDescription(LyXRC::RC_ACCEPT_COMPOUND);
2667         if (ob == dialog_->check_input_enc)
2668                 return LyXRC::getDescription(LyXRC::RC_USE_INP_ENC);
2669         return string();
2670 }
2671
2672
2673 bool FormPreferences::SpellOptions::input(FL_OBJECT const * const ob)
2674 {
2675         // !ob if function is called from updateSpellOptions() to de/activate
2676         // objects,
2677         // otherwise the function is called by an xforms CB via input().
2678
2679 #if 0
2680         // If spell checker == "none", disable all input.
2681         if (!ob || ob == dialog_->choice_spell_command) {
2682                 if (fl_get_choice(dialog_->choice_spell_command) == 1) {
2683                         fl_deactivate_object(dialog_->check_alt_lang);
2684                         fl_deactivate_object(dialog_->input_alt_lang);
2685                         fl_deactivate_object(dialog_->check_escape_chars);
2686                         fl_deactivate_object(dialog_->input_escape_chars);
2687                         fl_deactivate_object(dialog_->check_personal_dict);
2688                         fl_deactivate_object(dialog_->input_personal_dict);
2689                         fl_deactivate_object(dialog_->check_compound_words);
2690                         fl_deactivate_object(dialog_->check_input_enc);
2691                         return true;
2692                 } else {
2693                         fl_activate_object(dialog_->check_alt_lang);
2694                         fl_activate_object(dialog_->check_escape_chars);
2695                         fl_activate_object(dialog_->check_personal_dict);
2696                         fl_activate_object(dialog_->check_compound_words);
2697                         fl_activate_object(dialog_->check_input_enc);
2698                 }
2699         }
2700 #endif
2701
2702         if (!ob || ob == dialog_->check_alt_lang) {
2703                 bool const enable = fl_get_button(dialog_->check_alt_lang);
2704                 setEnabled(dialog_->input_alt_lang, enable);
2705         }
2706
2707         if (!ob || ob == dialog_->check_escape_chars) {
2708                 bool const enable = fl_get_button(dialog_->check_escape_chars);
2709                 setEnabled(dialog_->input_escape_chars, enable);
2710         }
2711
2712         if (!ob || ob == dialog_->check_personal_dict) {
2713                 bool const enable = fl_get_button(dialog_->check_personal_dict);
2714                 setEnabled(dialog_->input_personal_dict, enable);
2715         }
2716
2717         if (ob == dialog_->button_personal_dict) {
2718                 string f = parent_.controller().browsedict(
2719                         fl_get_input(dialog_->input_personal_dict));
2720                 fl_set_input(dialog_->input_personal_dict, f.c_str());
2721         }
2722
2723         return true; // All input is valid!
2724 }
2725
2726
2727 void FormPreferences::SpellOptions::update(LyXRC const & rc)
2728 {
2729         int choice = 1;
2730 #if 0
2731         if (rc.isp_command == "none")
2732                 choice = 1;
2733         else if (rc.isp_command == "ispell")
2734                 choice = 2;
2735         else if (rc.isp_command == "aspell")
2736                 choice = 3;
2737 #else
2738         if (rc.isp_command == "ispell")
2739                 choice = 1;
2740         else if (rc.isp_command == "aspell")
2741                 choice = 2;
2742 #endif
2743         fl_set_choice(dialog_->choice_spell_command, choice);
2744
2745         string str;
2746         if (rc.isp_use_alt_lang)
2747                 str = rc.isp_alt_lang;
2748
2749         fl_set_button(dialog_->check_alt_lang,
2750                       rc.isp_use_alt_lang);
2751         fl_set_input(dialog_->input_alt_lang, str.c_str());
2752
2753         str.erase();
2754         if (rc.isp_use_esc_chars)
2755                 str = rc.isp_esc_chars;
2756
2757         fl_set_button(dialog_->check_escape_chars,
2758                       rc.isp_use_esc_chars);
2759         fl_set_input(dialog_->input_escape_chars, str.c_str());
2760
2761         str.erase();
2762         if (rc.isp_use_pers_dict)
2763                 str = rc.isp_pers_dict;
2764
2765         fl_set_button(dialog_->check_personal_dict,
2766                       rc.isp_use_pers_dict);
2767         fl_set_input(dialog_->input_personal_dict, str.c_str());
2768
2769         fl_set_button(dialog_->check_compound_words,
2770                       rc.isp_accept_compound);
2771         fl_set_button(dialog_->check_input_enc,
2772                       rc.isp_use_input_encoding);
2773
2774         // Activate/Deactivate the input fields dependent on the state of the
2775         // buttons.
2776         input(0);
2777 }