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