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