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