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