]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormPreferences.C
Introduce LFUN_PRINT.
[lyx.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         rc.tempdir_path  = fl_get_input(dialog_->input_temp_dir);
1829
1830         int button = fl_get_button(dialog_->check_last_files);
1831         string str = fl_get_input(dialog_->input_lastfiles);
1832         if (!button) str.erase();
1833
1834         rc.check_lastfiles = button;
1835         rc.lastfiles = str;
1836         rc.num_lastfiles = static_cast<unsigned int>
1837                 (fl_get_counter_value(dialog_->counter_lastfiles));
1838
1839         button = fl_get_button(dialog_->check_make_backups);
1840         str = fl_get_input(dialog_->input_backup_path);
1841         if (!button)
1842                 str.erase();
1843
1844         rc.make_backup = button;
1845         rc.backupdir_path = str;
1846
1847         rc.lyxpipes = fl_get_input(dialog_->input_serverpipe);
1848
1849         // update view
1850         update(rc);
1851 }
1852
1853
1854 void FormPreferences::Paths::build()
1855 {
1856         dialog_.reset(build_preferences_paths(&parent_));
1857
1858         fl_set_input_return(dialog_->input_default_path, FL_RETURN_CHANGED);
1859         fl_set_input_return(dialog_->input_template_path, FL_RETURN_CHANGED);
1860         fl_set_input_return(dialog_->input_temp_dir, FL_RETURN_CHANGED);
1861         fl_set_input_return(dialog_->input_lastfiles, FL_RETURN_CHANGED);
1862         fl_set_input_return(dialog_->input_backup_path, FL_RETURN_CHANGED);
1863         fl_set_counter_return(dialog_->counter_lastfiles, FL_RETURN_CHANGED);
1864         fl_set_input_return(dialog_->input_serverpipe, FL_RETURN_CHANGED);
1865
1866         // set up the feedback mechanism
1867         setPrehandler(dialog_->input_default_path);
1868         setPrehandler(dialog_->counter_lastfiles);
1869         setPrehandler(dialog_->input_template_path);
1870         setPrehandler(dialog_->check_last_files);
1871         setPrehandler(dialog_->input_lastfiles);
1872         setPrehandler(dialog_->check_make_backups);
1873         setPrehandler(dialog_->input_backup_path);
1874         setPrehandler(dialog_->input_serverpipe);
1875         setPrehandler(dialog_->input_temp_dir);
1876 }
1877
1878
1879 string const
1880 FormPreferences::Paths::feedback(FL_OBJECT const * const ob) const
1881 {
1882         if (ob == dialog_->input_default_path)
1883                 return LyXRC::getDescription(LyXRC::RC_DOCUMENTPATH);
1884         if (ob == dialog_->input_template_path)
1885                 return LyXRC::getDescription(LyXRC::RC_TEMPLATEPATH);
1886         if (ob == dialog_->input_temp_dir)
1887                 return LyXRC::getDescription(LyXRC::RC_TEMPDIRPATH);
1888         if (ob == dialog_->check_last_files)
1889                 return LyXRC::getDescription(LyXRC::RC_CHECKLASTFILES);
1890         if (ob == dialog_->input_lastfiles)
1891                 return LyXRC::getDescription(LyXRC::RC_LASTFILES);
1892         if (ob == dialog_->counter_lastfiles)
1893                 return LyXRC::getDescription(LyXRC::RC_NUMLASTFILES);
1894         if (ob == dialog_->check_make_backups)
1895                 return LyXRC::getDescription(LyXRC::RC_MAKE_BACKUP);
1896         if (ob == dialog_->input_backup_path)
1897                 return LyXRC::getDescription(LyXRC::RC_BACKUPDIR_PATH);
1898         if (ob == dialog_->input_serverpipe)
1899                 return LyXRC::getDescription(LyXRC::RC_SERVERPIPE);
1900         return string();
1901 }
1902
1903
1904 bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
1905 {
1906         bool activate = true;
1907
1908         // !ob if function is called from Paths::update() to de/activate
1909         // objects,
1910         // otherwise the function is called by an xforms CB via input().
1911         if (!ob || ob == dialog_->check_last_files) {
1912                 bool const enable = fl_get_button(dialog_->check_last_files);
1913                 setEnabled(dialog_->input_lastfiles, enable);
1914         }
1915
1916         if (!ob || ob == dialog_->check_make_backups) {
1917                 bool const enable = fl_get_button(dialog_->check_make_backups);
1918                 setEnabled(dialog_->input_backup_path, enable);
1919         }
1920
1921         if (!ob || ob == dialog_->input_default_path) {
1922                 string const name = fl_get_input(dialog_->input_default_path);
1923                 if (!name.empty() && !RWInfo::WriteableDir(name)) {
1924                         parent_.postWarning(RWInfo::ErrorMessage());
1925                         return false;
1926                 }
1927         }
1928
1929         if (!ob || ob == dialog_->input_template_path) {
1930                 string const name = fl_get_input(dialog_->input_template_path);
1931                 if (!name.empty() && !RWInfo::ReadableDir(name)) {
1932                         parent_.postWarning(RWInfo::ErrorMessage());
1933                         return false;
1934                 }
1935         }
1936
1937         if (!ob || ob == dialog_->input_temp_dir) {
1938                 string const name = fl_get_input(dialog_->input_temp_dir);
1939                 if (fl_get_button(dialog_->check_make_backups)
1940                     && !name.empty()
1941                     && !RWInfo::WriteableDir(name)) {
1942                         parent_.postWarning(RWInfo::ErrorMessage());
1943                         return false;
1944                 }
1945         }
1946
1947         if (!ob || ob == dialog_->input_backup_path) {
1948                 string const name = fl_get_input(dialog_->input_backup_path);
1949                 if (fl_get_button(dialog_->check_make_backups)
1950                     && !name.empty()
1951                     && !RWInfo::WriteableDir(name)) {
1952                         parent_.postWarning(RWInfo::ErrorMessage());
1953                         return false;
1954                 }
1955         }
1956
1957         if (!ob || ob == dialog_->input_lastfiles) {
1958                 string const name = fl_get_input(dialog_->input_lastfiles);
1959                 if (fl_get_button(dialog_->check_last_files)
1960                     && !name.empty()
1961                     && !RWInfo::WriteableFile(name)) {
1962                         parent_.postWarning(RWInfo::ErrorMessage());
1963                         return false;
1964                 }
1965         }
1966
1967         if (!ob || ob == dialog_->input_serverpipe) {
1968                 string const name = fl_get_input(dialog_->input_serverpipe);
1969                 if (!name.empty()) {
1970                         // strip off the extension
1971                         string const str = ChangeExtension(name, "");
1972                         if (!RWInfo::WriteableFile(str + ".in")) {
1973                                 parent_.postWarning(RWInfo::ErrorMessage());
1974                                 return false;
1975                         }
1976                         if (!RWInfo::WriteableFile(str + ".out")) {
1977                                 parent_.postWarning(RWInfo::ErrorMessage());
1978                                 return false;
1979                         }
1980                 }
1981         }
1982
1983         if (ob == dialog_->button_default_path_browse) {
1984                 string f = parent_.controller().browsedir(
1985                         fl_get_input(dialog_->input_default_path), _("Default path"));
1986                 if (!f.empty())
1987                         fl_set_input(dialog_->input_default_path, f.c_str());
1988         } else if (ob == dialog_->button_template_path_browse) {
1989                 string f = parent_.controller().browsedir(
1990                         fl_get_input(dialog_->input_template_path), _("Template path"));
1991                 if (!f.empty())
1992                         fl_set_input(dialog_->input_template_path, f.c_str());
1993         } else if (ob == dialog_->button_temp_dir_browse) {
1994                 string f = parent_.controller().browsedir(
1995                         fl_get_input(dialog_->input_temp_dir), _("Temporary dir"));
1996                 if (!f.empty())
1997                         fl_set_input(dialog_->input_temp_dir, f.c_str());
1998         } else if (ob == dialog_->button_lastfiles_browse) {
1999                 string f = parent_.controller().browse(
2000                         fl_get_input(dialog_->input_lastfiles), _("Last files"));
2001                 if (!f.empty())
2002                         fl_set_input(dialog_->input_lastfiles, f.c_str());
2003         } else if (ob == dialog_->button_backup_path_browse) {
2004                 string f = parent_.controller().browsedir(
2005                         fl_get_input(dialog_->input_backup_path), _("Backup path"));
2006                 if (!f.empty())
2007                         fl_set_input(dialog_->input_backup_path, f.c_str());
2008         } else if (ob == dialog_->button_serverpipe_browse) {
2009                 string f = parent_.controller().browse(
2010                         fl_get_input(dialog_->input_serverpipe), _("LyX server pipes"));
2011                 if (!f.empty())
2012                         fl_set_input(dialog_->input_serverpipe, f.c_str());
2013         }
2014
2015         return activate;
2016 }
2017
2018
2019 void FormPreferences::Paths::update(LyXRC const & rc)
2020 {
2021         fl_set_input(dialog_->input_default_path,
2022                      rc.document_path.c_str());
2023         fl_set_input(dialog_->input_template_path,
2024                      rc.template_path.c_str());
2025
2026         string str;
2027         if (rc.make_backup)
2028                 str = rc.backupdir_path;
2029
2030         fl_set_button(dialog_->check_make_backups,
2031                       rc.make_backup);
2032         fl_set_input(dialog_->input_backup_path, str.c_str());
2033
2034         fl_set_input(dialog_->input_temp_dir, rc.tempdir_path.c_str());
2035
2036         str.erase();
2037         if (rc.check_lastfiles)
2038                 str = rc.lastfiles;
2039
2040         fl_set_button(dialog_->check_last_files,
2041                       rc.check_lastfiles);
2042         fl_set_input(dialog_->input_lastfiles, str.c_str());
2043         fl_set_counter_value(dialog_->counter_lastfiles,
2044                              rc.num_lastfiles);
2045
2046         fl_set_input(dialog_->input_serverpipe, rc.lyxpipes.c_str());
2047
2048         // Activate/Deactivate the input fields dependent on the state of the
2049         // buttons.
2050         input(0);
2051 }
2052
2053
2054 FormPreferences::Printer::Printer(FormPreferences &  p)
2055         : parent_(p)
2056 {}
2057
2058
2059 FD_preferences_printer const * FormPreferences::Printer::dialog()
2060 {
2061         return dialog_.get();
2062 }
2063
2064
2065 void FormPreferences::Printer::apply(LyXRC & rc) const
2066 {
2067         rc.print_adapt_output = fl_get_button(dialog_->check_adapt_output);
2068         rc.print_command = fl_get_input(dialog_->input_command);
2069         rc.print_pagerange_flag = fl_get_input(dialog_->input_page_range);
2070         rc.print_copies_flag = fl_get_input(dialog_->input_copies);
2071         rc.print_reverse_flag = fl_get_input(dialog_->input_reverse);
2072         rc.print_to_printer = fl_get_input(dialog_->input_to_printer);
2073         rc.print_file_extension =
2074                 fl_get_input(dialog_->input_file_extension);
2075         rc.print_spool_command =
2076                 fl_get_input(dialog_->input_spool_command);
2077         rc.print_paper_flag = fl_get_input(dialog_->input_paper_type);
2078         rc.print_evenpage_flag = fl_get_input(dialog_->input_even_pages);
2079         rc.print_oddpage_flag = fl_get_input(dialog_->input_odd_pages);
2080         rc.print_collcopies_flag = fl_get_input(dialog_->input_collated);
2081         rc.print_landscape_flag = fl_get_input(dialog_->input_landscape);
2082         rc.print_to_file = fl_get_input(dialog_->input_to_file);
2083         rc.print_extra_options =
2084                 fl_get_input(dialog_->input_extra_options);
2085         rc.print_spool_printerprefix =
2086                 fl_get_input(dialog_->input_spool_prefix);
2087         rc.print_paper_dimension_flag =
2088                 fl_get_input(dialog_->input_paper_size);
2089         rc.printer = fl_get_input(dialog_->input_name);
2090 }
2091
2092
2093 string const
2094 FormPreferences::Printer::feedback(FL_OBJECT const * const ob) const
2095 {
2096         if (ob == dialog_->input_command)
2097                 return LyXRC::getDescription(LyXRC::RC_PRINT_COMMAND);
2098         if (ob == dialog_->check_adapt_output)
2099                 return LyXRC::getDescription(LyXRC::RC_PRINT_ADAPTOUTPUT);
2100         if (ob == dialog_->input_to_printer)
2101                 return LyXRC::getDescription(LyXRC::RC_PRINTTOPRINTER);
2102         if (ob == dialog_->input_to_file)
2103                 return LyXRC::getDescription(LyXRC::RC_PRINTTOFILE);
2104         if (ob == dialog_->input_file_extension)
2105                 return LyXRC::getDescription(LyXRC::RC_PRINTFILEEXTENSION);
2106         if (ob == dialog_->input_extra_options)
2107                 return LyXRC::getDescription(LyXRC::RC_PRINTEXSTRAOPTIONS);
2108         if (ob == dialog_->input_spool_command)
2109                 return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_COMMAND);
2110         if (ob == dialog_->input_spool_prefix)
2111                 return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_PRINTERPREFIX);
2112         if (ob == dialog_->input_name)
2113                 return LyXRC::getDescription(LyXRC::RC_PRINTER);
2114         if (ob == dialog_->input_even_pages)
2115                 return LyXRC::getDescription(LyXRC::RC_PRINTEVENPAGEFLAG);
2116         if (ob == dialog_->input_odd_pages)
2117                 return LyXRC::getDescription(LyXRC::RC_PRINTODDPAGEFLAG);
2118         if (ob == dialog_->input_page_range)
2119                 return LyXRC::getDescription(LyXRC::RC_PRINTPAGERANGEFLAG);
2120         if (ob == dialog_->input_reverse)
2121                 return LyXRC::getDescription(LyXRC::RC_PRINTREVERSEFLAG);
2122         if (ob == dialog_->input_landscape)
2123                 return LyXRC::getDescription(LyXRC::RC_PRINTLANDSCAPEFLAG);
2124         if (ob == dialog_->input_copies)
2125                 return LyXRC::getDescription(LyXRC::RC_PRINTCOPIESFLAG);
2126         if (ob == dialog_->input_collated)
2127                 return LyXRC::getDescription(LyXRC::RC_PRINTCOLLCOPIESFLAG);
2128         if (ob == dialog_->input_paper_type)
2129                 return LyXRC::getDescription(LyXRC::RC_PRINTPAPERFLAG);
2130         if (ob == dialog_->input_paper_size)
2131                 return LyXRC::getDescription(LyXRC::RC_PRINTPAPERDIMENSIONFLAG);
2132         return string();
2133 }
2134
2135
2136 void FormPreferences::Printer::build()
2137 {
2138         dialog_.reset(build_preferences_printer(&parent_));
2139
2140         fl_set_input_return(dialog_->input_command, FL_RETURN_CHANGED);
2141         fl_set_input_return(dialog_->input_page_range, FL_RETURN_CHANGED);
2142         fl_set_input_return(dialog_->input_copies, FL_RETURN_CHANGED);
2143         fl_set_input_return(dialog_->input_reverse, FL_RETURN_CHANGED);
2144         fl_set_input_return(dialog_->input_to_printer, FL_RETURN_CHANGED);
2145         fl_set_input_return(dialog_->input_file_extension, FL_RETURN_CHANGED);
2146         fl_set_input_return(dialog_->input_spool_command, FL_RETURN_CHANGED);
2147         fl_set_input_return(dialog_->input_paper_type, FL_RETURN_CHANGED);
2148         fl_set_input_return(dialog_->input_even_pages, FL_RETURN_CHANGED);
2149         fl_set_input_return(dialog_->input_odd_pages, FL_RETURN_CHANGED);
2150         fl_set_input_return(dialog_->input_collated, FL_RETURN_CHANGED);
2151         fl_set_input_return(dialog_->input_landscape, FL_RETURN_CHANGED);
2152         fl_set_input_return(dialog_->input_to_file, FL_RETURN_CHANGED);
2153         fl_set_input_return(dialog_->input_extra_options, FL_RETURN_CHANGED);
2154         fl_set_input_return(dialog_->input_spool_prefix, FL_RETURN_CHANGED);
2155         fl_set_input_return(dialog_->input_paper_size, FL_RETURN_CHANGED);
2156         fl_set_input_return(dialog_->input_name, FL_RETURN_CHANGED);
2157
2158         // set up the feedback mechanism
2159         setPrehandler(dialog_->input_command);
2160         setPrehandler(dialog_->input_page_range);
2161         setPrehandler(dialog_->input_copies);
2162         setPrehandler(dialog_->input_reverse);
2163         setPrehandler(dialog_->input_to_printer);
2164         setPrehandler(dialog_->input_file_extension);
2165         setPrehandler(dialog_->input_spool_command);
2166         setPrehandler(dialog_->input_paper_type);
2167         setPrehandler(dialog_->input_even_pages);
2168         setPrehandler(dialog_->input_odd_pages);
2169         setPrehandler(dialog_->input_collated);
2170         setPrehandler(dialog_->input_landscape);
2171         setPrehandler(dialog_->input_to_file);
2172         setPrehandler(dialog_->input_extra_options);
2173         setPrehandler(dialog_->input_spool_prefix);
2174         setPrehandler(dialog_->input_paper_size);
2175         setPrehandler(dialog_->input_name);
2176         setPrehandler(dialog_->check_adapt_output);
2177 }
2178
2179
2180 void FormPreferences::Printer::update(LyXRC const & rc)
2181 {
2182         fl_set_button(dialog_->check_adapt_output,
2183                       rc.print_adapt_output);
2184         fl_set_input(dialog_->input_command,
2185                      rc.print_command.c_str());
2186         fl_set_input(dialog_->input_page_range,
2187                      rc.print_pagerange_flag.c_str());
2188         fl_set_input(dialog_->input_copies,
2189                      rc.print_copies_flag.c_str());
2190         fl_set_input(dialog_->input_reverse,
2191                      rc.print_reverse_flag.c_str());
2192         fl_set_input(dialog_->input_to_printer,
2193                      rc.print_to_printer.c_str());
2194         fl_set_input(dialog_->input_file_extension,
2195                      rc.print_file_extension.c_str());
2196         fl_set_input(dialog_->input_spool_command,
2197                      rc.print_spool_command.c_str());
2198         fl_set_input(dialog_->input_paper_type,
2199                      rc.print_paper_flag.c_str());
2200         fl_set_input(dialog_->input_even_pages,
2201                      rc.print_evenpage_flag.c_str());
2202         fl_set_input(dialog_->input_odd_pages,
2203                      rc.print_oddpage_flag.c_str());
2204         fl_set_input(dialog_->input_collated,
2205                      rc.print_collcopies_flag.c_str());
2206         fl_set_input(dialog_->input_landscape,
2207                      rc.print_landscape_flag.c_str());
2208         fl_set_input(dialog_->input_to_file,
2209                      rc.print_to_file.c_str());
2210         fl_set_input(dialog_->input_extra_options,
2211                      rc.print_extra_options.c_str());
2212         fl_set_input(dialog_->input_spool_prefix,
2213                      rc.print_spool_printerprefix.c_str());
2214         fl_set_input(dialog_->input_paper_size,
2215                      rc.print_paper_dimension_flag.c_str());
2216         fl_set_input(dialog_->input_name,
2217                      rc.printer.c_str());
2218 }
2219
2220
2221 FormPreferences::ScreenFonts::ScreenFonts(FormPreferences &  p)
2222         : parent_(p)
2223 {}
2224
2225
2226 FD_preferences_screen_fonts const * FormPreferences::ScreenFonts::dialog()
2227 {
2228         return dialog_.get();
2229 }
2230
2231
2232 void FormPreferences::ScreenFonts::apply(LyXRC & rc) const
2233 {
2234         bool changed = false;
2235
2236         pair<string, string> tmp =
2237                 parseFontName(fl_get_input(dialog_->input_roman));
2238         if (rc.roman_font_name != tmp.first ||
2239             rc.roman_font_foundry != tmp.second) {
2240                 changed = true;
2241                 rc.roman_font_name = tmp.first;
2242                 rc.roman_font_foundry = tmp.second;
2243         }
2244
2245         tmp = parseFontName(fl_get_input(dialog_->input_sans));
2246         if (rc.sans_font_name != tmp.first ||
2247             rc.sans_font_foundry != tmp.second) {
2248                 changed = true;
2249                 rc.sans_font_name = tmp.first;
2250                 rc.sans_font_foundry = tmp.second;
2251         }
2252
2253         tmp = parseFontName(fl_get_input(dialog_->input_typewriter));
2254         if (rc.typewriter_font_name != tmp.first ||
2255             rc.typewriter_font_foundry != tmp.second) {
2256                 changed = true;
2257                 rc.typewriter_font_name = tmp.first;
2258                 rc.typewriter_font_foundry = tmp.second;
2259         }
2260
2261         string str = fl_get_input(dialog_->input_screen_encoding);
2262         if (rc.font_norm != str) {
2263                 changed = true;
2264                 rc.font_norm = str;
2265                 rc.set_font_norm_type();
2266         }
2267
2268         bool button = fl_get_button(dialog_->check_scalable);
2269         if (rc.use_scalable_fonts != button) {
2270                 changed = true;
2271                 rc.use_scalable_fonts = button;
2272         }
2273
2274         unsigned int ivalue = static_cast<unsigned int>
2275                 (fl_get_counter_value(dialog_->counter_zoom));
2276         if (rc.zoom != ivalue) {
2277                 changed = true;
2278                 rc.zoom = ivalue;
2279         }
2280
2281         ivalue = static_cast<unsigned int>
2282                 (fl_get_counter_value(dialog_->counter_dpi));
2283         if (rc.dpi != ivalue) {
2284                 changed = true;
2285                 rc.dpi = ivalue;
2286         }
2287
2288         double dvalue = strToDbl(fl_get_input(dialog_->input_tiny));
2289         if (rc.font_sizes[LyXFont::SIZE_TINY] != dvalue) {
2290                 changed = true;
2291                 rc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
2292         }
2293
2294         dvalue = strToDbl(fl_get_input(dialog_->input_script));
2295         if (rc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue) {
2296                 changed = true;
2297                 rc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
2298         }
2299
2300         dvalue = strToDbl(fl_get_input(dialog_->input_footnote));
2301         if (rc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue) {
2302                 changed = true;
2303                 rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
2304         }
2305
2306         dvalue = strToDbl(fl_get_input(dialog_->input_small));
2307         if (rc.font_sizes[LyXFont::SIZE_SMALL] != dvalue) {
2308                 changed = true;
2309                 rc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
2310         }
2311
2312         dvalue = strToDbl(fl_get_input(dialog_->input_normal));
2313         if (rc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue) {
2314                 changed = true;
2315                 rc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
2316         }
2317
2318         dvalue = strToDbl(fl_get_input(dialog_->input_large));
2319         if (rc.font_sizes[LyXFont::SIZE_LARGE] != dvalue) {
2320                 changed = true;
2321                 rc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
2322         }
2323
2324         dvalue = strToDbl(fl_get_input(dialog_->input_larger));
2325         if (rc.font_sizes[LyXFont::SIZE_LARGER] != dvalue) {
2326                 changed = true;
2327                 rc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
2328         }
2329
2330         dvalue = strToDbl(fl_get_input(dialog_->input_largest));
2331         if (rc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue) {
2332                 changed = true;
2333                 rc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
2334         }
2335
2336         dvalue = strToDbl(fl_get_input(dialog_->input_huge));
2337         if (rc.font_sizes[LyXFont::SIZE_HUGE] != dvalue) {
2338                 changed = true;
2339                 rc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
2340         }
2341
2342         dvalue = strToDbl(fl_get_input(dialog_->input_huger));
2343         if (rc.font_sizes[LyXFont::SIZE_HUGER] != dvalue) {
2344                 changed = true;
2345                 rc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
2346         }
2347
2348         if (changed) {
2349                 // Now update the buffers
2350                 // Can anything below here affect the redraw process?
2351                 parent_.controller().updateScreenFonts();
2352         }
2353 }
2354
2355
2356 void FormPreferences::ScreenFonts::build()
2357 {
2358         dialog_.reset(build_preferences_screen_fonts(&parent_));
2359
2360         fl_set_counter_step(dialog_->counter_zoom, 1, 10);
2361         fl_set_counter_step(dialog_->counter_dpi,  1, 10);
2362
2363         fl_set_input_return(dialog_->input_roman,           FL_RETURN_CHANGED);
2364         fl_set_input_return(dialog_->input_sans,            FL_RETURN_CHANGED);
2365         fl_set_input_return(dialog_->input_typewriter,      FL_RETURN_CHANGED);
2366         fl_set_input_return(dialog_->input_screen_encoding, FL_RETURN_CHANGED);
2367         fl_set_counter_return(dialog_->counter_zoom,        FL_RETURN_CHANGED);
2368         fl_set_counter_return(dialog_->counter_dpi,         FL_RETURN_CHANGED);
2369         fl_set_input_return(dialog_->input_tiny,            FL_RETURN_CHANGED);
2370         fl_set_input_return(dialog_->input_script,          FL_RETURN_CHANGED);
2371         fl_set_input_return(dialog_->input_footnote,        FL_RETURN_CHANGED);
2372         fl_set_input_return(dialog_->input_small,           FL_RETURN_CHANGED);
2373         fl_set_input_return(dialog_->input_normal,          FL_RETURN_CHANGED);
2374         fl_set_input_return(dialog_->input_large,           FL_RETURN_CHANGED);
2375         fl_set_input_return(dialog_->input_larger,          FL_RETURN_CHANGED);
2376         fl_set_input_return(dialog_->input_largest,         FL_RETURN_CHANGED);
2377         fl_set_input_return(dialog_->input_huge,            FL_RETURN_CHANGED);
2378         fl_set_input_return(dialog_->input_huger,           FL_RETURN_CHANGED);
2379
2380         fl_set_input_filter(dialog_->input_tiny,     fl_unsigned_float_filter);
2381         fl_set_input_filter(dialog_->input_script,   fl_unsigned_float_filter);
2382         fl_set_input_filter(dialog_->input_footnote, fl_unsigned_float_filter);
2383         fl_set_input_filter(dialog_->input_small,    fl_unsigned_float_filter);
2384         fl_set_input_filter(dialog_->input_normal,   fl_unsigned_float_filter);
2385         fl_set_input_filter(dialog_->input_large,    fl_unsigned_float_filter);
2386         fl_set_input_filter(dialog_->input_larger,   fl_unsigned_float_filter);
2387         fl_set_input_filter(dialog_->input_largest,  fl_unsigned_float_filter);
2388         fl_set_input_filter(dialog_->input_huge,     fl_unsigned_float_filter);
2389         fl_set_input_filter(dialog_->input_huger,    fl_unsigned_float_filter);
2390
2391         // set up the feedback mechanism
2392         setPrehandler(dialog_->input_roman);
2393         setPrehandler(dialog_->input_sans);
2394         setPrehandler(dialog_->input_typewriter);
2395         setPrehandler(dialog_->counter_zoom);
2396         setPrehandler(dialog_->counter_dpi);
2397         setPrehandler(dialog_->check_scalable);
2398         setPrehandler(dialog_->input_screen_encoding);
2399         setPrehandler(dialog_->input_tiny);
2400         setPrehandler(dialog_->input_script);
2401         setPrehandler(dialog_->input_footnote);
2402         setPrehandler(dialog_->input_small);
2403         setPrehandler(dialog_->input_large);
2404         setPrehandler(dialog_->input_larger);
2405         setPrehandler(dialog_->input_largest);
2406         setPrehandler(dialog_->input_normal);
2407         setPrehandler(dialog_->input_huge);
2408         setPrehandler(dialog_->input_huger);
2409 }
2410
2411
2412 string const
2413 FormPreferences::ScreenFonts::feedback(FL_OBJECT const * const ob) const
2414 {
2415         if (ob == dialog_->input_roman)
2416                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ROMAN);
2417         if (ob == dialog_->input_sans)
2418                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SANS);
2419         if (ob == dialog_->input_typewriter)
2420                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_TYPEWRITER);
2421         if (ob == dialog_->check_scalable)
2422                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SCALABLE);
2423         if (ob == dialog_->input_screen_encoding)
2424                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ENCODING);
2425         if (ob == dialog_->counter_zoom)
2426                 return LyXRC::getDescription(LyXRC::RC_SCREEN_ZOOM);
2427         if (ob == dialog_->counter_dpi)
2428                 return LyXRC::getDescription(LyXRC::RC_SCREEN_DPI);
2429         if (ob == dialog_->input_tiny
2430             || ob == dialog_->input_script
2431             || ob == dialog_->input_footnote
2432             || ob == dialog_->input_small
2433             || ob == dialog_->input_large
2434             || ob == dialog_->input_larger
2435             || ob == dialog_->input_larger
2436             || ob == dialog_->input_largest
2437             || ob == dialog_->input_normal
2438             || ob == dialog_->input_huge
2439             || ob == dialog_->input_huger)
2440                 return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SIZES);
2441         return string();
2442 }
2443
2444
2445 bool FormPreferences::ScreenFonts::input()
2446 {
2447         bool activate = true;
2448         string str;
2449
2450         // Make sure that all fonts all have positive entries
2451         // Also note that an empty entry is returned as 0.0 by strToDbl
2452         if (0.0 >= strToDbl(fl_get_input(dialog_->input_tiny))
2453             || 0.0 >= strToDbl(fl_get_input(dialog_->input_script))
2454             || 0.0 >= strToDbl(fl_get_input(dialog_->input_footnote))
2455             || 0.0 >= strToDbl(fl_get_input(dialog_->input_small))
2456             || 0.0 >= strToDbl(fl_get_input(dialog_->input_normal))
2457             || 0.0 >= strToDbl(fl_get_input(dialog_->input_large))
2458             || 0.0 >= strToDbl(fl_get_input(dialog_->input_larger))
2459             || 0.0 >= strToDbl(fl_get_input(dialog_->input_largest))
2460             || 0.0 >= strToDbl(fl_get_input(dialog_->input_huge))
2461             || 0.0 >= strToDbl(fl_get_input(dialog_->input_huger))) {
2462                 activate = false;
2463                 str = _("Fonts must be positive!");
2464
2465         } else if (strToDbl(fl_get_input(dialog_->input_tiny)) >
2466                    // Fontsizes -- tiny < script < footnote etc.
2467                    strToDbl(fl_get_input(dialog_->input_script)) ||
2468                    strToDbl(fl_get_input(dialog_->input_script)) >
2469                    strToDbl(fl_get_input(dialog_->input_footnote)) ||
2470                    strToDbl(fl_get_input(dialog_->input_footnote)) >
2471                    strToDbl(fl_get_input(dialog_->input_small)) ||
2472                    strToDbl(fl_get_input(dialog_->input_small)) >
2473                    strToDbl(fl_get_input(dialog_->input_normal)) ||
2474                    strToDbl(fl_get_input(dialog_->input_normal)) >
2475                    strToDbl(fl_get_input(dialog_->input_large)) ||
2476                    strToDbl(fl_get_input(dialog_->input_large)) >
2477                    strToDbl(fl_get_input(dialog_->input_larger)) ||
2478                    strToDbl(fl_get_input(dialog_->input_larger)) >
2479                    strToDbl(fl_get_input(dialog_->input_largest)) ||
2480                    strToDbl(fl_get_input(dialog_->input_largest)) >
2481                    strToDbl(fl_get_input(dialog_->input_huge)) ||
2482                    strToDbl(fl_get_input(dialog_->input_huge)) >
2483                    strToDbl(fl_get_input(dialog_->input_huger))) {
2484                 activate = false;
2485
2486                 str = _("Fonts must be input in the order Tiny > Smallest > Smaller > Small > Normal > Large > Larger > Largest > Huge > Huger.");
2487         }
2488
2489         if (!activate)
2490                 parent_.postWarning(str);
2491
2492         return activate;
2493 }
2494
2495
2496 void FormPreferences::ScreenFonts::update(LyXRC const & rc)
2497 {
2498         fl_set_input(dialog_->input_roman,
2499                      makeFontName(rc.roman_font_name,
2500                                   rc.roman_font_foundry).c_str());
2501         fl_set_input(dialog_->input_sans,
2502                      makeFontName(rc.sans_font_name,
2503                                   rc.sans_font_foundry).c_str());
2504         fl_set_input(dialog_->input_typewriter,
2505                      makeFontName(rc.typewriter_font_name,
2506                                   rc.typewriter_font_foundry).c_str());
2507         fl_set_input(dialog_->input_screen_encoding,
2508                      rc.font_norm.c_str());
2509         fl_set_button(dialog_->check_scalable,
2510                       rc.use_scalable_fonts);
2511         fl_set_counter_value(dialog_->counter_zoom, rc.zoom);
2512         fl_set_counter_value(dialog_->counter_dpi,  rc.dpi);
2513         fl_set_input(dialog_->input_tiny,
2514                      tostr(rc.font_sizes[LyXFont::SIZE_TINY]).c_str());
2515         fl_set_input(dialog_->input_script,
2516                      tostr(rc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
2517         fl_set_input(dialog_->input_footnote,
2518                      tostr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
2519         fl_set_input(dialog_->input_small,
2520                      tostr(rc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
2521         fl_set_input(dialog_->input_normal,
2522                      tostr(rc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
2523         fl_set_input(dialog_->input_large,
2524                      tostr(rc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
2525         fl_set_input(dialog_->input_larger,
2526                      tostr(rc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
2527         fl_set_input(dialog_->input_largest,
2528                      tostr(rc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
2529         fl_set_input(dialog_->input_huge,
2530                      tostr(rc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
2531         fl_set_input(dialog_->input_huger,
2532                      tostr(rc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
2533 }
2534
2535
2536
2537 FormPreferences::SpellOptions::SpellOptions(FormPreferences &  p)
2538         : parent_(p)
2539 {}
2540
2541
2542 FD_preferences_spelloptions const * FormPreferences::SpellOptions::dialog()
2543 {
2544         return dialog_.get();
2545 }
2546
2547
2548 void FormPreferences::SpellOptions::apply(LyXRC & rc)
2549 {
2550         string choice = fl_get_choice_text(dialog_->choice_spell_command);
2551         choice = trim(choice);
2552
2553         rc.isp_command = choice;
2554
2555 #if 0
2556         // If spell checker == "none", all other input set to off.
2557         if (fl_get_choice(dialog_->choice_spell_command) == 1) {
2558                 rc.isp_use_alt_lang = false;
2559                 rc.isp_alt_lang.erase();
2560
2561                 rc.isp_use_esc_chars = false;
2562                 rc.isp_esc_chars.erase();
2563
2564                 rc.isp_use_pers_dict = false;
2565                 rc.isp_pers_dict.erase();
2566
2567                 rc.isp_accept_compound = false;
2568                 rc.isp_use_input_encoding = false;
2569         } else {
2570 #else
2571                 int button = fl_get_button(dialog_->check_alt_lang);
2572                 choice = fl_get_input(dialog_->input_alt_lang);
2573                 if (button && choice.empty()) button = 0;
2574                 if (!button) choice.erase();
2575
2576                 rc.isp_use_alt_lang = static_cast<bool>(button);
2577                 rc.isp_alt_lang = choice;
2578
2579                 button = fl_get_button(dialog_->check_escape_chars);
2580                 choice = fl_get_input(dialog_->input_escape_chars);
2581                 if (button && choice.empty()) button = 0;
2582                 if (!button) choice.erase();
2583
2584                 rc.isp_use_esc_chars = static_cast<bool>(button);
2585                 rc.isp_esc_chars = choice;
2586
2587                 button = fl_get_button(dialog_->check_personal_dict);
2588                 choice = fl_get_input(dialog_->input_personal_dict);
2589                 if (button && choice.empty()) button = 0;
2590                 if (!button) choice.erase();
2591
2592                 rc.isp_use_pers_dict = static_cast<bool>(button);
2593                 rc.isp_pers_dict = choice;
2594
2595                 button = fl_get_button(dialog_->check_compound_words);
2596                 rc.isp_accept_compound = static_cast<bool>(button);
2597
2598                 button = fl_get_button(dialog_->check_input_enc);
2599                 rc.isp_use_input_encoding = static_cast<bool>(button);
2600 #endif
2601 #if 0
2602         }
2603 #endif
2604
2605         // Reset view
2606         update(rc);
2607 }
2608
2609
2610 void FormPreferences::SpellOptions::build()
2611 {
2612         dialog_.reset(build_preferences_spelloptions(&parent_));
2613
2614         fl_addto_choice(dialog_->choice_spell_command,
2615                         _(" ispell | aspell ").c_str());
2616         fl_set_input_return(dialog_->input_alt_lang,      FL_RETURN_CHANGED);
2617         fl_set_input_return(dialog_->input_escape_chars,  FL_RETURN_CHANGED);
2618         fl_set_input_return(dialog_->input_personal_dict, FL_RETURN_CHANGED);
2619
2620         // set up the feedback mechanism
2621         setPrehandler(dialog_->choice_spell_command);
2622         setPrehandler(dialog_->check_alt_lang);
2623         setPrehandler(dialog_->input_alt_lang);
2624         setPrehandler(dialog_->check_escape_chars);
2625         setPrehandler(dialog_->input_escape_chars);
2626         setPrehandler(dialog_->check_personal_dict);
2627         setPrehandler(dialog_->input_personal_dict);
2628         setPrehandler(dialog_->button_personal_dict);
2629         setPrehandler(dialog_->check_compound_words);
2630         setPrehandler(dialog_->check_input_enc);
2631 }
2632
2633
2634 string const
2635 FormPreferences::SpellOptions::feedback(FL_OBJECT const * const ob) const
2636 {
2637         if (ob == dialog_->choice_spell_command)
2638                 return LyXRC::getDescription(LyXRC::RC_SPELL_COMMAND);
2639         if (ob == dialog_->check_alt_lang)
2640                 return LyXRC::getDescription(LyXRC::RC_USE_ALT_LANG);
2641         if (ob == dialog_->input_alt_lang)
2642                 return LyXRC::getDescription(LyXRC::RC_ALT_LANG);
2643         if (ob == dialog_->check_escape_chars)
2644                 return LyXRC::getDescription(LyXRC::RC_USE_ESC_CHARS);
2645         if (ob == dialog_->input_escape_chars)
2646                 return LyXRC::getDescription(LyXRC::RC_ESC_CHARS);
2647         if (ob == dialog_->check_personal_dict)
2648                 return LyXRC::getDescription(LyXRC::RC_USE_PERS_DICT);
2649         if (ob == dialog_->input_personal_dict)
2650                 return LyXRC::getDescription(LyXRC::RC_PERS_DICT);
2651         if (ob == dialog_->check_compound_words)
2652                 return LyXRC::getDescription(LyXRC::RC_ACCEPT_COMPOUND);
2653         if (ob == dialog_->check_input_enc)
2654                 return LyXRC::getDescription(LyXRC::RC_USE_INP_ENC);
2655         return string();
2656 }
2657
2658
2659 bool FormPreferences::SpellOptions::input(FL_OBJECT const * const ob)
2660 {
2661         // !ob if function is called from updateSpellOptions() to de/activate
2662         // objects,
2663         // otherwise the function is called by an xforms CB via input().
2664
2665 #if 0
2666         // If spell checker == "none", disable all input.
2667         if (!ob || ob == dialog_->choice_spell_command) {
2668                 if (fl_get_choice(dialog_->choice_spell_command) == 1) {
2669                         fl_deactivate_object(dialog_->check_alt_lang);
2670                         fl_deactivate_object(dialog_->input_alt_lang);
2671                         fl_deactivate_object(dialog_->check_escape_chars);
2672                         fl_deactivate_object(dialog_->input_escape_chars);
2673                         fl_deactivate_object(dialog_->check_personal_dict);
2674                         fl_deactivate_object(dialog_->input_personal_dict);
2675                         fl_deactivate_object(dialog_->check_compound_words);
2676                         fl_deactivate_object(dialog_->check_input_enc);
2677                         return true;
2678                 } else {
2679                         fl_activate_object(dialog_->check_alt_lang);
2680                         fl_activate_object(dialog_->check_escape_chars);
2681                         fl_activate_object(dialog_->check_personal_dict);
2682                         fl_activate_object(dialog_->check_compound_words);
2683                         fl_activate_object(dialog_->check_input_enc);
2684                 }
2685         }
2686 #endif
2687
2688         if (!ob || ob == dialog_->check_alt_lang) {
2689                 bool const enable = fl_get_button(dialog_->check_alt_lang);
2690                 setEnabled(dialog_->input_alt_lang, enable);
2691         }
2692
2693         if (!ob || ob == dialog_->check_escape_chars) {
2694                 bool const enable = fl_get_button(dialog_->check_escape_chars);
2695                 setEnabled(dialog_->input_escape_chars, enable);
2696         }
2697
2698         if (!ob || ob == dialog_->check_personal_dict) {
2699                 bool const enable = fl_get_button(dialog_->check_personal_dict);
2700                 setEnabled(dialog_->input_personal_dict, enable);
2701         }
2702
2703         if (ob == dialog_->button_personal_dict) {
2704                 string f = parent_.controller().browsedict(
2705                         fl_get_input(dialog_->input_personal_dict));
2706                 fl_set_input(dialog_->input_personal_dict, f.c_str());
2707         }
2708
2709         return true; // All input is valid!
2710 }
2711
2712
2713 void FormPreferences::SpellOptions::update(LyXRC const & rc)
2714 {
2715         int choice = 1;
2716 #if 0
2717         if (rc.isp_command == "none")
2718                 choice = 1;
2719         else if (rc.isp_command == "ispell")
2720                 choice = 2;
2721         else if (rc.isp_command == "aspell")
2722                 choice = 3;
2723 #else
2724         if (rc.isp_command == "ispell")
2725                 choice = 1;
2726         else if (rc.isp_command == "aspell")
2727                 choice = 2;
2728 #endif
2729         fl_set_choice(dialog_->choice_spell_command, choice);
2730
2731         string str;
2732         if (rc.isp_use_alt_lang)
2733                 str = rc.isp_alt_lang;
2734
2735         fl_set_button(dialog_->check_alt_lang,
2736                       rc.isp_use_alt_lang);
2737         fl_set_input(dialog_->input_alt_lang, str.c_str());
2738
2739         str.erase();
2740         if (rc.isp_use_esc_chars)
2741                 str = rc.isp_esc_chars;
2742
2743         fl_set_button(dialog_->check_escape_chars,
2744                       rc.isp_use_esc_chars);
2745         fl_set_input(dialog_->input_escape_chars, str.c_str());
2746
2747         str.erase();
2748         if (rc.isp_use_pers_dict)
2749                 str = rc.isp_pers_dict;
2750
2751         fl_set_button(dialog_->check_personal_dict,
2752                       rc.isp_use_pers_dict);
2753         fl_set_input(dialog_->input_personal_dict, str.c_str());
2754
2755         fl_set_button(dialog_->check_compound_words,
2756                       rc.isp_accept_compound);
2757         fl_set_button(dialog_->check_input_enc,
2758                       rc.isp_use_input_encoding);
2759
2760         // Activate/Deactivate the input fields dependent on the state of the
2761         // buttons.
2762         input(0);
2763 }