]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormPreferences.C
84abfb05959e59287019a53b953463ad725793dd
[features.git] / src / frontends / xforms / FormPreferences.C
1 /* FormPreferences.C
2  * FormPreferences Interface Class Implementation
3  */
4
5 #include <utility>
6 #include <config.h>
7
8 #include FORMS_H_LOCATION
9
10 #ifdef __GNUG_
11 #pragma implementation
12 #endif
13
14 #include "Lsstream.h"
15 #include "FormPreferences.h"
16 #include "form_preferences.h"
17 #include "input_validators.h"
18 #include "LyXView.h"
19 #include "language.h"
20 #include "lyxfunc.h"
21 #include "Dialogs.h"
22 #include "lyxrc.h"
23 #include "combox.h"
24 #include "debug.h"
25 #include "support/FileInfo.h"
26 #include "support/filetools.h"
27 #include "lyx_gui_misc.h"
28 #include "lyxlex.h"
29 #include "input_validators.h"
30 #include "xform_helpers.h" // formatted()
31 #include "xform_macros.h"
32 #include "converter.h"
33 #include "support/lyxfunctional.h"
34
35
36 #ifdef SIGC_CXX_NAMESPACES
37 using SigC::slot;
38 #endif
39
40 using std::find;
41 using std::find_if;
42 using std::pair;
43 using std::sort;
44 using std::vector;
45
46 extern string fmt(char const * fmtstr ...);
47 extern string system_lyxdir;
48 extern Languages languages;
49
50 static string const colorFile("/usr/lib/X11/rgb.txt");
51 vector<X11Color> FormPreferences::colorDB;
52 vector<XFormColor> FormPreferences::xformColorDB;
53 pair<vector<string>, vector<string> > FormPreferences::dirlist;
54
55 // Two functions used to help sort a vector<Command> and a vector<Format>.
56 // Only used in this file, so no need to declare them globally.
57 bool CommandsCompare( Command const & a, Command const & b )
58 {
59         if( a.from->prettyname == b.from->prettyname )
60                 return( a.to->prettyname < b.to->prettyname );
61         else
62                 return( a.from->prettyname < b.from->prettyname );
63 }
64
65
66 bool FormatsCompare( Format const & a, Format const & b )
67 {
68         return( a.name < b.name );
69 }
70
71
72 FormPreferences::FormPreferences(LyXView * lv, Dialogs * d)
73         : FormBaseBI(lv, d, _("Preferences"), new PreferencesPolicy),
74           dialog_(0),
75           converters_tab_(0), inputs_tab_(0), look_n_feel_tab_(0),
76           outputs_tab_(0),  usage_tab_(0),
77           colors_(0), converters_(0), formats_(0), inputs_misc_(0),
78           interface_(0), language_(0), lnf_misc_(0), outputs_misc_(0),
79           paths_(0), printer_(0), screen_fonts_(0), spellchecker_(0),
80           combo_default_lang(0), combo_kbmap_1(0), combo_kbmap_2(0),
81           warningPosted(false)
82 {
83         // let the dialog be shown
84         // This is a permanent connection so we won't bother
85         // storing a copy because we won't be disconnecting.
86         d->showPreferences.connect(slot(this, &FormPreferences::show));
87 }
88
89
90 FormPreferences::~FormPreferences()
91 {
92         delete combo_default_lang;
93         delete combo_kbmap_1;
94         delete combo_kbmap_2;
95
96         delete colors_;
97         delete converters_;
98         delete formats_;
99         delete inputs_misc_;
100         delete interface_;
101         delete language_;
102         delete lnf_misc_;
103         delete outputs_misc_;
104         delete paths_;
105         delete printer_;
106         delete screen_fonts_;
107         delete spellchecker_;
108
109         delete converters_tab_;
110         delete inputs_tab_;
111         delete look_n_feel_tab_;
112         delete outputs_tab_;
113         delete usage_tab_;
114
115         delete dialog_;
116 }
117
118
119 void FormPreferences::redraw()
120 {
121         if( form() && form()->visible )
122                 fl_redraw_form( form() );
123         else
124                 return;
125
126         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabfolder_prefs);
127         if (outer_form && outer_form->visible)
128                 fl_redraw_form( outer_form );
129         else
130                 return;
131
132         if( outer_form == converters_tab_->form )
133                 outer_form =
134                         fl_get_active_folder(converters_tab_->tabfolder_outer);
135
136         else if( outer_form == look_n_feel_tab_->form )
137                 outer_form =
138                         fl_get_active_folder(look_n_feel_tab_->tabfolder_outer);
139
140         else if( outer_form == inputs_tab_->form )
141                 outer_form = fl_get_active_folder(inputs_tab_->tabfolder_outer);
142
143         else if( outer_form == outputs_tab_->form )
144                 outer_form = 
145                         fl_get_active_folder(outputs_tab_->tabfolder_outer);
146
147         else if( outer_form == usage_tab_->form )
148                 outer_form = fl_get_active_folder(usage_tab_->tabfolder_outer);
149
150         if (outer_form && outer_form->visible)
151                 fl_redraw_form( outer_form );
152 }
153
154
155 FL_FORM * FormPreferences::form() const
156 {
157         if (dialog_) return dialog_->form;
158         return 0;
159 }
160
161
162 void FormPreferences::ok()
163 {
164         FormBase::ok();
165         lv_->getLyXFunc()->Dispatch(LFUN_SAVEPREFERENCES);
166 }
167
168
169 void FormPreferences::hide()
170 {
171         // We need to hide the active tabfolder otherwise we get a
172         // BadDrawable error from X windows and LyX crashes without saving.
173         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabfolder_prefs);
174         if (outer_form
175             && outer_form->visible) {
176                 fl_hide_form(outer_form);
177         }
178         FormBase::hide();
179 }
180
181
182 void FormPreferences::build()
183 {
184         dialog_ = build_preferences();
185
186         // manage the restore, save, apply and cancel/close buttons
187         bc_.setOK(dialog_->button_ok);
188         bc_.setApply(dialog_->button_apply);
189         bc_.setCancel(dialog_->button_cancel);
190         bc_.setUndoAll(dialog_->button_restore);
191         bc_.refresh();
192
193         // Workaround dumb xforms sizing bug
194         minw_ = form()->w;
195         minh_ = form()->h;
196
197         // build the tab folders
198         converters_tab_ = build_outer_tab();
199         look_n_feel_tab_ = build_outer_tab();
200         inputs_tab_ = build_outer_tab();
201         outputs_tab_ = build_outer_tab();
202         usage_tab_ = build_outer_tab();
203
204         // build actual tabfolder contents
205         // these will become nested tabfolders
206         buildColors();
207         buildConverters();
208         buildFormats();
209         buildInputsMisc();
210         buildInterface();
211         buildLanguage();
212         buildLnFmisc();
213         buildOutputsMisc();
214         buildPaths();
215         buildPrinter();
216         buildScreenFonts();
217         buildSpellchecker();
218
219         // Now add them to the tabfolder
220         fl_addto_tabfolder(dialog_->tabfolder_prefs,
221                            _("Look and Feel"),
222                            look_n_feel_tab_->form);
223         fl_addto_tabfolder(dialog_->tabfolder_prefs,
224                            _("Usage"),
225                            usage_tab_->form);
226         fl_addto_tabfolder(dialog_->tabfolder_prefs,
227                            _("Converters"),
228                            converters_tab_->form);
229         fl_addto_tabfolder(dialog_->tabfolder_prefs,
230                            _("Inputs"),
231                            inputs_tab_->form);
232         fl_addto_tabfolder(dialog_->tabfolder_prefs,
233                            _("Outputs"),
234                            outputs_tab_->form);
235
236         // now build the nested tabfolders
237         // Starting with look and feel
238         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
239                            _("Screen Fonts"),
240                            screen_fonts_->form);
241         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
242                            _("Interface"),
243                            interface_->form);
244         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
245                            _("Colors"),
246                            colors_->form);
247         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
248                            _("Misc"),
249                            lnf_misc_->form);
250
251         // then build converters
252         fl_addto_tabfolder(converters_tab_->tabfolder_outer,
253                            _("Formats"),
254                            formats_->form);
255         fl_addto_tabfolder(converters_tab_->tabfolder_outer,
256                            _("Converters"),
257                            converters_->form);
258
259         // then build inputs
260         // Paths should probably go in a few outer_tab called Files
261         fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
262                            _("Paths"),
263                            paths_->form);
264         fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
265                            _("Misc"),
266                            inputs_misc_->form);
267
268         // then building outputs
269         fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
270                            _("Printer"),
271                            printer_->form);
272         fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
273                            _("Misc"),
274                            outputs_misc_->form);
275
276         // then building usage
277         fl_addto_tabfolder(usage_tab_->tabfolder_outer,
278                            _("Spell checker"),
279                            spellchecker_->form);
280         fl_addto_tabfolder(usage_tab_->tabfolder_outer,
281                            _("Language"),
282                            language_->form);
283 }
284
285
286 void FormPreferences::apply()
287 {
288         // set the new lyxrc entries
289         // many of these need to trigger other functions when the assignment
290         // is made.  For example, screen zoom and font types.  These could be
291         // handled either by signals/slots in lyxrc or just directly call the
292         // associated functions here.
293         // There are other problems with this scheme.  We really should check
294         // what we copy to make sure that it really is necessary to do things
295         // like update the screen fonts because that flushes the textcache
296         // and other stuff which may cost us a lot on slower/high-load machines.
297
298         applyColors();
299         applyConverters();
300         applyFormats();
301         applyInputsMisc();
302         applyInterface();
303         applyLanguage();
304         applyLnFmisc();
305         applyOutputsMisc();
306         applyPaths();
307         applyPrinter();
308         applyScreenFonts();
309         applySpellChecker();
310 }
311
312
313 void FormPreferences::feedback( FL_OBJECT * ob )
314 {
315         Assert(ob);
316
317         string str;
318
319         if (ob->form->fdui == colors_) {
320                 str = feedbackColors( ob );
321         } else if (ob->form->fdui == converters_) {
322                 str = feedbackConverters( ob );
323         } else if (ob->form->fdui == formats_) {
324                 str = feedbackFormats( ob );
325         } else if (ob->form->fdui == inputs_misc_) {
326                 str = feedbackInputsMisc( ob );
327         } else if (ob->form->fdui == interface_) {
328                 str = feedbackInterface( ob );
329         } else if (ob->form->fdui == language_) {
330                 str = feedbackLanguage( ob );
331         } else if (ob->form->fdui == lnf_misc_) {
332                 str = feedbackLnFmisc( ob );
333         } else if (ob->form->fdui == outputs_misc_) {
334                 str = feedbackOutputsMisc( ob );
335         } else if (ob->form->fdui == paths_) {
336                 str = feedbackPaths( ob );
337         } else if (ob->form->fdui == printer_) {
338                 str = feedbackPrinter( ob );
339         } else if (ob->form->fdui == screen_fonts_) {
340                 str = feedbackScreenFonts( ob );
341         } else if (ob->form->fdui == spellchecker_) {
342                 str = feedbackSpellChecker( ob );
343         }
344
345         str = formatted( str, dialog_->text_warning->w-10,
346                          FL_SMALL_SIZE, FL_NORMAL_STYLE );
347
348         fl_set_object_label(dialog_->text_warning, str.c_str());
349         fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
350 }
351
352
353 bool FormPreferences::input(FL_OBJECT * ob, long)
354 {
355         Assert(ob);
356         
357         // whatever checks you need to ensure the user hasn't entered
358         // some totally ridiculous value somewhere.  Change activate to suit.
359         // comments before each test describe what is _valid_
360
361         if (ob->form->fdui == colors_)
362                 return inputColors(ob);
363         else if (ob->form->fdui == converters_)
364                 return inputConverters(ob);
365         else if (ob->form->fdui == language_)
366                 return inputLanguage(ob);
367         else if (ob->form->fdui == paths_)
368                 return inputPaths(ob);
369         else if (ob->form->fdui == screen_fonts_)
370                 return inputScreenFonts();
371         else if (ob->form->fdui == spellchecker_)
372                 return inputSpellChecker(ob);
373         else if (ob->form->fdui == formats_)
374                 return inputFormats(ob);
375
376         return true;
377 }
378
379
380 void FormPreferences::update()
381 {
382         if (!dialog_) return;
383     
384         // read lyxrc entries
385         updateColors();
386         updateConverters();
387         updateFormats();
388         updateInputsMisc();
389         updateInterface();
390         updateLanguage();
391         updateLnFmisc();
392         updateOutputsMisc();
393         updatePaths();
394         updatePrinter();
395         updateScreenFonts();
396         updateSpellChecker();
397 }
398
399
400 void FormPreferences::applyColors() const
401 {
402         bool modifiedXForms = false;
403         bool modifiedText = false;
404         bool modifiedBackground = false;
405
406         for( vector<XFormColor>::const_iterator cit = xformColorDB.begin();
407              cit != xformColorDB.end(); ++cit ) {
408                 RGB col;
409                 fl_getmcolor((*cit).colorID, &col.r, &col.g, &col.b);
410                 if( col != (*cit).col ) {
411                         modifiedXForms = true;
412                         if( (*cit).colorID == FL_BLACK )
413                                 modifiedText = true;
414                         if( (*cit).colorID == FL_COL1 )
415                                 modifiedBackground = true;
416                 }
417         }
418
419         if( modifiedXForms ) {
420                 vector<XFormColor>::const_iterator cit;
421                 for( cit = xformColorDB.begin(); 
422                      cit != xformColorDB.end(); ++cit ) {
423                         fl_mapcolor((*cit).colorID,
424                                     (*cit).col.r, (*cit).col.g, (*cit).col.b);
425
426                         if( modifiedText && (*cit).colorID == FL_BLACK ) {
427                                 ColorsAdjustVal( FL_INACTIVE, FL_BLACK, 0.5 );
428                         }
429
430                         if( modifiedBackground && (*cit).colorID == FL_COL1 ) {
431                                 ColorsAdjustVal( FL_MCOL,      FL_COL1, 0.1 );
432                                 ColorsAdjustVal( FL_TOP_BCOL,  FL_COL1, 0.1 );
433                                 ColorsAdjustVal( FL_LEFT_BCOL, FL_COL1, 0.1 );
434
435                                 ColorsAdjustVal( FL_RIGHT_BCOL,  FL_COL1, -0.5);
436                                 ColorsAdjustVal( FL_BOTTOM_BCOL, FL_COL1, -0.5);
437                         }               
438                 }
439                 Dialogs::redrawGUI();
440         }
441 }
442
443
444 void FormPreferences::buildColors()
445 {
446         colors_ = build_colors();
447
448         FL_OBJECT * obj = colors_->valslider_red;
449         fl_set_slider_bounds(obj, 0, 255);
450         fl_set_slider_precision(obj, 0);
451         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
452         
453         obj = colors_->valslider_green;
454         fl_set_slider_bounds(obj, 0, 255);
455         fl_set_slider_precision(obj, 0);
456         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
457         
458         obj = colors_->valslider_blue;
459         fl_set_slider_bounds(obj, 0, 255);
460         fl_set_slider_precision(obj, 0);
461         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
462
463         fl_set_object_color(colors_->button_color,
464                             FL_FREE_COL4, FL_FREE_COL4);
465         
466         fl_set_input_return(colors_->input_name, FL_RETURN_END_CHANGED);
467
468         if (ColorsLoadBrowserX11(colorFile) )
469                 fl_set_input(colors_->input_name, colorFile.c_str());
470         else
471                 fl_set_input(colors_->input_name, N_("No file found"));
472
473         ColorsLoadBrowserLyX();
474
475         // deactivate the browse button because it isn't implemented
476         fl_deactivate_object(colors_->button_browse);
477         fl_set_object_lcol(colors_->button_browse, FL_INACTIVE);
478
479         // set up the feedback mechanism
480         setPreHandler( colors_->browser_x11 );
481         setPreHandler( colors_->input_name );
482         setPreHandler( colors_->button_browse );
483         setPreHandler( colors_->button_color );
484         setPreHandler( colors_->valslider_red );
485         setPreHandler( colors_->valslider_green );
486         setPreHandler( colors_->valslider_blue );
487         setPreHandler( colors_->browser_lyx_objs );
488         setPreHandler( colors_->button_modify );
489 }
490
491
492 string const
493 FormPreferences::feedbackColors(FL_OBJECT const * const ob) const
494 {
495         string str;
496
497         if (ob == colors_->browser_x11 ) {
498                 str = N_("The colors listed in the X11 database.");
499         } else if (ob == colors_->browser_lyx_objs ) {
500                 str = N_("LyX objects that can be assigned a color.");
501         } else if (ob == colors_->input_name ) {
502                 str = N_("The file containing the X11 color database.");
503         } else if (ob == colors_->button_color ) {
504                 str = N_("You will only be able to modify the LyX object if the sliders and X11 browser agree. Force this by clicking on the highlighted browser name.");
505         } else if (ob == colors_->valslider_red
506                    || ob == colors_->valslider_green
507                    || ob == colors_->valslider_blue ) {
508                 str = N_("Find a new color. The name highlighted in the X11 database is the closest match to this.");
509         } else if (ob == colors_->button_modify ) {
510                 str = N_("Modify the color of the LyX object.");
511         }
512
513         return str;
514 }
515
516
517 bool FormPreferences::inputColors( FL_OBJECT const * const ob )
518 {
519         if (ob == colors_->browser_x11) {
520                 return ColorsBrowserX11();
521
522         } else if (ob == colors_->valslider_red
523                    || ob == colors_->valslider_green
524                    || ob == colors_->valslider_blue) {
525                 return ColorsRGB();
526
527         } else if (ob == colors_->input_name) {
528                 return ColorsDatabase();
529
530         } else if (ob == colors_->browser_lyx_objs) {
531                 return ColorsBrowserLyX();
532                 
533         } else if (ob == colors_->button_modify) {
534                 return ColorsModify();
535         }
536         
537         return true;
538 }
539
540
541 void FormPreferences::ColorsAdjustVal( int colAdjust, int colParent,
542                                        double addVal ) const
543 {
544         RGB rgb;
545         fl_getmcolor( colParent, &rgb.r, &rgb.g, &rgb.b);
546
547         HSV hsv = HSV( rgb );
548         hsv.v += addVal;
549         if( hsv.v > 1.0 )
550                 hsv.v = 1.0;
551         else if( hsv.v < 0.0 )
552                 hsv.v = 0.0;
553
554         rgb = RGB( hsv );
555         fl_mapcolor( colAdjust, rgb.r, rgb.g, rgb.b );
556 }
557
558
559 bool FormPreferences::ColorsBrowserLyX() const
560 {
561         int i = fl_get_browser( colors_->browser_lyx_objs );
562         if (i < 1)
563                 return true;
564
565         string name = fl_get_browser_line( colors_->browser_lyx_objs, i );
566
567         vector<XFormColor>::const_iterator cit =
568                 find_if(xformColorDB.begin(), xformColorDB.end(),
569                         compare_memfun(&XFormColor::getname, name));
570
571         if( cit != xformColorDB.end() ) {
572                 fl_freeze_form( colors_->form );
573
574                 fl_set_slider_value( colors_->valslider_red,   (*cit).col.r );
575                 fl_set_slider_value( colors_->valslider_green, (*cit).col.g );
576                 fl_set_slider_value( colors_->valslider_blue,  (*cit).col.b );
577                 ColorsRGB();
578
579                 fl_unfreeze_form( colors_->form );
580         }
581
582         fl_deactivate_object( colors_->button_modify );
583         fl_set_object_lcol( colors_->button_modify, FL_INACTIVE );
584
585         return true;
586 }
587
588
589 bool FormPreferences::ColorsBrowserX11() const
590 {
591         int i = fl_get_browser(colors_->browser_x11);
592         if (i < 1)
593                 return true;
594
595         fl_freeze_form( colors_->form );
596
597         RGB col = colorDB[i-1].second;
598     
599         fl_mapcolor( FL_FREE_COL4 + i, col.r, col.g, col.b );
600         fl_mapcolor( FL_FREE_COL4, col.r, col.g, col.b );
601         fl_set_slider_value( colors_->valslider_red,   col.r );
602         fl_set_slider_value( colors_->valslider_green, col.g );
603         fl_set_slider_value( colors_->valslider_blue,  col.b );
604         fl_redraw_object( colors_->button_color );
605
606         // Is it valid to activate the "Modify" button?
607         int line = fl_get_browser(colors_->browser_lyx_objs);
608         bool isSelected = ( line > 0 );
609         if( isSelected )
610                 if( line > fl_get_browser_maxline(colors_->browser_lyx_objs) )
611                         isSelected = false;     
612
613         if( isSelected && colorDB[i-1].second == col ) {
614                 fl_activate_object( colors_->button_modify );
615                 fl_set_object_lcol( colors_->button_modify, FL_BLACK );
616         }
617         
618         fl_unfreeze_form( colors_->form );
619
620         return true;
621 }
622
623
624 bool FormPreferences::ColorsDatabase() const
625 {
626         string file = fl_get_input(colors_->input_name);
627         if (ColorsLoadBrowserX11(file) )
628                 fl_set_input(colors_->input_name, file.c_str());
629         else if (ColorsLoadBrowserX11(colorFile) )
630                 fl_set_input(colors_->input_name, colorFile.c_str());
631         else
632                 fl_set_input(colors_->input_name, N_("No file found"));
633         return true;
634 }
635
636
637 void FormPreferences::ColorsLoadBrowserLyX()
638 {
639         XFormColor xcol;
640
641         xcol.name = "GUI background";
642         xcol.colorID = FL_COL1;
643         fl_getmcolor(FL_COL1, &xcol.col.r, &xcol.col.g, &xcol.col.b);
644
645         xformColorDB.push_back( xcol );
646
647         xcol.name = "GUI text";
648         xcol.colorID = FL_BLACK;
649         fl_getmcolor(FL_BLACK, &xcol.col.r, &xcol.col.g, &xcol.col.b);
650
651         xformColorDB.push_back( xcol );
652
653         xcol.name = "GUI active tab";
654         xcol.colorID = FL_LIGHTER_COL1;
655         fl_getmcolor(FL_LIGHTER_COL1, &xcol.col.r, &xcol.col.g, &xcol.col.b);
656
657         xformColorDB.push_back( xcol );
658
659         xcol.name = "GUI push button";
660         xcol.colorID = FL_YELLOW;
661         fl_getmcolor(FL_YELLOW, &xcol.col.r, &xcol.col.g, &xcol.col.b);
662
663         xformColorDB.push_back( xcol );
664
665         FL_OBJECT * colbr = colors_->browser_lyx_objs;
666         fl_clear_browser( colbr );
667         for( vector<XFormColor>::const_iterator cit = xformColorDB.begin();
668              cit != xformColorDB.end(); ++cit ) {
669                 fl_addto_browser(colbr, (*cit).name.c_str() );
670         }
671
672         fl_deselect_browser(colors_->browser_lyx_objs);
673         fl_deactivate_object( colors_->button_modify );
674         fl_set_object_lcol( colors_->button_modify, FL_INACTIVE );
675 }
676
677
678 bool FormPreferences::ColorsLoadBrowserX11(string const & filename) const
679 {
680         LyXLex lex(0, 0);
681         lex.setCommentChar('!');
682         
683         if (!lex.setFile(filename))
684                 return true;
685
686         vector<RGB> cols;
687         vector<string> names;
688         
689         while (lex.next()) {
690                 RGB col;
691                 col.r = lex.GetInteger();
692                 lex.next();
693                 col.g = lex.GetInteger();
694                 lex.next();
695                 col.b = lex.GetInteger();
696                 lex.EatLine();
697                 string name = frontStrip(lex.GetString(), " \t");
698
699                 // remove redundant entries on the fly
700                 bool add = cols.empty();
701                 if (!add) {
702                         vector<RGB>::const_iterator cit = 
703                                 find( cols.begin(), cols.end(), col );
704                         add = (cit == cols.end());
705                 }
706                 
707                 if (add) {
708                         if( col == RGB(0,0,0) )
709                                 name = "black";
710                         else if( col == RGB(255,255,255) )
711                                 name = "white";
712                         else
713                                 name = lowercase( name );
714
715                         if ( col == RGB(0,0,0) || col == RGB(255,255,255) ) {
716                                 cols.insert(cols.begin(), col);
717                                 names.insert(names.begin(), name);
718                         } else {
719                                 cols.push_back(col);
720                                 names.push_back(name);
721                         }
722                 }
723         }
724         
725         FL_OBJECT * colbr = colors_->browser_x11;
726         fl_freeze_form(colors_->form);
727         fl_clear_browser( colbr );
728
729         vector<string>::const_iterator sit = names.begin();
730         for (vector<RGB>::const_iterator iit = cols.begin();
731              iit != cols.end(); ++iit, ++sit) {
732                 colorDB.push_back( X11Color(*sit, *iit) );
733                 fl_addto_browser(colbr, (*sit).c_str());
734         }
735         
736         fl_set_browser_topline(colbr, 1);
737         fl_select_browser_line(colbr, 1);
738         ColorsBrowserX11();
739         fl_unfreeze_form(colors_->form);
740         
741         return true;
742 }
743
744
745 bool FormPreferences::ColorsModify() const
746 {
747         int i = fl_get_browser( colors_->browser_lyx_objs );
748         if (i < 1)
749                 return true;
750
751         string name = fl_get_browser_line( colors_->browser_lyx_objs, i );
752
753         vector<XFormColor>::iterator it = // non-const; it's modified below
754                 find_if(xformColorDB.begin(), xformColorDB.end(),
755                         compare_memfun(&XFormColor::getname, name));
756
757         if( it == xformColorDB.end() )
758                 return true;
759
760         int j = fl_get_browser( colors_->browser_x11 );
761         if (j < 1)
762                 return true;
763
764         (*it).col.r = colorDB[j-1].second.r;
765         (*it).col.g = colorDB[j-1].second.g;
766         (*it).col.b = colorDB[j-1].second.b;
767
768         fl_deselect_browser(colors_->browser_x11);
769         fl_deselect_browser(colors_->browser_lyx_objs);
770         fl_deactivate_object( colors_->button_modify );
771         fl_set_object_lcol( colors_->button_modify, FL_INACTIVE );
772
773         return true;
774 }
775
776 bool FormPreferences::ColorsRGB() const
777 {
778         fl_freeze_form(colors_->form);
779
780         RGB col;
781         col.r = int(fl_get_slider_value(colors_->valslider_red));
782         col.g = int(fl_get_slider_value(colors_->valslider_green));
783         col.b = int(fl_get_slider_value(colors_->valslider_blue));
784     
785         fl_mapcolor(FL_FREE_COL4, col.r, col.g, col.b);
786         fl_redraw_object(colors_->button_color);
787
788         int const i = ColorsSearchEntry( col );
789         // change topline only if necessary
790         // int top = fl_get_browser_topline(colors_->browser_x11);
791         // if (i < top || i > (top+15))
792         fl_set_browser_topline(colors_->browser_x11, i - 5);
793         fl_select_browser_line(colors_->browser_x11, i + 1);
794
795         // Only activate the "Modify" button if the browser and slider colors
796         // are the same AND if a LyX object is selected.
797         int line = fl_get_browser(colors_->browser_lyx_objs);
798         bool isSelected = ( line > 0 );
799         if( isSelected )
800                 if( line > fl_get_browser_maxline(colors_->browser_lyx_objs) )
801                         isSelected = false;     
802
803         if( isSelected && colorDB[i].second == col ) {
804                 fl_activate_object( colors_->button_modify );
805                 fl_set_object_lcol( colors_->button_modify, FL_BLACK );
806         } else {
807                 fl_deactivate_object( colors_->button_modify );
808                 fl_set_object_lcol( colors_->button_modify, FL_INACTIVE );
809         }
810
811         fl_unfreeze_form(colors_->form);
812
813         return true;
814 }
815
816
817 int FormPreferences::ColorsSearchEntry(RGB const & col) const
818 {
819         int mindiff = 0x7fffffff;
820         vector<X11Color>::const_iterator mincit = colorDB.begin();
821
822         for (vector<X11Color>::const_iterator cit = colorDB.begin();
823              cit != colorDB.end(); ++cit) {
824                 RGB colDB = (*cit).second;
825                 RGB diff;
826                 diff.r = col.r - colDB.r;
827                 diff.g = col.g - colDB.g;
828                 diff.b = col.b - colDB.b;
829
830                 int d = (2 * (diff.r * diff.r) +
831                          3 * (diff.g * diff.g) +
832                              (diff.b * diff.b));
833
834                 if (mindiff > d) {
835                         mindiff = d;
836                         mincit = cit;
837                 }
838         }
839         return static_cast<int>(mincit - colorDB.begin());
840 }
841
842
843 void FormPreferences::updateColors()
844 {}
845
846
847 void FormPreferences::applyConverters() const
848 {
849         /* Uncomment once Converter is a "real" class.
850
851         vector<Command> old = Converter::GetAllCommands();
852         for (vector<Command>::const_iterator cit = old.begin();
853              cit != old.end(); ++cit) {
854                 pair<string, string> FromTo =
855                         pair<string, string>((*cit).from->prettyname,
856                                              (*cit).to->prettyname);
857         
858                 vector<Command>::const_iterator cit2 =
859                         find_if(commands_vec.begin(), commands_vec.end(),
860                                 compare_memfun(&Command::getFromToPrettyname,
861                                                FromTo));
862
863                 // Ie, converter exists in old, but is removed now.
864                 // Can't actually Delete it, because old will contain
865                 // system defauts.
866                 if (cit2 == commands_vec.end())
867                         commands.Add((*cit).from, (*cit).to, string());
868         }
869
870         // Add new converters.
871         for (vector<Command>::const_iterator cit = commands_vec.begin();
872              cit != commands_vec.end(); ++cit) {
873                 commands.Add((*cit).from, (*cit).to, (*cit).command);
874         }
875         */
876 }
877
878
879 void FormPreferences::buildConverters()
880 {
881         converters_ = build_converters();
882
883         fl_set_input_return(converters_->input_converter, FL_RETURN_CHANGED);
884         fl_set_input_return(converters_->input_flags, FL_RETURN_CHANGED);
885
886         // set up the feedback mechanism
887         setPreHandler( converters_->browser_all );
888         setPreHandler( converters_->button_delete );
889         setPreHandler( converters_->button_add );
890         setPreHandler( converters_->input_converter );
891         setPreHandler( converters_->choice_from );
892         setPreHandler( converters_->choice_to );
893         setPreHandler( converters_->input_flags );
894 }
895
896
897 string const
898 FormPreferences::feedbackConverters( FL_OBJECT const * const ob ) const
899 {
900         string str;
901
902         if (ob == converters_->browser_all) {
903                 str = N_("All the currently defined converters known to LyX.");
904         } else if (ob == converters_->choice_from) {
905                 str = N_("Convert \"from\" this format");
906         } else if (ob == converters_->choice_to) {
907                 str = N_("Convert \"to\" this format");
908         } else if (ob == converters_->input_converter) {
909                 str = N_("The conversion command. \"$$FName\" is the input file name, \"$$BaseName\" is the file name without its extension and $$OutName is the name of the output file.");
910         } else if (ob == converters_->input_flags) {
911                 str = N_("I have no idea what this field is to be used for!");
912         } else if (ob == converters_->button_delete) {
913                 str = N_("Remove the current converter from the list of available converters.");
914         } else if (ob == converters_->button_add) {
915                 str = N_("Add the current converter to the list of available converters.");
916         }
917
918         return str;
919 }
920
921
922 bool FormPreferences::inputConverters( FL_OBJECT const * const ob )
923 {
924         if( ob == converters_->browser_all ) {
925                 return ConvertersBrowser();
926
927         } else if (ob == converters_->choice_from
928                    || ob == converters_->choice_to
929                    || ob == converters_->input_converter
930                    || ob == converters_->input_flags ) {
931                 return ConvertersInput();
932
933         } else if( ob == converters_->button_add ) {
934                 return ConvertersAdd();
935
936         } else if( ob == converters_->button_delete ) {
937                 return ConvertersDelete();
938         }
939
940         return true;
941 }
942
943
944 void FormPreferences::updateConverters()
945 {
946         commands_vec = Converter::GetAllCommands();
947         sort( commands_vec.begin(), commands_vec.end(), &CommandsCompare );
948
949         ConvertersClear();
950 }
951
952
953 bool FormPreferences::ConvertersAdd()
954 {
955         Command command( 0, 0, "" );
956         if( !ConvertersSetCommand( command ) )
957                 return false;
958
959         string from = command.from->prettyname;
960         string to   = command.to->prettyname;
961         pair<string, string> FromTo = pair<string, string>(from, to);
962         
963         vector<Command>::iterator it = // non-const; it's modified below
964                 find_if(commands_vec.begin(), commands_vec.end(),
965                         compare_memfun(&Command::getFromToPrettyname, FromTo));
966
967         fl_freeze_form(converters_->form);
968
969         if (it == commands_vec.end()) {
970                 // Unable to find command. Add to list.
971                 commands_vec.push_back(command);
972                 sort( commands_vec.begin(), commands_vec.end(), 
973                       &CommandsCompare );
974
975         } else {
976                 // Command found. Modify it.
977                 (*it).from = command.from;
978                 (*it).to   = command.to;
979                 (*it).command = command.command;
980         }
981         
982         // Clear input
983         ConvertersClear();
984                         
985         fl_unfreeze_form(converters_->form);
986         return true;
987 }
988
989
990 bool FormPreferences::ConvertersBrowser() 
991 {
992         int i = fl_get_browser( converters_->browser_all );
993         if( i <= 0 ) return false;
994
995         fl_freeze_form( converters_->form );
996
997         Command const & c = commands_vec[i-1];
998
999         int sel = 0;
1000         for( i = 1;
1001              i <= fl_get_choice_maxitems( converters_->choice_from ); ++i ) {
1002                 string str =
1003                         fl_get_choice_item_text( converters_->choice_from, i );
1004                 str = strip( frontStrip( str ) );
1005                 
1006                 if( str == c.from->prettyname ) {
1007                         sel = i;
1008                         break;
1009                 }
1010         }
1011
1012         if( sel != 0 )
1013                 fl_set_choice( converters_->choice_from, sel );
1014
1015         sel = 0;
1016         for( int i = 1;
1017              i <= fl_get_choice_maxitems( converters_->choice_to ); ++i ) {
1018                 string str =
1019                         fl_get_choice_item_text( converters_->choice_to, i );
1020                 str = strip( frontStrip( str ) );
1021
1022                 if( str == c.to->prettyname ) {
1023                         sel = i;
1024                         break;
1025                 }
1026         }
1027
1028         if( sel != 0 )
1029                 fl_set_choice( converters_->choice_to, sel );
1030
1031         fl_set_input( converters_->input_converter, c.command.c_str() );
1032
1033         fl_set_object_label( converters_->button_add, idex(_("Modify|#M")) );
1034         fl_set_button_shortcut( converters_->button_add,
1035                                 scex(_("Modify|#M")), 1 );
1036
1037         fl_deactivate_object( converters_->button_add );
1038         fl_set_object_lcol( converters_->button_add, FL_INACTIVE );
1039
1040         fl_activate_object( converters_->button_delete );
1041         fl_set_object_lcol( converters_->button_delete, FL_BLACK );
1042                                 
1043         fl_unfreeze_form( converters_->form);
1044         return false;
1045 }
1046
1047
1048 void FormPreferences::ConvertersClear() const
1049 {
1050         // Re-create browser
1051         fl_clear_browser( converters_->browser_all );
1052         for (vector<Command>::const_iterator cit = commands_vec.begin();
1053              cit != commands_vec.end(); ++cit) {
1054                 string from = (*cit).from->prettyname;
1055                 string to   = (*cit).to->prettyname;
1056                 string name = from + " -> " + to;
1057                 fl_addto_browser( converters_->browser_all, name.c_str() );
1058         }
1059
1060         fl_set_input(converters_->input_converter, "");
1061         fl_set_input(converters_->input_flags, "");
1062
1063         fl_deselect_browser(formats_->browser_all);
1064
1065         fl_set_object_label( converters_->button_add, idex(_("Add|#A")) );
1066         fl_set_button_shortcut( converters_->button_add, scex(_("Add|#A")), 1);
1067
1068         fl_deactivate_object(converters_->button_add);
1069         fl_set_object_lcol(converters_->button_add, FL_INACTIVE);
1070
1071         fl_deactivate_object(converters_->button_delete);
1072         fl_set_object_lcol(converters_->button_delete, FL_INACTIVE);
1073 }
1074
1075
1076 bool FormPreferences::ConvertersContainFormat( Format const & format ) const
1077 {
1078         for( vector<Command>::const_iterator cit = commands_vec.begin();
1079              cit != commands_vec.end(); ++cit ) {
1080                 if( format.name == (*cit).from->name ) return true;
1081                 if( format.name == (*cit).to->name )   return true;
1082         }
1083         return false;
1084 }
1085
1086
1087 bool FormPreferences::ConvertersDelete()
1088 {
1089         Command command( 0, 0, "" );
1090         if( !ConvertersSetCommand( command ) )
1091                 return false;
1092
1093         string from = command.from->prettyname;
1094         string to   = command.to->prettyname;
1095         pair<string, string> FromTo = pair<string, string>(from, to);
1096         
1097         vector<Command>::iterator it = // non-const; it's modified below
1098                 find_if(commands_vec.begin(), commands_vec.end(),
1099                         compare_memfun(&Command::getFromToPrettyname, FromTo));
1100
1101         fl_freeze_form(converters_->form);
1102
1103         if (it == commands_vec.end()) {
1104                 fl_deactivate_object(converters_->button_delete);
1105                 fl_set_object_lcol(converters_->button_delete, FL_INACTIVE);
1106         
1107                 fl_unfreeze_form(converters_->form);
1108                 return false;
1109         }
1110
1111         commands_vec.erase(it);
1112         ConvertersClear();
1113         
1114         fl_unfreeze_form(converters_->form);
1115         return true;
1116 }
1117
1118
1119 bool FormPreferences::ConvertersInput()
1120 {
1121         string from = fl_get_choice_text( converters_->choice_from );
1122         from = strip( frontStrip( from ) );
1123         
1124         string to = fl_get_choice_text( converters_->choice_to );
1125         to = strip( frontStrip( to ) );
1126
1127         string name;
1128         if( !from.empty() && !to.empty() )
1129                 name = from + " -> " + to;
1130
1131         int sel = 0;
1132         if( !name.empty() ) {
1133                 for( int i = 0;
1134                      i < fl_get_browser_maxline(converters_->browser_all); 
1135                      ++i ) {
1136                         string str =
1137                                 fl_get_browser_line( converters_->browser_all, 
1138                                                      i+1 );
1139                         if( str == name ) {
1140                                 sel = i+1;
1141                                 break;
1142                         }
1143                 }
1144         }
1145         
1146         fl_freeze_form(converters_->form);
1147
1148         if( sel == 0 ) {
1149                 fl_set_object_label( converters_->button_add,
1150                                      idex(_("Add|#A")) );
1151                 fl_set_button_shortcut( converters_->button_add,
1152                                         scex(_("Add|#A")), 1);
1153
1154                 if( name.empty() ) {
1155                         fl_deactivate_object(converters_->button_add);
1156                         fl_set_object_lcol(converters_->button_add, FL_INACTIVE);
1157                 } else {
1158                         fl_activate_object(converters_->button_add);
1159                         fl_set_object_lcol(converters_->button_add, FL_BLACK);
1160                 }
1161
1162                 fl_deselect_browser(converters_->browser_all);
1163
1164                 fl_deactivate_object(converters_->button_delete);
1165                 fl_set_object_lcol(converters_->button_delete, FL_INACTIVE);
1166
1167         } else {
1168                 fl_set_object_label( converters_->button_add,
1169                                      idex(_("Modify|#M")) );
1170                 fl_set_button_shortcut( converters_->button_add,
1171                                         scex(_("Modify|#M")), 1);
1172                 
1173                 int top = sel-6;
1174                 if( top < 1 ) top = 0;
1175                 fl_set_browser_topline(converters_->browser_all, top);
1176                 fl_select_browser_line(converters_->browser_all, sel);
1177                 
1178                 fl_activate_object(converters_->button_add);
1179                 fl_set_object_lcol(converters_->button_add, FL_BLACK);
1180
1181                 fl_activate_object(converters_->button_delete);
1182                 fl_set_object_lcol(converters_->button_delete, FL_BLACK);
1183         }
1184
1185         fl_unfreeze_form(converters_->form);
1186         return true;
1187 }
1188
1189
1190 bool FormPreferences::ConvertersSetCommand( Command & command ) const
1191 {
1192         string from = fl_get_choice_text( converters_->choice_from );
1193         from = strip( frontStrip( from ) );
1194         if( from.empty() )
1195             return false;
1196         
1197         vector<Format>::const_iterator fit =
1198                 find_if(formats_vec.begin(), formats_vec.end(),
1199                         compare_memfun(&Format::getprettyname, from));
1200         if( fit == formats_vec.end() )
1201             return false;
1202
1203         string to = fl_get_choice_text( converters_->choice_to );
1204         to = strip( frontStrip( to ) );
1205         if( to.empty() )
1206             return false;
1207
1208         vector<Format>::const_iterator tit =
1209                 find_if(formats_vec.begin(), formats_vec.end(),
1210                         compare_memfun(&Format::getprettyname, to));
1211         if( tit == formats_vec.end() )
1212             return false;
1213
1214         string converter = fl_get_input( converters_->input_converter );
1215         string flags = fl_get_input( converters_->input_flags );
1216
1217         command.from = fit;
1218         command.to   = tit;
1219         command.command = converter;
1220
1221         return true;
1222 }
1223
1224
1225 void FormPreferences::ConvertersUpdateChoices()
1226 {
1227         string choice;
1228         for( vector<Format>::iterator cit = formats_vec.begin();
1229              cit != formats_vec.end(); ++cit ) {
1230                 if( !choice.empty() )
1231                         choice += " | ";
1232                 else
1233                         choice += " ";
1234                 choice += (*cit).prettyname;
1235         }
1236         choice += " ";
1237
1238         fl_clear_choice( converters_->choice_from );
1239         fl_addto_choice( converters_->choice_from, choice.c_str() );
1240
1241         fl_clear_choice( converters_->choice_to );
1242         fl_addto_choice( converters_->choice_to, choice.c_str() );
1243 }
1244
1245
1246 void FormPreferences::applyFormats() const
1247 {
1248         vector<Format> old = formats.GetAllFormats();
1249         for (vector<Format>::const_iterator cit = old.begin();
1250              cit != old.end(); ++cit) {
1251
1252                 vector<Format>::const_iterator cit2 =
1253                         find_if(formats_vec.begin(),formats_vec.end(),
1254                                 compare_memfun(&Format::getname, (*cit).name));
1255
1256                 // Ie, format exists in old, but is removed now.
1257                 // Can't actually Delete it, because old will contain
1258                 // system defauts.
1259                 if (cit2 == formats_vec.end())
1260                         formats.Add((*cit).name, string(), string(), string());
1261         }
1262
1263         // Add new formats.
1264         for (vector<Format>::const_iterator cit = formats_vec.begin();
1265              cit != formats_vec.end(); ++cit) {
1266                 formats.Add((*cit).name, (*cit).extension, (*cit).prettyname, 
1267                             (*cit).shortcut);
1268                 formats.SetViewer((*cit).name, (*cit).viewer);
1269         }
1270 }
1271
1272
1273 void FormPreferences::buildFormats()
1274 {
1275         formats_ = build_formats();
1276
1277         fl_set_input_return(formats_->input_format, FL_RETURN_CHANGED);
1278         fl_set_input_return(formats_->input_viewer, FL_RETURN_CHANGED);
1279         fl_set_input_return(formats_->input_shrtcut, FL_RETURN_CHANGED);
1280         fl_set_input_return(formats_->input_gui_name, FL_RETURN_CHANGED);
1281         fl_set_input_return(formats_->input_extension, FL_RETURN_CHANGED);
1282
1283         fl_set_input_filter(formats_->input_format, fl_lowercase_filter);
1284
1285         // set up the feedback mechanism
1286         setPreHandler( formats_->browser_all );
1287         setPreHandler( formats_->input_format );
1288         setPreHandler( formats_->input_gui_name );
1289         setPreHandler( formats_->button_delete );
1290         setPreHandler( formats_->button_add );
1291         setPreHandler( formats_->input_extension );
1292         setPreHandler( formats_->input_viewer );
1293         setPreHandler( formats_->input_shrtcut );
1294 }
1295
1296
1297 string const
1298 FormPreferences::feedbackFormats( FL_OBJECT const * const ob ) const
1299 {
1300         string str;
1301
1302         if (ob == formats_->browser_all) {
1303                 str = N_("All the currently defined formats known to LyX.");
1304         } else if (ob == formats_->input_format) {
1305                 str = N_("The format identifier.");
1306         } else if (ob == formats_->input_gui_name) {
1307                 str = N_("The format name as it will appear in the menus.");
1308         } else if (ob == formats_->input_shrtcut) {
1309                 str = N_("The keyboard accelerator. Use a letter in the GUI name. Case sensitive.");
1310         } else if (ob == formats_->input_extension) {
1311                 str = N_("Used to recognize the file. E.g., ps, pdf, tex.");
1312         } else if (ob == formats_->input_viewer) {
1313                 str = N_("The command used to launch the viwer application\nE.g. \"netscape $$FName\" where $$FName is the name of the file.");
1314         } else if (ob == formats_->button_delete) {
1315                 str = N_("Remove the current format from the list of available formats.");
1316         } else if (ob == formats_->button_add) {
1317                 str = N_("Add the current format to the list of available formats.");
1318         }
1319
1320         return str;
1321 }
1322
1323
1324 bool FormPreferences::inputFormats(FL_OBJECT const * const ob)
1325 {
1326         if (ob == formats_->browser_all) {
1327                 return FormatsBrowser();
1328
1329         } else if (ob == formats_->input_format
1330                    || ob == formats_->input_gui_name
1331                    || ob == formats_->input_shrtcut
1332                    || ob == formats_->input_extension
1333                    || ob == formats_->input_viewer ) {
1334                 return FormatsInput();
1335
1336         } else if (ob == formats_->button_add) {
1337                 return FormatsAdd();
1338
1339         } else if (ob == formats_->button_delete) {
1340                 return FormatsDelete();
1341         }
1342
1343         return false;
1344 }
1345
1346
1347 void FormPreferences::updateFormats()
1348 {
1349         formats_vec = formats.GetAllFormats();
1350         sort( formats_vec.begin(), formats_vec.end(), &FormatsCompare );
1351
1352         // Mustn't forget to update the Formats available to the converters
1353         ConvertersUpdateChoices();
1354
1355         FormatsClear();
1356 }
1357
1358
1359 bool FormPreferences::FormatsAdd()
1360 {
1361         string name = fl_get_input(formats_->input_format);
1362         string prettyname = fl_get_input(formats_->input_gui_name);
1363         string extension = fl_get_input(formats_->input_extension);
1364         string shortcut =  fl_get_input(formats_->input_shrtcut);
1365         string viewer =  fl_get_input(formats_->input_viewer);
1366         if (prettyname.empty())
1367                 return false;
1368
1369         Format format(name, extension, prettyname, shortcut, viewer);
1370         vector<Format>::iterator it = // non-const; it's modified below
1371                 find_if(formats_vec.begin(), formats_vec.end(),
1372                         compare_memfun(&Format::getname, name));
1373
1374         fl_freeze_form(formats_->form);
1375
1376         if (it == formats_vec.end()) {
1377                 // Unable to find format. Add to list.
1378                 formats_vec.push_back(format);
1379                 sort( formats_vec.begin(), formats_vec.end(), &FormatsCompare );
1380
1381                 // Mustn't forget to update the Formats available to the
1382                 // converters
1383                 ConvertersUpdateChoices();
1384
1385                 // Re-create browser
1386                 fl_clear_browser( formats_->browser_all );
1387                 for (vector<Format>::const_iterator cit = formats_vec.begin();
1388                      cit != formats_vec.end(); ++cit)
1389                         fl_addto_browser(formats_->browser_all,
1390                                          (*cit).name.c_str()); 
1391         } else {                
1392                 // Format found. Modify it.
1393                 (*it).name = name;
1394                 (*it).prettyname = prettyname;
1395                 (*it).extension = extension;
1396                 (*it).shortcut = shortcut;
1397                 (*it).viewer = viewer;
1398         }
1399
1400         // Clear input
1401         FormatsClear();
1402                         
1403         fl_unfreeze_form(formats_->form);
1404         return true;
1405 }
1406
1407
1408 bool FormPreferences::FormatsBrowser() 
1409 {
1410         int i = fl_get_browser(formats_->browser_all);
1411         if( i <= 0 ) return false;
1412
1413         fl_freeze_form(formats_->form);
1414
1415         Format const & f = formats_vec[i-1];
1416
1417         fl_set_input(formats_->input_format, f.name.c_str());
1418         fl_set_input(formats_->input_gui_name, f.prettyname.c_str());
1419         fl_set_input(formats_->input_shrtcut, f.shortcut.c_str());
1420         fl_set_input(formats_->input_extension, f.extension.c_str());
1421         fl_set_input(formats_->input_viewer, f.viewer.c_str());
1422
1423         fl_set_object_label( formats_->button_add, idex(_("Modify|#M")) );
1424         fl_set_button_shortcut( formats_->button_add, scex(_("Modify|#M")), 1);
1425
1426         fl_deactivate_object(formats_->button_add);
1427         fl_set_object_lcol(formats_->button_add, FL_INACTIVE);
1428
1429         fl_activate_object(formats_->button_delete);
1430         fl_set_object_lcol(formats_->button_delete, FL_BLACK);
1431                                 
1432         fl_unfreeze_form(formats_->form);
1433         return false;
1434 }
1435
1436
1437 void FormPreferences::FormatsClear() const
1438 {
1439         // Re-create browser
1440         fl_clear_browser(formats_->browser_all);
1441         for (vector<Format>::const_iterator cit = formats_vec.begin();
1442              cit != formats_vec.end(); ++cit)
1443                 fl_addto_browser( formats_->browser_all, (*cit).name.c_str() );
1444
1445         fl_deselect_browser(formats_->browser_all);
1446
1447         fl_set_input(formats_->input_format, "");
1448         fl_set_input(formats_->input_gui_name, "");
1449         fl_set_input(formats_->input_shrtcut, "");
1450         fl_set_input(formats_->input_extension, "");
1451         fl_set_input(formats_->input_viewer, "");
1452
1453         fl_set_object_label( formats_->button_add, idex(_("Add|#A")) );
1454         fl_set_button_shortcut( formats_->button_add, scex(_("Add|#A")), 1);
1455
1456         fl_deactivate_object(formats_->button_add);
1457         fl_set_object_lcol(formats_->button_add, FL_INACTIVE);
1458
1459         fl_deactivate_object(formats_->button_delete);
1460         fl_set_object_lcol(formats_->button_delete, FL_INACTIVE);
1461 }
1462
1463
1464 bool FormPreferences::FormatsDelete()
1465 {
1466         string name = fl_get_input(formats_->input_format);
1467         vector<Format>::iterator it = // non-const; it's modified below
1468                 find_if(formats_vec.begin(), formats_vec.end(),
1469                         compare_memfun(&Format::getname, name));
1470
1471         fl_freeze_form(formats_->form);
1472
1473         bool warning = ConvertersContainFormat( *it );
1474         if( warning ) {
1475                 string str = N_("WARNING! Cannot remove a Format used by a Converter. Remove the converter first.");
1476                 printWarning( str );
1477         }
1478         
1479         if (it == formats_vec.end() || warning) {
1480                 fl_deactivate_object(formats_->button_delete);
1481                 fl_set_object_lcol(formats_->button_delete, FL_INACTIVE);
1482         
1483                 fl_unfreeze_form(formats_->form);
1484                 return false;
1485         }
1486
1487         formats_vec.erase(it);
1488         FormatsClear();
1489         
1490         // Mustn't forget to update the Formats available to the converters
1491         ConvertersUpdateChoices();
1492                 
1493         fl_unfreeze_form(formats_->form);
1494         return true;
1495 }
1496
1497
1498 bool FormPreferences::FormatsInput()
1499 {
1500         string name = fl_get_input(formats_->input_format);
1501
1502         int sel = 0;
1503         if( !name.empty() ) {
1504                 for( int i = 0;
1505                      i < fl_get_browser_maxline(formats_->browser_all); ++i ) {
1506                         string str =
1507                                 fl_get_browser_line( formats_->browser_all,
1508                                                      i+1 );
1509                         if( str == name ) {
1510                                 sel = i+1;
1511                                 break;
1512                         }
1513                 }
1514         }
1515         
1516         fl_freeze_form(formats_->form);
1517
1518         if( sel == 0 ) {
1519                 fl_set_object_label( formats_->button_add,
1520                                      idex(_("Add|#A")) );
1521                 fl_set_button_shortcut( formats_->button_add,
1522                                         scex(_("Add|#A")), 1);
1523
1524                 if( name.empty() ) {
1525                         fl_deactivate_object(formats_->button_add);
1526                         fl_set_object_lcol(formats_->button_add, FL_INACTIVE);
1527                 } else {
1528                         fl_activate_object(formats_->button_add);
1529                         fl_set_object_lcol(formats_->button_add, FL_BLACK);
1530                 }
1531
1532                 fl_deselect_browser(formats_->browser_all);
1533
1534                 fl_deactivate_object(formats_->button_delete);
1535                 fl_set_object_lcol(formats_->button_delete, FL_INACTIVE);
1536
1537         } else {
1538                 fl_set_object_label( formats_->button_add,
1539                                      idex(_("Modify|#M")) );
1540                 fl_set_button_shortcut( formats_->button_add,
1541                                         scex(_("Modify|#M")), 1);
1542
1543                 int top = sel-6;
1544                 if( top < 1 ) top = 0;
1545                 fl_set_browser_topline(formats_->browser_all, top);
1546                 fl_select_browser_line(formats_->browser_all, sel);
1547                 
1548                 fl_activate_object(formats_->button_add);
1549                 fl_set_object_lcol(formats_->button_add, FL_BLACK);
1550
1551                 fl_activate_object(formats_->button_delete);
1552                 fl_set_object_lcol(formats_->button_delete, FL_BLACK);
1553         }
1554
1555         fl_unfreeze_form(formats_->form);
1556         return true;
1557 }
1558
1559
1560 void FormPreferences::applyInputsMisc() const
1561 {
1562         lyxrc.date_insert_format =
1563                 fl_get_input(inputs_misc_->input_date_format);
1564 }
1565
1566
1567 void FormPreferences::buildInputsMisc()
1568 {
1569         inputs_misc_ = build_inputs_misc();
1570
1571         fl_set_input_return(inputs_misc_->input_date_format,
1572                             FL_RETURN_CHANGED);
1573
1574         // set up the feedback mechanism
1575         setPreHandler( inputs_misc_->input_date_format );
1576 }
1577
1578
1579 string const
1580 FormPreferences::feedbackInputsMisc(FL_OBJECT const * const ob) const
1581 {
1582         string str;
1583
1584         if (ob == inputs_misc_->input_date_format )
1585                 str = lyxrc.getDescription( LyXRC::RC_DATE_INSERT_FORMAT );
1586
1587         return str;
1588 }
1589
1590
1591 void FormPreferences::updateInputsMisc()
1592 {
1593         fl_set_input(inputs_misc_->input_date_format,
1594                      lyxrc.date_insert_format.c_str());
1595 }
1596
1597
1598 void FormPreferences::applyInterface() const
1599 {
1600         lyxrc.popup_font_name =
1601                 fl_get_input(interface_->input_popup_font);
1602         lyxrc.menu_font_name = fl_get_input(interface_->input_menu_font);
1603         lyxrc.font_norm_menu =
1604                 fl_get_input(interface_->input_popup_encoding);
1605         lyxrc.bind_file = fl_get_input(interface_->input_bind_file);
1606         lyxrc.ui_file = fl_get_input(interface_->input_ui_file);
1607         lyxrc.override_x_deadkeys =
1608                 fl_get_button(interface_->check_override_x_dead_keys);
1609 }
1610
1611
1612 void FormPreferences::buildInterface()
1613 {
1614         interface_ = build_interface();
1615
1616         fl_set_input_return(interface_->input_popup_font, FL_RETURN_CHANGED);
1617         fl_set_input_return(interface_->input_menu_font, FL_RETURN_CHANGED);
1618         fl_set_input_return(interface_->input_popup_encoding, 
1619                             FL_RETURN_CHANGED);
1620         fl_set_input_return(interface_->input_bind_file, FL_RETURN_CHANGED);
1621         fl_set_input_return(interface_->input_ui_file, FL_RETURN_CHANGED);
1622
1623         // deactivate the browse buttons because they aren't implemented
1624         fl_deactivate_object(interface_->button_bind_file_browse);
1625         fl_deactivate_object(interface_->button_ui_file_browse);
1626         fl_set_object_lcol(interface_->button_bind_file_browse, FL_INACTIVE);
1627         fl_set_object_lcol(interface_->button_ui_file_browse, FL_INACTIVE);
1628
1629         // set up the feedback mechanism
1630         setPreHandler( interface_->input_popup_font );
1631         setPreHandler( interface_->input_menu_font );
1632         setPreHandler( interface_->input_popup_encoding );
1633         setPreHandler( interface_->input_bind_file );
1634         setPreHandler( interface_->button_bind_file_browse );
1635         setPreHandler( interface_->input_ui_file );
1636         setPreHandler( interface_->button_ui_file_browse );
1637         setPreHandler( interface_->check_override_x_dead_keys );
1638 }
1639
1640
1641 string const
1642 FormPreferences::feedbackInterface( FL_OBJECT const * const ob ) const
1643 {
1644         string str;
1645
1646         if (ob == interface_->input_popup_font )
1647                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_POPUP );
1648         else if (ob == interface_->input_menu_font )
1649                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_MENU );
1650         else if (ob == interface_->input_popup_encoding )
1651                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ENCODING_MENU );
1652         else if (ob == interface_->input_bind_file )
1653                 str = lyxrc.getDescription( LyXRC::RC_BINDFILE );
1654         else if (ob == interface_->input_ui_file )
1655                 str = lyxrc.getDescription( LyXRC::RC_UIFILE );
1656         else if (ob == interface_->check_override_x_dead_keys )
1657                 str = lyxrc.getDescription( LyXRC::RC_OVERRIDE_X_DEADKEYS );
1658
1659         return str;
1660 }
1661
1662
1663 void FormPreferences::updateInterface()
1664 {
1665         fl_set_input(interface_->input_popup_font,
1666                      lyxrc.popup_font_name.c_str());
1667         fl_set_input(interface_->input_menu_font,
1668                      lyxrc.menu_font_name.c_str());
1669         fl_set_input(interface_->input_popup_encoding,
1670                      lyxrc.font_norm_menu.c_str());
1671         fl_set_input(interface_->input_bind_file,
1672                      lyxrc.bind_file.c_str());
1673         fl_set_input(interface_->input_ui_file,
1674                      lyxrc.ui_file.c_str());
1675         fl_set_button(interface_->check_override_x_dead_keys,
1676                       lyxrc.override_x_deadkeys);
1677 }
1678
1679
1680 void FormPreferences::applyLanguage()
1681 {
1682         lyxrc.default_language = combo_default_lang->getline();
1683
1684         int button = fl_get_button(language_->check_use_kbmap);
1685         string name_1 = combo_kbmap_1->getline();
1686         string name_2 = combo_kbmap_2->getline();
1687         if( button )
1688                 button = ( !name_1.empty() && !name_2.empty() );
1689         lyxrc.use_kbmap = static_cast<bool>(button);
1690
1691         if (button) {
1692                 vector<string>::const_iterator cit =
1693                         find( dirlist.second.begin(), dirlist.second.end(),
1694                               name_1 );
1695                 vector<string>::size_type sel = cit - dirlist.second.begin();
1696                 lyxrc.primary_kbmap = dirlist.first[sel];
1697
1698                 cit = find( dirlist.second.begin(), dirlist.second.end(),
1699                            name_2 );
1700                 sel = cit - dirlist.second.begin();
1701                 lyxrc.secondary_kbmap = dirlist.first[sel];
1702         }
1703         
1704         button = fl_get_button(language_->check_rtl_support);
1705         lyxrc.rtl_support = static_cast<bool>(button);
1706
1707         button = fl_get_button(language_->check_auto_begin);
1708         lyxrc.language_auto_begin = static_cast<bool>(button);
1709
1710         button = fl_get_button(language_->check_auto_end);
1711         lyxrc.language_auto_end = static_cast<bool>(button);
1712
1713         button = fl_get_button(language_->check_mark_foreign);
1714         lyxrc.mark_foreign_language = static_cast<bool>(button);
1715
1716         lyxrc.language_package = fl_get_input(language_->input_package);
1717         lyxrc.language_command_begin = fl_get_input(language_->input_command_begin);
1718         lyxrc.language_command_end = fl_get_input(language_->input_command_end);
1719
1720         // Ensure that all is self-consistent.
1721         updateLanguage();
1722 }
1723
1724
1725 void FormPreferences::buildLanguage()
1726 {
1727         language_ = build_language();
1728
1729         fl_set_input_return(language_->input_package, FL_RETURN_CHANGED);
1730         fl_set_input_return(language_->input_command_begin, FL_RETURN_CHANGED);
1731         fl_set_input_return(language_->input_command_end, FL_RETURN_CHANGED);
1732
1733         // The default_language is a combo-box and has to be inserted manually
1734         fl_freeze_form(language_->form);
1735         fl_addto_form(language_->form);
1736
1737         FL_OBJECT * obj = language_->choice_default_lang;
1738         fl_deactivate_object(language_->choice_default_lang);
1739         combo_default_lang = new Combox(FL_COMBOX_DROPLIST);
1740         combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400);
1741         combo_default_lang->shortcut("#L",1);
1742         combo_default_lang->setcallback(ComboLanguageCB, this);
1743
1744         for (Languages::const_iterator cit = languages.begin();
1745             cit != languages.end(); ++cit) {
1746                 combo_default_lang->addto((*cit).second.lang());
1747         }
1748
1749         // ditto kbmap_1
1750         string dir = AddPath(system_lyxdir, "kbd");
1751         dirlist.first = DirList(dir , "kmap");
1752
1753         for (vector<string>::const_iterator cit = dirlist.first.begin();
1754             cit != dirlist.first.end(); ++cit) {
1755                 string name = ChangeExtension( OnlyFilename(*cit), "" );
1756                 dirlist.second.push_back( name );
1757         }
1758
1759         obj = language_->choice_kbmap_1;
1760         fl_deactivate_object(language_->choice_kbmap_1);
1761         combo_kbmap_1 = new Combox(FL_COMBOX_DROPLIST);
1762         combo_kbmap_1->add(obj->x, obj->y, obj->w, obj->h, 400);
1763         combo_kbmap_1->shortcut("#1",1);
1764         combo_kbmap_1->setcallback(ComboLanguageCB, this);
1765
1766         for (vector<string>::const_iterator cit = dirlist.second.begin();
1767             cit != dirlist.second.end(); ++cit) {
1768                 combo_kbmap_1->addto(*cit);
1769         }
1770
1771         // ditto kbmap_2
1772         obj = language_->choice_kbmap_2;
1773         fl_deactivate_object(language_->choice_kbmap_2);
1774         combo_kbmap_2 = new Combox(FL_COMBOX_DROPLIST);
1775         combo_kbmap_2->add(obj->x, obj->y, obj->w, obj->h, 400);
1776         combo_kbmap_2->shortcut("#2",1);
1777         combo_kbmap_2->setcallback(ComboLanguageCB, this);
1778
1779         for (vector<string>::const_iterator cit = dirlist.second.begin();
1780             cit != dirlist.second.end(); ++cit) {
1781                 combo_kbmap_2->addto(*cit);
1782         }
1783
1784         fl_end_form();
1785         fl_unfreeze_form(language_->form);
1786
1787         // set up the feedback mechanism
1788         setPreHandler( language_->input_package );
1789         setPreHandler( language_->check_use_kbmap );
1790
1791         // This is safe, as nothing is done to the pointer, other than
1792         // to use its address in a block-if statement.
1793         //setPreHandler( reinterpret_cast<FL_OBJECT *>(combo_default_lang) );
1794         //setPreHandler( reinterpret_cast<FL_OBJECT *>(combo_kbmap_1) );
1795         //setPreHandler( reinterpret_cast<FL_OBJECT *>(combo_kbmap_2) );
1796
1797         setPreHandler( language_->check_rtl_support );
1798         setPreHandler( language_->check_mark_foreign );
1799         setPreHandler( language_->check_auto_begin );
1800         setPreHandler( language_->check_auto_end );
1801         setPreHandler( language_->input_command_begin );
1802         setPreHandler( language_->input_command_end );
1803
1804         // Activate/Deactivate the input fields dependent on the state of the
1805         // buttons.
1806         inputLanguage( 0 );
1807 }
1808
1809
1810 string const
1811 FormPreferences::feedbackLanguage(FL_OBJECT const * const ob) const
1812 {
1813         string str;
1814
1815         if (reinterpret_cast<Combox const *>(ob) == combo_default_lang )
1816                 str = lyxrc.getDescription( LyXRC::RC_DEFAULT_LANGUAGE );
1817         else if (ob == language_->check_use_kbmap )
1818                 str = lyxrc.getDescription( LyXRC::RC_KBMAP );
1819         else if (reinterpret_cast<Combox const *>(ob) == combo_kbmap_1)
1820                 str = lyxrc.getDescription( LyXRC::RC_KBMAP_PRIMARY );
1821         else if (reinterpret_cast<Combox const *>(ob) == combo_kbmap_2 )
1822                 str = lyxrc.getDescription( LyXRC::RC_KBMAP_SECONDARY );
1823         else if (ob == language_->check_rtl_support )
1824                 str = lyxrc.getDescription( LyXRC::RC_RTL_SUPPORT );
1825         else if (ob == language_->check_auto_begin )
1826                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_AUTO_BEGIN );
1827         else if (ob == language_->check_auto_end )
1828                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_AUTO_END );
1829         else if (ob == language_->check_mark_foreign )
1830                 str = lyxrc.getDescription( LyXRC::RC_MARK_FOREIGN_LANGUAGE );
1831         else if (ob == language_->input_package )
1832                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_PACKAGE );
1833         else if (ob == language_->input_command_begin )
1834                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_COMMAND_BEGIN );
1835         else if (ob == language_->input_command_end )
1836                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_COMMAND_END );
1837
1838         return str;
1839 }
1840
1841
1842 bool FormPreferences::inputLanguage( FL_OBJECT const * const ob )
1843 {
1844         bool activate = true;
1845
1846         // !ob if function is called from buildLanguage() to de/activate
1847         // objects,
1848         // otherwise the function is called by an xforms CB via input().
1849         if (!ob || ob == language_->check_use_kbmap) {
1850                 if (fl_get_button(language_->check_use_kbmap)) {
1851                         combo_kbmap_1->activate();
1852                         combo_kbmap_2->activate();
1853                 } else {
1854                         combo_kbmap_1->deactivate();
1855                         combo_kbmap_2->deactivate();
1856                 }
1857         }
1858
1859         return activate;
1860 }
1861
1862
1863 void FormPreferences::updateLanguage()
1864 {
1865         fl_set_button(language_->check_use_kbmap,
1866                       lyxrc.use_kbmap);
1867
1868         combo_default_lang->select_text( lyxrc.default_language );
1869
1870         if (lyxrc.use_kbmap) {
1871                 string fullpath = lyxrc.primary_kbmap;
1872                 vector<string>::const_iterator cit =
1873                         find( dirlist.first.begin(), dirlist.first.end(),
1874                               fullpath );
1875                 if (cit != dirlist.first.end()) {
1876                         vector<string>::size_type sel =
1877                                 cit - dirlist.first.begin();
1878                         combo_kbmap_1->select_text(dirlist.second[sel]);
1879                 } else
1880                         combo_kbmap_1->select_text("");
1881
1882                 fullpath = lyxrc.secondary_kbmap;
1883                 cit = find( dirlist.first.begin(), dirlist.first.end(),
1884                            fullpath );
1885                 if (cit != dirlist.first.end()) {
1886                         vector<string>::size_type sel =
1887                                 cit - dirlist.first.begin();
1888                         combo_kbmap_2->select_text(dirlist.second[sel]);
1889                 } else
1890                         combo_kbmap_2->select_text("");
1891         } else {
1892                 combo_kbmap_1->select_text( "" );
1893                 combo_kbmap_2->select_text( "" );
1894         }
1895         
1896         fl_set_button(language_->check_rtl_support, lyxrc.rtl_support);
1897         fl_set_button(language_->check_auto_begin,  lyxrc.language_auto_begin);
1898         fl_set_button(language_->check_auto_end,    lyxrc.language_auto_end);
1899         fl_set_button(language_->check_mark_foreign,
1900                       lyxrc.mark_foreign_language);
1901
1902         fl_set_input(language_->input_package,
1903                      lyxrc.language_package.c_str());
1904         fl_set_input(language_->input_command_begin,
1905                      lyxrc.language_command_begin.c_str());
1906         fl_set_input(language_->input_command_end,
1907                      lyxrc.language_command_end.c_str());
1908
1909         // Activate/Deactivate the input fields dependent on the state of the
1910         // buttons.
1911         inputLanguage( 0 );
1912 }
1913
1914
1915 void FormPreferences::applyLnFmisc() const
1916 {
1917         lyxrc.show_banner = fl_get_button(lnf_misc_->check_banner);
1918         lyxrc.auto_region_delete = fl_get_button(lnf_misc_->
1919                                                  check_auto_region_delete);
1920         lyxrc.exit_confirmation = fl_get_button(lnf_misc_->check_exit_confirm);
1921         lyxrc.display_shortcuts =
1922                 fl_get_button(lnf_misc_->check_display_shrtcuts);
1923         lyxrc.new_ask_filename = fl_get_button(lnf_misc_->check_ask_new_file);
1924         lyxrc.cursor_follows_scrollbar =
1925                 fl_get_button(lnf_misc_->check_cursor_follows_scrollbar);
1926         lyxrc.autosave = static_cast<unsigned int>
1927                 (fl_get_counter_value(lnf_misc_->counter_autosave));
1928         lyxrc.wheel_jump = static_cast<unsigned int>
1929                 (fl_get_counter_value(lnf_misc_->counter_wm_jump));
1930 }
1931
1932
1933 void FormPreferences::buildLnFmisc()
1934 {
1935         lnf_misc_ = build_lnf_misc();
1936
1937         fl_set_counter_return(lnf_misc_->counter_autosave,
1938                               FL_RETURN_CHANGED);
1939         fl_set_counter_return(lnf_misc_->counter_wm_jump,
1940                               FL_RETURN_CHANGED);
1941
1942         // set up the feedback mechanism
1943         setPreHandler( lnf_misc_->check_banner );
1944         setPreHandler( lnf_misc_->check_auto_region_delete );
1945         setPreHandler( lnf_misc_->check_exit_confirm );
1946         setPreHandler( lnf_misc_->check_display_shrtcuts );
1947         setPreHandler( lnf_misc_->counter_autosave );
1948         setPreHandler( lnf_misc_->check_ask_new_file );
1949         setPreHandler( lnf_misc_->check_cursor_follows_scrollbar );
1950         setPreHandler( lnf_misc_->counter_wm_jump );
1951 }
1952
1953
1954 string const FormPreferences::feedbackLnFmisc(FL_OBJECT const * const ob) const
1955 {
1956         string str;
1957
1958         if (ob == lnf_misc_->check_banner )
1959                 str = lyxrc.getDescription( LyXRC::RC_SHOW_BANNER );
1960         else if (ob == lnf_misc_->check_auto_region_delete )
1961                 str = lyxrc.getDescription( LyXRC::RC_AUTOREGIONDELETE );
1962         else if (ob == lnf_misc_->check_exit_confirm )
1963                 str = lyxrc.getDescription( LyXRC::RC_EXIT_CONFIRMATION );
1964         else if (ob == lnf_misc_->check_display_shrtcuts )
1965                 str = lyxrc.getDescription( LyXRC::RC_DISPLAY_SHORTCUTS );
1966         else if (ob == lnf_misc_->check_ask_new_file )
1967                 str = lyxrc.getDescription( LyXRC::RC_NEW_ASK_FILENAME );
1968         else if (ob == lnf_misc_->check_cursor_follows_scrollbar )
1969                 str = lyxrc.getDescription( LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR );
1970         else if (ob == lnf_misc_->counter_autosave )
1971                 str = lyxrc.getDescription( LyXRC::RC_AUTOSAVE );
1972         else if (ob == lnf_misc_->counter_wm_jump )
1973                 str = lyxrc.getDescription( LyXRC::RC_WHEEL_JUMP );
1974
1975         return str;
1976 }
1977
1978
1979 void FormPreferences::updateLnFmisc()
1980 {
1981         fl_set_button(lnf_misc_->check_banner,
1982                       lyxrc.show_banner);
1983         fl_set_button(lnf_misc_->check_auto_region_delete,
1984                       lyxrc.auto_region_delete);
1985         fl_set_button(lnf_misc_->check_exit_confirm,
1986                       lyxrc.exit_confirmation);
1987         fl_set_button(lnf_misc_->check_display_shrtcuts,
1988                       lyxrc.display_shortcuts);
1989         fl_set_button(lnf_misc_->check_ask_new_file,
1990                       lyxrc.new_ask_filename);
1991         fl_set_button(lnf_misc_->check_cursor_follows_scrollbar,
1992                       lyxrc.cursor_follows_scrollbar);
1993         fl_set_counter_value(lnf_misc_->counter_autosave,
1994                              lyxrc.autosave);
1995         fl_set_counter_value(lnf_misc_->counter_wm_jump,
1996                              lyxrc.wheel_jump);
1997 }
1998
1999
2000 void FormPreferences::applyOutputsMisc() const
2001 {
2002         lyxrc.ascii_linelen = static_cast<unsigned int>
2003                 (fl_get_counter_value(outputs_misc_->counter_line_len));
2004         lyxrc.fontenc = fl_get_input(outputs_misc_->input_tex_encoding);
2005
2006         int choice =
2007                 fl_get_choice(outputs_misc_->choice_default_papersize) - 1;
2008         lyxrc.default_papersize = static_cast<BufferParams::PAPER_SIZE>(choice);
2009
2010         lyxrc.ascii_roff_command = fl_get_input(outputs_misc_->input_ascii_roff);
2011         lyxrc.chktex_command = fl_get_input(outputs_misc_->input_checktex);
2012 }
2013
2014
2015 void FormPreferences::buildOutputsMisc()
2016 {
2017         outputs_misc_ = build_outputs_misc();
2018
2019         fl_set_counter_return(outputs_misc_->counter_line_len,
2020                               FL_RETURN_CHANGED);
2021         fl_set_input_return(outputs_misc_->input_tex_encoding,
2022                             FL_RETURN_CHANGED);
2023         fl_set_input_return(outputs_misc_->input_ascii_roff,
2024                             FL_RETURN_CHANGED);
2025         fl_set_input_return(outputs_misc_->input_checktex,
2026                             FL_RETURN_CHANGED);
2027         fl_addto_choice(outputs_misc_->choice_default_papersize,
2028                         _(" default | US letter | legal | executive | A3 | A4 | A5 | B5 "));
2029
2030         // set up the feedback mechanism
2031         setPreHandler( outputs_misc_->counter_line_len );
2032         setPreHandler( outputs_misc_->input_tex_encoding );
2033         setPreHandler( outputs_misc_->choice_default_papersize );
2034         setPreHandler( outputs_misc_->input_ascii_roff );
2035         setPreHandler( outputs_misc_->input_checktex );
2036 }
2037
2038
2039 string const
2040 FormPreferences::feedbackOutputsMisc(FL_OBJECT const * const ob) const
2041 {
2042         string str;
2043
2044         if (ob == outputs_misc_->counter_line_len )
2045                 str = lyxrc.getDescription( LyXRC::RC_ASCII_LINELEN );
2046         else if (ob == outputs_misc_->input_tex_encoding )
2047                 str = lyxrc.getDescription( LyXRC::RC_FONT_ENCODING );
2048         else if (ob == outputs_misc_->input_ascii_roff )
2049                 str = lyxrc.getDescription( LyXRC::RC_ASCIIROFF_COMMAND );
2050         else if (ob == outputs_misc_->input_checktex )
2051                 str = lyxrc.getDescription( LyXRC::RC_CHKTEX_COMMAND );
2052         else if (ob == outputs_misc_->choice_default_papersize )
2053                 str = lyxrc.getDescription( LyXRC::RC_DEFAULT_PAPERSIZE );
2054
2055         return str;
2056 }
2057
2058
2059 void FormPreferences::updateOutputsMisc()
2060 {
2061         fl_set_counter_value(outputs_misc_->counter_line_len,
2062                              lyxrc.ascii_linelen);
2063         fl_set_input(outputs_misc_->input_tex_encoding,
2064                      lyxrc.fontenc.c_str());
2065         fl_set_choice(outputs_misc_->choice_default_papersize,
2066                       lyxrc.default_papersize+1);
2067         fl_set_input(outputs_misc_->input_ascii_roff,
2068                      lyxrc.ascii_roff_command.c_str());
2069         fl_set_input(outputs_misc_->input_checktex,
2070                      lyxrc.chktex_command.c_str());
2071 }
2072
2073
2074 void FormPreferences::applyPaths()
2075 {
2076         lyxrc.document_path = fl_get_input(paths_->input_default_path);
2077         lyxrc.template_path = fl_get_input(paths_->input_template_path);
2078
2079         int button = fl_get_button(paths_->check_use_temp_dir);
2080         string str  = fl_get_input(paths_->input_temp_dir);
2081         if (!button ) str.erase();
2082
2083         lyxrc.use_tempdir = button;
2084         lyxrc.tempdir_path = str;
2085
2086         button = fl_get_button(paths_->check_last_files);
2087         str = fl_get_input(paths_->input_lastfiles);
2088         if (!button ) str.erase();
2089         
2090         lyxrc.check_lastfiles = button;
2091         lyxrc.lastfiles = str;
2092         lyxrc.num_lastfiles = static_cast<unsigned int>
2093                 (fl_get_counter_value(paths_->counter_lastfiles));
2094
2095         button = fl_get_button(paths_->check_make_backups);
2096         str = fl_get_input(paths_->input_backup_path);
2097         if (!button ) str.erase();
2098
2099         lyxrc.make_backup = button;
2100         lyxrc.backupdir_path = str;
2101
2102         lyxrc.lyxpipes = fl_get_input(paths_->input_serverpipe);
2103
2104         // update view
2105         updatePaths();
2106 }
2107
2108
2109 void FormPreferences::buildPaths()
2110 {
2111         paths_ = build_paths();
2112
2113         fl_set_input_return(paths_->input_default_path, FL_RETURN_CHANGED);
2114         fl_set_input_return(paths_->input_template_path, FL_RETURN_CHANGED);
2115         fl_set_input_return(paths_->input_temp_dir, FL_RETURN_CHANGED);
2116         fl_set_input_return(paths_->input_lastfiles, FL_RETURN_CHANGED);
2117         fl_set_input_return(paths_->input_backup_path, FL_RETURN_CHANGED);
2118         fl_set_counter_return(paths_->counter_lastfiles, FL_RETURN_CHANGED);
2119         fl_set_input_return(paths_->input_serverpipe, FL_RETURN_CHANGED);
2120
2121         // deactivate the browse buttons because they aren't implemented
2122         fl_deactivate_object(paths_->button_document_browse);
2123         fl_deactivate_object(paths_->button_template_browse);
2124         fl_deactivate_object(paths_->button_temp_dir_browse);
2125         fl_deactivate_object(paths_->button_lastfiles_browse);
2126         fl_deactivate_object(paths_->button_backup_path_browse);
2127         fl_deactivate_object(paths_->button_serverpipe_browse);
2128         fl_set_object_lcol(paths_->button_document_browse, FL_INACTIVE);
2129         fl_set_object_lcol(paths_->button_template_browse, FL_INACTIVE);
2130         fl_set_object_lcol(paths_->button_temp_dir_browse, FL_INACTIVE);
2131         fl_set_object_lcol(paths_->button_lastfiles_browse, FL_INACTIVE);
2132         fl_set_object_lcol(paths_->button_backup_path_browse, FL_INACTIVE);
2133         fl_set_object_lcol(paths_->button_serverpipe_browse, FL_INACTIVE);
2134
2135         // set up the feedback mechanism
2136         setPreHandler( paths_->input_default_path );
2137         setPreHandler( paths_->button_document_browse );
2138         setPreHandler( paths_->counter_lastfiles );
2139         setPreHandler( paths_->input_template_path );
2140         setPreHandler( paths_->button_template_browse );
2141         setPreHandler( paths_->check_last_files );
2142         setPreHandler( paths_->button_temp_dir_browse );
2143         setPreHandler( paths_->input_lastfiles );
2144         setPreHandler( paths_->button_lastfiles_browse );
2145         setPreHandler( paths_->check_make_backups );
2146         setPreHandler( paths_->input_backup_path );
2147         setPreHandler( paths_->button_backup_path_browse );
2148         setPreHandler( paths_->input_serverpipe );
2149         setPreHandler( paths_->button_serverpipe_browse );
2150         setPreHandler( paths_->input_temp_dir );
2151         setPreHandler( paths_->check_use_temp_dir );
2152 }
2153
2154
2155 string const FormPreferences::feedbackPaths( FL_OBJECT const * const ob ) const
2156 {
2157         string str;
2158
2159         if (ob == paths_->input_default_path )
2160                 str = lyxrc.getDescription( LyXRC::RC_DOCUMENTPATH );
2161         else if (ob == paths_->input_template_path )
2162                 str = lyxrc.getDescription( LyXRC::RC_TEMPLATEPATH );
2163         else if (ob == paths_->check_use_temp_dir )
2164                 str = lyxrc.getDescription( LyXRC::RC_USETEMPDIR );
2165         else if (ob == paths_->input_temp_dir )
2166                 str = lyxrc.getDescription( LyXRC::RC_TEMPDIRPATH );
2167         else if (ob == paths_->check_last_files )
2168                 str = lyxrc.getDescription( LyXRC::RC_CHECKLASTFILES );
2169         else if (ob == paths_->input_lastfiles )
2170                 str = lyxrc.getDescription( LyXRC::RC_LASTFILES );
2171         else if (ob == paths_->counter_lastfiles )
2172                 str = lyxrc.getDescription( LyXRC::RC_NUMLASTFILES );
2173         else if (ob == paths_->check_make_backups )
2174                 str = lyxrc.getDescription( LyXRC::RC_MAKE_BACKUP );
2175         else if (ob == paths_->input_backup_path )
2176                 str = lyxrc.getDescription( LyXRC::RC_BACKUPDIR_PATH );
2177         else if (ob == paths_->input_serverpipe )
2178                 str = lyxrc.getDescription( LyXRC::RC_SERVERPIPE );
2179
2180         return str;
2181 }
2182
2183
2184 bool FormPreferences::inputPaths( FL_OBJECT const * const ob )
2185 {
2186         bool activate = true;
2187         
2188         // !ob if function is called from updatePaths() to de/activate objects,
2189         // otherwise the function is called by an xforms CB via input().
2190         if (!ob || ob == paths_->check_use_temp_dir) {
2191                 if (fl_get_button(paths_->check_use_temp_dir)) {
2192                         fl_activate_object(paths_->input_temp_dir);
2193                         fl_set_object_lcol(paths_->input_temp_dir,
2194                                            FL_BLACK);
2195                 } else {
2196                         fl_deactivate_object(paths_->input_temp_dir);
2197                         fl_set_object_lcol(paths_->input_temp_dir,
2198                                            FL_INACTIVE);
2199                 }
2200         }
2201
2202         if (!ob || ob == paths_->check_last_files) {
2203                 if (fl_get_button(paths_->check_last_files)) {
2204                         fl_activate_object(paths_->input_lastfiles);
2205                         fl_set_object_lcol(paths_->input_lastfiles,
2206                                            FL_BLACK);
2207                 } else {
2208                         fl_deactivate_object(paths_->input_lastfiles);
2209                         fl_set_object_lcol(paths_->input_lastfiles,
2210                                            FL_INACTIVE);
2211                 }
2212         }
2213
2214         if (!ob || ob == paths_->check_make_backups) {
2215                 if (fl_get_button(paths_->check_make_backups)) {
2216                         fl_activate_object(paths_->input_backup_path);
2217                         fl_set_object_lcol(paths_->input_backup_path,
2218                                            FL_BLACK);
2219                 } else {
2220                         fl_deactivate_object(paths_->input_backup_path);
2221                         fl_set_object_lcol(paths_->input_backup_path,
2222                                            FL_INACTIVE);
2223                 }
2224         }
2225
2226         if (!ob || ob == paths_->input_default_path) {
2227                 string name = fl_get_input(paths_->input_default_path);
2228                 if (!WriteableDir(name) )
2229                         return false;
2230         }
2231
2232         if (!ob || ob == paths_->input_template_path) {
2233                 string name = fl_get_input(paths_->input_template_path);
2234                 if (!ReadableDir(name) )
2235                     return false;
2236         }
2237
2238         if (!ob || ob == paths_->input_temp_dir) {
2239                 string name = fl_get_input(paths_->input_temp_dir);
2240                 if (fl_get_button(paths_->check_make_backups)
2241                     && !name.empty()
2242                     && !WriteableDir(name) )
2243                         return false;
2244         }
2245
2246         if (!ob || ob == paths_->input_backup_path) {
2247                 string name = fl_get_input(paths_->input_backup_path);
2248                 if (fl_get_button(paths_->check_make_backups)
2249                     && !name.empty()
2250                     && !WriteableDir(name) )
2251                         return false;
2252         }
2253
2254         if (!ob || ob == paths_->input_lastfiles) {
2255                 string name = fl_get_input(paths_->input_lastfiles);
2256                 if (fl_get_button(paths_->check_last_files)
2257                     && !name.empty()
2258                     && !WriteableFile(name) )
2259                         return false;
2260         }
2261
2262         if (!ob || ob == paths_->input_serverpipe) {
2263                 string name = fl_get_input(paths_->input_serverpipe);
2264                 if (!name.empty()) {
2265                         if (!WriteableFile(name, ".in"))
2266                                 return false;
2267                         if (!WriteableFile(name, ".out"))
2268                                 return false;
2269                 }
2270         }
2271
2272         return activate;
2273 }
2274
2275
2276 void FormPreferences::updatePaths()
2277 {
2278         fl_set_input(paths_->input_default_path,
2279                      lyxrc.document_path.c_str());
2280         fl_set_input(paths_->input_template_path,
2281                      lyxrc.template_path.c_str());
2282
2283         string str;
2284         if (lyxrc.make_backup) str = lyxrc.backupdir_path;
2285
2286         fl_set_button(paths_->check_make_backups,
2287                       lyxrc.make_backup);
2288         fl_set_input(paths_->input_backup_path, str.c_str());
2289
2290         str.erase();
2291         if (lyxrc.use_tempdir) str = lyxrc.tempdir_path;
2292
2293         fl_set_button(paths_->check_use_temp_dir,
2294                       lyxrc.use_tempdir);
2295         fl_set_input(paths_->input_temp_dir, str.c_str());
2296
2297         str.erase();
2298         if (lyxrc.check_lastfiles) str = lyxrc.lastfiles;
2299
2300         fl_set_button(paths_->check_last_files,
2301                       lyxrc.check_lastfiles);           
2302         fl_set_input(paths_->input_lastfiles, str.c_str());
2303         fl_set_counter_value(paths_->counter_lastfiles,
2304                              lyxrc.num_lastfiles);
2305
2306         fl_set_input(paths_->input_serverpipe, lyxrc.lyxpipes.c_str());
2307
2308         // Activate/Deactivate the input fields dependent on the state of the
2309         // buttons.
2310         inputPaths( 0 );
2311 }
2312
2313
2314 void FormPreferences::applyPrinter() const
2315 {
2316         lyxrc.print_adapt_output = fl_get_button(printer_->check_adapt_output);
2317         lyxrc.print_command = fl_get_input(printer_->input_command);
2318         lyxrc.print_pagerange_flag = fl_get_input(printer_->input_page_range);
2319         lyxrc.print_copies_flag = fl_get_input(printer_->input_copies);
2320         lyxrc.print_reverse_flag = fl_get_input(printer_->input_reverse);
2321         lyxrc.print_to_printer = fl_get_input(printer_->input_to_printer);
2322         lyxrc.print_file_extension =
2323                 fl_get_input(printer_->input_file_extension);
2324         lyxrc.print_spool_command =
2325                 fl_get_input(printer_->input_spool_command);
2326         lyxrc.print_paper_flag = fl_get_input(printer_->input_paper_type);
2327         lyxrc.print_evenpage_flag = fl_get_input(printer_->input_even_pages);
2328         lyxrc.print_oddpage_flag = fl_get_input(printer_->input_odd_pages);
2329         lyxrc.print_collcopies_flag = fl_get_input(printer_->input_collated);
2330         lyxrc.print_landscape_flag = fl_get_input(printer_->input_landscape);
2331         lyxrc.print_to_file = fl_get_input(printer_->input_to_file);
2332         lyxrc.print_extra_options =
2333                 fl_get_input(printer_->input_extra_options);
2334         lyxrc.print_spool_printerprefix =
2335                 fl_get_input(printer_->input_spool_prefix);
2336         lyxrc.print_paper_dimension_flag =
2337                 fl_get_input(printer_->input_paper_size);
2338         lyxrc.printer = fl_get_input(printer_->input_name);
2339 }
2340
2341
2342 string const
2343 FormPreferences::feedbackPrinter(FL_OBJECT const * const ob) const
2344 {
2345         string str;
2346
2347         if (ob == printer_->input_command )
2348                 str = lyxrc.getDescription( LyXRC::RC_PRINT_COMMAND );
2349         else if (ob == printer_->check_adapt_output )
2350                 str = lyxrc.getDescription( LyXRC::RC_PRINT_ADAPTOUTPUT );
2351         else if (ob == printer_->input_to_printer )
2352                 str = lyxrc.getDescription( LyXRC::RC_PRINTTOPRINTER );
2353         else if (ob == printer_->input_to_file )
2354                 str = lyxrc.getDescription( LyXRC::RC_PRINTTOFILE );
2355         else if (ob == printer_->input_file_extension )
2356                 str = lyxrc.getDescription( LyXRC::RC_PRINTFILEEXTENSION );
2357         else if (ob == printer_->input_extra_options )
2358                 str = lyxrc.getDescription( LyXRC::RC_PRINTEXSTRAOPTIONS );
2359         else if (ob == printer_->input_spool_command )
2360                 str = lyxrc.getDescription( LyXRC::RC_PRINTSPOOL_COMMAND );
2361         else if (ob == printer_->input_spool_prefix )
2362                 str = lyxrc.getDescription( LyXRC::RC_PRINTSPOOL_PRINTERPREFIX );
2363         else if (ob == printer_->input_name )
2364                 str = lyxrc.getDescription( LyXRC::RC_PRINTER );
2365         else if (ob == printer_->input_even_pages )
2366                 str = lyxrc.getDescription( LyXRC::RC_PRINTEVENPAGEFLAG );
2367         else if (ob == printer_->input_odd_pages )
2368                 str = lyxrc.getDescription( LyXRC::RC_PRINTODDPAGEFLAG );
2369         else if (ob == printer_->input_page_range )
2370                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAGERANGEFLAG );
2371         else if (ob == printer_->input_reverse )
2372                 str = lyxrc.getDescription( LyXRC::RC_PRINTREVERSEFLAG );
2373         else if (ob == printer_->input_landscape )
2374                 str = lyxrc.getDescription( LyXRC::RC_PRINTLANDSCAPEFLAG );
2375         else if (ob == printer_->input_copies )
2376                 str = lyxrc.getDescription( LyXRC::RC_PRINTCOLLCOPIESFLAG );
2377         else if (ob == printer_->input_collated )
2378                 str = lyxrc.getDescription( LyXRC::RC_PRINTCOPIESFLAG );
2379         else if (ob == printer_->input_paper_type )
2380                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAPERFLAG );
2381         else if (ob == printer_->input_paper_size )
2382                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAPERDIMENSIONFLAG );
2383
2384         return str;
2385 }
2386
2387
2388 void FormPreferences::buildPrinter()
2389 {
2390         printer_ = build_printer();
2391
2392         fl_set_input_return(printer_->input_command, FL_RETURN_CHANGED);
2393         fl_set_input_return(printer_->input_page_range, FL_RETURN_CHANGED);
2394         fl_set_input_return(printer_->input_copies, FL_RETURN_CHANGED);
2395         fl_set_input_return(printer_->input_reverse, FL_RETURN_CHANGED);
2396         fl_set_input_return(printer_->input_to_printer, FL_RETURN_CHANGED);
2397         fl_set_input_return(printer_->input_file_extension, FL_RETURN_CHANGED);
2398         fl_set_input_return(printer_->input_spool_command, FL_RETURN_CHANGED);
2399         fl_set_input_return(printer_->input_paper_type, FL_RETURN_CHANGED);
2400         fl_set_input_return(printer_->input_even_pages, FL_RETURN_CHANGED);
2401         fl_set_input_return(printer_->input_odd_pages, FL_RETURN_CHANGED);
2402         fl_set_input_return(printer_->input_collated, FL_RETURN_CHANGED);
2403         fl_set_input_return(printer_->input_landscape, FL_RETURN_CHANGED);
2404         fl_set_input_return(printer_->input_to_file, FL_RETURN_CHANGED);
2405         fl_set_input_return(printer_->input_extra_options, FL_RETURN_CHANGED);
2406         fl_set_input_return(printer_->input_spool_prefix, FL_RETURN_CHANGED);
2407         fl_set_input_return(printer_->input_paper_size, FL_RETURN_CHANGED);
2408         fl_set_input_return(printer_->input_name, FL_RETURN_CHANGED);
2409
2410         // set up the feedback mechanism
2411         setPreHandler( printer_->input_command );
2412         setPreHandler( printer_->input_page_range );
2413         setPreHandler( printer_->input_copies );
2414         setPreHandler( printer_->input_reverse );
2415         setPreHandler( printer_->input_to_printer );
2416         setPreHandler( printer_->input_file_extension );
2417         setPreHandler( printer_->input_spool_command );
2418         setPreHandler( printer_->input_paper_type );
2419         setPreHandler( printer_->input_even_pages );
2420         setPreHandler( printer_->input_odd_pages );
2421         setPreHandler( printer_->input_collated );
2422         setPreHandler( printer_->input_landscape );
2423         setPreHandler( printer_->input_to_file );
2424         setPreHandler( printer_->input_extra_options );
2425         setPreHandler( printer_->input_spool_prefix );
2426         setPreHandler( printer_->input_paper_size );
2427         setPreHandler( printer_->input_name );
2428         setPreHandler( printer_->check_adapt_output );
2429 }
2430
2431
2432 void FormPreferences::updatePrinter()
2433 {
2434         fl_set_button(printer_->check_adapt_output,
2435                       lyxrc.print_adapt_output);
2436         fl_set_input(printer_->input_command,
2437                      lyxrc.print_command.c_str());
2438         fl_set_input(printer_->input_page_range,
2439                      lyxrc.print_pagerange_flag.c_str());
2440         fl_set_input(printer_->input_copies,
2441                      lyxrc.print_copies_flag.c_str());
2442         fl_set_input(printer_->input_reverse,
2443                      lyxrc.print_reverse_flag.c_str());
2444         fl_set_input(printer_->input_to_printer,
2445                      lyxrc.print_to_printer.c_str());
2446         fl_set_input(printer_->input_file_extension,
2447                      lyxrc.print_file_extension.c_str());
2448         fl_set_input(printer_->input_spool_command,
2449                      lyxrc.print_spool_command.c_str());
2450         fl_set_input(printer_->input_paper_type,
2451                      lyxrc.print_paper_flag.c_str());
2452         fl_set_input(printer_->input_even_pages,
2453                      lyxrc.print_evenpage_flag.c_str());
2454         fl_set_input(printer_->input_odd_pages,
2455                      lyxrc.print_oddpage_flag.c_str());
2456         fl_set_input(printer_->input_collated,
2457                      lyxrc.print_collcopies_flag.c_str());
2458         fl_set_input(printer_->input_landscape,
2459                      lyxrc.print_landscape_flag.c_str());
2460         fl_set_input(printer_->input_to_file,
2461                      lyxrc.print_to_file.c_str());
2462         fl_set_input(printer_->input_extra_options,
2463                      lyxrc.print_extra_options.c_str());
2464         fl_set_input(printer_->input_spool_prefix,
2465                      lyxrc.print_spool_printerprefix.c_str());
2466         fl_set_input(printer_->input_paper_size,
2467                      lyxrc.print_paper_dimension_flag.c_str());
2468         fl_set_input(printer_->input_name,
2469                      lyxrc.printer.c_str());
2470 }
2471
2472
2473 void FormPreferences::applyScreenFonts() const
2474 {
2475         bool changed = false;
2476
2477         string str = fl_get_input(screen_fonts_->input_roman);
2478         if (lyxrc.roman_font_name != str) {
2479                 changed = true;
2480                 lyxrc.roman_font_name = str;
2481         }
2482
2483         str = fl_get_input(screen_fonts_->input_sans);
2484         if (lyxrc.sans_font_name != str) {
2485                 changed = true;
2486                 lyxrc.sans_font_name = str;
2487         }
2488
2489         str = fl_get_input(screen_fonts_->input_typewriter);
2490         if (lyxrc.typewriter_font_name != str) {
2491                 changed = true;
2492                 lyxrc.typewriter_font_name = str;
2493         }
2494
2495         str = fl_get_input(screen_fonts_->input_screen_encoding);
2496         if (lyxrc.font_norm != str) {
2497                 changed = true;
2498                 lyxrc.font_norm = str;
2499         }
2500
2501         bool button = fl_get_button(screen_fonts_->check_scalable);
2502         if (lyxrc.use_scalable_fonts != button) {
2503                 changed = true;
2504                 lyxrc.use_scalable_fonts = button;
2505         }
2506
2507         unsigned int ivalue = static_cast<unsigned int>
2508                 (fl_get_counter_value(screen_fonts_->counter_zoom));
2509         if (lyxrc.zoom != ivalue) {
2510                 changed = true;
2511                 lyxrc.zoom = ivalue;
2512         }
2513
2514         ivalue = static_cast<unsigned int>
2515                 (fl_get_counter_value(screen_fonts_->counter_dpi));
2516         if (lyxrc.dpi != ivalue) {
2517                 changed = true;
2518                 lyxrc.dpi = ivalue;
2519         }
2520         
2521         double dvalue = strToDbl(fl_get_input(screen_fonts_->input_tiny));
2522         if (lyxrc.font_sizes[LyXFont::SIZE_TINY] != dvalue) {
2523                 changed = true;
2524                 lyxrc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
2525         }
2526
2527         dvalue = strToDbl(fl_get_input(screen_fonts_->input_script));
2528         if (lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue) {
2529                 changed = true;
2530                 lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
2531         }
2532
2533         dvalue = strToDbl(fl_get_input(screen_fonts_->input_footnote));
2534         if (lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue) {
2535                 changed = true;
2536                 lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
2537         }
2538
2539         dvalue = strToDbl(fl_get_input(screen_fonts_->input_small));
2540         if (lyxrc.font_sizes[LyXFont::SIZE_SMALL] != dvalue) {
2541                 changed = true;
2542                 lyxrc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
2543         }
2544
2545         dvalue = strToDbl(fl_get_input(screen_fonts_->input_normal));
2546         if (lyxrc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue) {
2547                 changed = true;
2548                 lyxrc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
2549         }
2550
2551         dvalue = strToDbl(fl_get_input(screen_fonts_->input_large));
2552         if (lyxrc.font_sizes[LyXFont::SIZE_LARGE] != dvalue) {
2553                 changed = true;
2554                 lyxrc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
2555         }
2556
2557         dvalue = strToDbl(fl_get_input(screen_fonts_->input_larger));
2558         if (lyxrc.font_sizes[LyXFont::SIZE_LARGER] != dvalue) {
2559                 changed = true;
2560                 lyxrc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
2561         }
2562
2563         dvalue = strToDbl(fl_get_input(screen_fonts_->input_largest));
2564         if (lyxrc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue) {
2565                 changed = true;
2566                 lyxrc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
2567         }
2568
2569         dvalue = strToDbl(fl_get_input(screen_fonts_->input_huge));
2570         if (lyxrc.font_sizes[LyXFont::SIZE_HUGE] != dvalue) {
2571                 changed = true;
2572                 lyxrc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
2573         }
2574
2575         dvalue = strToDbl(fl_get_input(screen_fonts_->input_huger));
2576         if (lyxrc.font_sizes[LyXFont::SIZE_HUGER] != dvalue) {
2577                 changed = true;
2578                 lyxrc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
2579         }
2580
2581         if (changed) {
2582                 // Now update the buffers
2583                 // Can anything below here affect the redraw process?
2584                 lv_->getLyXFunc()->Dispatch(LFUN_SCREEN_FONT_UPDATE);
2585         }
2586 }
2587
2588
2589 void FormPreferences::buildScreenFonts()
2590 {
2591         screen_fonts_ = build_screen_fonts();
2592
2593         fl_set_input_return(screen_fonts_->input_roman, FL_RETURN_CHANGED);
2594         fl_set_input_return(screen_fonts_->input_sans, FL_RETURN_CHANGED);
2595         fl_set_input_return(screen_fonts_->input_typewriter,
2596                             FL_RETURN_CHANGED);
2597         fl_set_input_return(screen_fonts_->input_screen_encoding,
2598                             FL_RETURN_CHANGED);
2599         fl_set_counter_return(screen_fonts_->counter_zoom, FL_RETURN_CHANGED);
2600         fl_set_counter_return(screen_fonts_->counter_dpi, FL_RETURN_CHANGED);
2601         fl_set_input_return(screen_fonts_->input_tiny, FL_RETURN_CHANGED);
2602         fl_set_input_return(screen_fonts_->input_script, FL_RETURN_CHANGED);
2603         fl_set_input_return(screen_fonts_->input_footnote, FL_RETURN_CHANGED);
2604         fl_set_input_return(screen_fonts_->input_small, FL_RETURN_CHANGED);
2605         fl_set_input_return(screen_fonts_->input_normal, FL_RETURN_CHANGED);
2606         fl_set_input_return(screen_fonts_->input_large, FL_RETURN_CHANGED);
2607         fl_set_input_return(screen_fonts_->input_larger, FL_RETURN_CHANGED);
2608         fl_set_input_return(screen_fonts_->input_largest, FL_RETURN_CHANGED);
2609         fl_set_input_return(screen_fonts_->input_huge, FL_RETURN_CHANGED);
2610         fl_set_input_return(screen_fonts_->input_huger, FL_RETURN_CHANGED);
2611
2612         fl_set_input_filter(screen_fonts_->input_tiny,
2613                             fl_unsigned_int_filter);
2614         fl_set_input_filter(screen_fonts_->input_script,
2615                             fl_unsigned_int_filter);
2616         fl_set_input_filter(screen_fonts_->input_footnote,
2617                             fl_unsigned_int_filter);
2618         fl_set_input_filter(screen_fonts_->input_small,
2619                             fl_unsigned_int_filter);
2620         fl_set_input_filter(screen_fonts_->input_normal,
2621                             fl_unsigned_int_filter);
2622         fl_set_input_filter(screen_fonts_->input_large,
2623                             fl_unsigned_int_filter);
2624         fl_set_input_filter(screen_fonts_->input_larger,
2625                             fl_unsigned_int_filter);
2626         fl_set_input_filter(screen_fonts_->input_largest,
2627                             fl_unsigned_int_filter);
2628         fl_set_input_filter(screen_fonts_->input_huge,
2629                             fl_unsigned_int_filter);
2630         fl_set_input_filter(screen_fonts_->input_huger,
2631                             fl_unsigned_int_filter);
2632
2633         // set up the feedback mechanism
2634         setPreHandler( screen_fonts_->input_roman );
2635         setPreHandler( screen_fonts_->input_sans );
2636         setPreHandler( screen_fonts_->input_typewriter );
2637         setPreHandler( screen_fonts_->counter_zoom );
2638         setPreHandler( screen_fonts_->counter_dpi );
2639         setPreHandler( screen_fonts_->check_scalable );
2640         setPreHandler( screen_fonts_->input_screen_encoding );
2641         setPreHandler( screen_fonts_->input_tiny );
2642         setPreHandler( screen_fonts_->input_script );
2643         setPreHandler( screen_fonts_->input_footnote );
2644         setPreHandler( screen_fonts_->input_small );
2645         setPreHandler( screen_fonts_->input_large );
2646         setPreHandler( screen_fonts_->input_larger );
2647         setPreHandler( screen_fonts_->input_largest );
2648         setPreHandler( screen_fonts_->input_normal );
2649         setPreHandler( screen_fonts_->input_huge );
2650         setPreHandler( screen_fonts_->input_huger );
2651 }
2652
2653         
2654 string const
2655 FormPreferences::feedbackScreenFonts(FL_OBJECT const * const ob ) const
2656 {
2657         string str;
2658
2659         if (ob == screen_fonts_->input_roman )
2660                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ROMAN );
2661         else if (ob == screen_fonts_->input_sans )
2662                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SANS );
2663         else if (ob == screen_fonts_->input_typewriter )
2664                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_TYPEWRITER );
2665         else if (ob == screen_fonts_->check_scalable )
2666                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SCALABLE );
2667         else if (ob == screen_fonts_->input_screen_encoding )
2668                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ENCODING );
2669         else if (ob == screen_fonts_->counter_zoom )
2670                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_ZOOM );
2671         else if (ob == screen_fonts_->counter_dpi ) 
2672                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_DPI );
2673         else if (ob == screen_fonts_->input_tiny
2674                  || ob == screen_fonts_->input_script
2675                  || ob == screen_fonts_->input_footnote
2676                  || ob == screen_fonts_->input_small
2677                  || ob == screen_fonts_->input_large
2678                  || ob == screen_fonts_->input_larger
2679                  || ob == screen_fonts_->input_larger
2680                  || ob == screen_fonts_->input_largest
2681                  || ob == screen_fonts_->input_normal
2682                  || ob == screen_fonts_->input_huge
2683                  || ob == screen_fonts_->input_huger )
2684                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SIZES );
2685
2686         return str;
2687 }
2688
2689
2690 bool FormPreferences::inputScreenFonts()
2691 {
2692         bool activate = true;
2693         string str;
2694
2695         // Make sure that all fonts all have positive entries
2696         // Also note that an empty entry is returned as 0.0 by strToDbl
2697         if (0.0 >= strToDbl(fl_get_input(screen_fonts_->input_tiny))
2698             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_script))
2699             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_footnote))
2700             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_small))
2701             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_normal))
2702             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_large))
2703             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_larger))
2704             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_largest))
2705             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_huge))
2706             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_huger))) {
2707                 activate = false;
2708                 str = N_("WARNING! Fonts must be positive!");
2709
2710         // Fontsizes -- tiny < script < footnote etc.
2711         } else if (strToDbl(fl_get_input(screen_fonts_->input_tiny)) >
2712                    strToDbl(fl_get_input(screen_fonts_->input_script)) ||
2713                    strToDbl(fl_get_input(screen_fonts_->input_script)) >
2714                    strToDbl(fl_get_input(screen_fonts_->input_footnote)) ||
2715                    strToDbl(fl_get_input(screen_fonts_->input_footnote)) >
2716                    strToDbl(fl_get_input(screen_fonts_->input_small)) ||
2717                    strToDbl(fl_get_input(screen_fonts_->input_small)) >
2718                    strToDbl(fl_get_input(screen_fonts_->input_normal)) ||
2719                    strToDbl(fl_get_input(screen_fonts_->input_normal)) >
2720                    strToDbl(fl_get_input(screen_fonts_->input_large)) ||
2721                    strToDbl(fl_get_input(screen_fonts_->input_large)) >
2722                    strToDbl(fl_get_input(screen_fonts_->input_larger)) ||
2723                    strToDbl(fl_get_input(screen_fonts_->input_larger)) >
2724                    strToDbl(fl_get_input(screen_fonts_->input_largest)) ||
2725                    strToDbl(fl_get_input(screen_fonts_->input_largest)) >
2726                    strToDbl(fl_get_input(screen_fonts_->input_huge)) ||
2727                    strToDbl(fl_get_input(screen_fonts_->input_huge)) >
2728                    strToDbl(fl_get_input(screen_fonts_->input_huger))) {
2729                 activate = false;
2730
2731                 str = N_("WARNING! Fonts must be input in the order tiny > script>\nfootnote > small > normal > large > larger > largest > huge > huger.");
2732         }
2733
2734         if (!activate)
2735                 printWarning( str );
2736         
2737         return activate;
2738 }
2739
2740
2741 void FormPreferences::updateScreenFonts()
2742 {
2743         fl_set_input(screen_fonts_->input_roman,
2744                      lyxrc.roman_font_name.c_str());
2745         fl_set_input(screen_fonts_->input_sans,
2746                      lyxrc.sans_font_name.c_str());
2747         fl_set_input(screen_fonts_->input_typewriter,
2748                      lyxrc.typewriter_font_name.c_str());
2749         fl_set_input(screen_fonts_->input_screen_encoding,
2750                      lyxrc.font_norm.c_str());
2751         fl_set_button(screen_fonts_->check_scalable,
2752                       lyxrc.use_scalable_fonts);
2753         fl_set_counter_value(screen_fonts_->counter_zoom, lyxrc.zoom);
2754         fl_set_counter_value(screen_fonts_->counter_dpi,  lyxrc.dpi);
2755         fl_set_input(screen_fonts_->input_tiny,
2756                      tostr(lyxrc.font_sizes[LyXFont::SIZE_TINY]).c_str());
2757         fl_set_input(screen_fonts_->input_script,
2758                      tostr(lyxrc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
2759         fl_set_input(screen_fonts_->input_footnote,
2760                      tostr(lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
2761         fl_set_input(screen_fonts_->input_small,
2762                      tostr(lyxrc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
2763         fl_set_input(screen_fonts_->input_normal,
2764                      tostr(lyxrc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
2765         fl_set_input(screen_fonts_->input_large,
2766                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
2767         fl_set_input(screen_fonts_->input_larger,
2768                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
2769         fl_set_input(screen_fonts_->input_largest,
2770                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
2771         fl_set_input(screen_fonts_->input_huge,
2772                      tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
2773         fl_set_input(screen_fonts_->input_huger,
2774                      tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
2775 }
2776
2777
2778 void FormPreferences::applySpellChecker()
2779 {
2780
2781         string choice = fl_get_choice_text(spellchecker_->choice_spell_command);
2782         choice = strip( frontStrip( choice ) );
2783         
2784         lyxrc.isp_command = choice;
2785
2786         // If spell checker == "none", all other input set to off.
2787         if (fl_get_choice(spellchecker_->choice_spell_command) == 1) {
2788                 lyxrc.isp_use_alt_lang = false;
2789                 lyxrc.isp_alt_lang.erase();
2790
2791                 lyxrc.isp_use_esc_chars = false;
2792                 lyxrc.isp_esc_chars.erase();
2793
2794                 lyxrc.isp_use_pers_dict = false;
2795                 lyxrc.isp_pers_dict.erase();
2796
2797                 lyxrc.isp_accept_compound = false;
2798                 lyxrc.isp_use_input_encoding = false;
2799         } else {
2800                 int button = fl_get_button(spellchecker_->check_alt_lang);
2801                 choice = fl_get_input(spellchecker_->input_alt_lang);
2802                 if (button && choice.empty() ) button = 0;
2803                 if (!button ) choice.erase();
2804
2805                 lyxrc.isp_use_alt_lang = static_cast<bool>(button);
2806                 lyxrc.isp_alt_lang = choice;
2807
2808                 button = fl_get_button(spellchecker_->check_escape_chars);
2809                 choice = fl_get_input(spellchecker_->input_escape_chars);
2810                 if (button && choice.empty() ) button = 0;
2811                 if (!button ) choice.erase();
2812         
2813                 lyxrc.isp_use_esc_chars = static_cast<bool>(button);
2814                 lyxrc.isp_esc_chars = choice;
2815
2816                 button = fl_get_button(spellchecker_->check_personal_dict);
2817                 choice = fl_get_input(spellchecker_->input_personal_dict);
2818                 if (button && choice.empty() ) button = 0;
2819                 if (!button ) choice.erase();
2820
2821                 lyxrc.isp_use_pers_dict = static_cast<bool>(button);
2822                 lyxrc.isp_pers_dict = choice;
2823
2824                 button = fl_get_button(spellchecker_->check_compound_words);
2825                 lyxrc.isp_accept_compound = static_cast<bool>(button);
2826
2827                 button = fl_get_button(spellchecker_->check_input_enc);
2828                 lyxrc.isp_use_input_encoding = static_cast<bool>(button);
2829         }
2830
2831         // Reset view
2832         updateSpellChecker();
2833 }
2834
2835
2836 void FormPreferences::buildSpellchecker()
2837 {
2838         spellchecker_ = build_spellchecker();
2839
2840         fl_addto_choice(spellchecker_->choice_spell_command,
2841                         _(" none | ispell | aspell "));
2842         fl_set_input_return(spellchecker_->input_alt_lang,
2843                             FL_RETURN_CHANGED);
2844         fl_set_input_return(spellchecker_->input_escape_chars,
2845                             FL_RETURN_CHANGED);
2846         fl_set_input_return(spellchecker_->input_personal_dict,
2847                             FL_RETURN_CHANGED);
2848
2849         // deactivate the browse button because it isn't implemented
2850         fl_deactivate_object(spellchecker_->button_personal_dict);
2851         fl_set_object_lcol(spellchecker_->button_personal_dict,
2852                            FL_INACTIVE);
2853
2854         // set up the feedback mechanism
2855         setPreHandler( spellchecker_->choice_spell_command );
2856         setPreHandler( spellchecker_->check_alt_lang );
2857         setPreHandler( spellchecker_->input_alt_lang );
2858         setPreHandler( spellchecker_->check_escape_chars );
2859         setPreHandler( spellchecker_->input_escape_chars );
2860         setPreHandler( spellchecker_->check_personal_dict );
2861         setPreHandler( spellchecker_->input_personal_dict );
2862         setPreHandler( spellchecker_->button_personal_dict );
2863         setPreHandler( spellchecker_->check_compound_words );
2864         setPreHandler( spellchecker_->check_input_enc );
2865 }
2866
2867
2868 string const
2869 FormPreferences::feedbackSpellChecker(FL_OBJECT const * const ob) const
2870 {
2871         string str;
2872
2873         if (ob == spellchecker_->choice_spell_command )
2874                 str = lyxrc.getDescription( LyXRC::RC_SPELL_COMMAND );
2875         else if (ob == spellchecker_->check_alt_lang )
2876                 str = lyxrc.getDescription( LyXRC::RC_USE_ALT_LANG );
2877         else if (ob == spellchecker_->input_alt_lang )
2878                 str = lyxrc.getDescription( LyXRC::RC_ALT_LANG );
2879         else if (ob == spellchecker_->check_escape_chars )
2880                 str = lyxrc.getDescription( LyXRC::RC_USE_ESC_CHARS );
2881         else if (ob == spellchecker_->input_escape_chars )
2882                 str = lyxrc.getDescription( LyXRC::RC_ESC_CHARS );
2883         else if (ob == spellchecker_->check_personal_dict )
2884                 str = lyxrc.getDescription( LyXRC::RC_USE_PERS_DICT );
2885         else if (ob == spellchecker_->input_personal_dict )
2886                 str = lyxrc.getDescription( LyXRC::RC_PERS_DICT );
2887         else if (ob == spellchecker_->check_compound_words )
2888                 str = lyxrc.getDescription( LyXRC::RC_ACCEPT_COMPOUND );
2889         else if (ob == spellchecker_->check_input_enc )
2890                 str = lyxrc.getDescription( LyXRC::RC_USE_INP_ENC );
2891
2892         return str;
2893 }
2894
2895
2896 bool FormPreferences::inputSpellChecker( FL_OBJECT const * const ob )
2897 {
2898         // !ob if function is called from updateSpellChecker() to de/activate
2899         // objects,
2900         // otherwise the function is called by an xforms CB via input().
2901
2902         // If spell checker == "none", disable all input.
2903         if (!ob || ob == spellchecker_->choice_spell_command) {
2904                 if (fl_get_choice(spellchecker_->choice_spell_command) == 1) {
2905                         fl_deactivate_object( spellchecker_->check_alt_lang );
2906                         fl_deactivate_object( spellchecker_->input_alt_lang );
2907                         fl_deactivate_object( spellchecker_->check_escape_chars );
2908                         fl_deactivate_object( spellchecker_->input_escape_chars );
2909                         fl_deactivate_object( spellchecker_->check_personal_dict );
2910                         fl_deactivate_object( spellchecker_->input_personal_dict );
2911                         fl_deactivate_object( spellchecker_->check_compound_words );
2912                         fl_deactivate_object( spellchecker_->check_input_enc );
2913                         return true;
2914                 } else {
2915                         fl_activate_object( spellchecker_->check_alt_lang );
2916                         fl_activate_object( spellchecker_->check_escape_chars );
2917                         fl_activate_object( spellchecker_->check_personal_dict );
2918                         fl_activate_object( spellchecker_->check_compound_words );
2919                         fl_activate_object( spellchecker_->check_input_enc );
2920                 }
2921         }
2922
2923         if (!ob || ob == spellchecker_->check_alt_lang) {
2924                 if (fl_get_button(spellchecker_->check_alt_lang)) {
2925                         fl_activate_object(spellchecker_->input_alt_lang);
2926                         fl_set_object_lcol(spellchecker_->input_alt_lang,
2927                                            FL_BLACK);
2928                 } else {
2929                         fl_deactivate_object(spellchecker_->input_alt_lang);
2930                         fl_set_object_lcol(spellchecker_->input_alt_lang,
2931                                            FL_INACTIVE);
2932                 }
2933         }
2934
2935         if (!ob || ob == spellchecker_->check_escape_chars) {
2936                 if (fl_get_button(spellchecker_->check_escape_chars)) {
2937                         fl_activate_object(spellchecker_->input_escape_chars);
2938                         fl_set_object_lcol(spellchecker_->input_escape_chars,
2939                                            FL_BLACK);
2940                 } else {
2941                         fl_deactivate_object(spellchecker_->input_escape_chars);
2942                         fl_set_object_lcol(spellchecker_->input_escape_chars,
2943                                            FL_INACTIVE);
2944                 }
2945         }
2946
2947         if (!ob || ob == spellchecker_->check_personal_dict) {
2948                 if (fl_get_button(spellchecker_->check_personal_dict)) {
2949                         fl_activate_object(spellchecker_->input_personal_dict);
2950                         fl_set_object_lcol(spellchecker_->input_personal_dict,
2951                                            FL_BLACK);
2952                 } else {
2953                         fl_deactivate_object(spellchecker_->input_personal_dict);
2954                         fl_set_object_lcol(spellchecker_->input_personal_dict,
2955                                            FL_INACTIVE);
2956                 }
2957         }
2958         
2959         return true; // All input is valid!
2960 }
2961
2962
2963 void FormPreferences::updateSpellChecker()
2964 {
2965         int choice = 1;
2966         if (lyxrc.isp_command == "none" )
2967                 choice = 1;
2968         else if (lyxrc.isp_command == "ispell" )
2969                 choice = 2;
2970         else if (lyxrc.isp_command == "aspell" )
2971                 choice = 3;
2972         fl_set_choice(spellchecker_->choice_spell_command, choice);
2973         
2974         string str;
2975         if (lyxrc.isp_use_alt_lang ) str = lyxrc.isp_alt_lang;
2976
2977         fl_set_button(spellchecker_->check_alt_lang,
2978                       lyxrc.isp_use_alt_lang);
2979         fl_set_input(spellchecker_->input_alt_lang, str.c_str());
2980         
2981         str.erase();
2982         if (lyxrc.isp_use_esc_chars ) str = lyxrc.isp_esc_chars;
2983
2984         fl_set_button(spellchecker_->check_escape_chars,
2985                       lyxrc.isp_use_esc_chars);
2986         fl_set_input(spellchecker_->input_escape_chars, str.c_str());
2987
2988         str.erase();
2989         if (lyxrc.isp_use_pers_dict ) str = lyxrc.isp_pers_dict;
2990
2991         fl_set_button(spellchecker_->check_personal_dict,
2992                       lyxrc.isp_use_pers_dict);
2993         fl_set_input(spellchecker_->input_personal_dict, str.c_str());
2994
2995         fl_set_button(spellchecker_->check_compound_words,
2996                       lyxrc.isp_accept_compound);
2997         fl_set_button(spellchecker_->check_input_enc,
2998                       lyxrc.isp_use_input_encoding);
2999
3000         // Activate/Deactivate the input fields dependent on the state of the
3001         // buttons.
3002         inputSpellChecker( 0 );
3003 }
3004
3005
3006 bool FormPreferences::WriteableDir( string const & name )
3007 {
3008         bool success = true;
3009         string str;
3010
3011         if (!AbsolutePath(name)) {
3012                 success = false;
3013                 str = N_("WARNING! The absolute path is required.");
3014         }
3015
3016         FileInfo const tp(name);
3017         if (success && !tp.isDir()) {
3018                 success = false;
3019                 str = N_("WARNING! Directory does not exist.");
3020         }
3021
3022         if (success && !tp.writable()) {
3023                 success = false;
3024                 str = N_("WARNING! Cannot write to this directory.");
3025         }
3026
3027         if (!success)
3028                 printWarning( str );
3029         
3030         return success;
3031 }
3032
3033
3034 bool FormPreferences::ReadableDir( string const & name )
3035 {
3036         bool success = true;
3037         string str;
3038
3039         if (!AbsolutePath(name)) {
3040                 success = false;
3041                 str = N_("WARNING! The absolute path is required.");
3042         }
3043
3044         FileInfo const tp(name);
3045         if (success && !tp.isDir()) {
3046                 success = false;
3047                 str = N_("WARNING! Directory does not exist.");
3048         }
3049
3050         if (success && !tp.readable()) {
3051                 success = false;
3052                 str = N_("WARNING! Cannot read this directory.");
3053         }
3054
3055         if (!success)
3056                 printWarning( str );
3057
3058         return success;
3059 }
3060
3061
3062 bool FormPreferences::WriteableFile(string const & name,
3063                                     string const & suffix)
3064 {
3065         // A writeable file is either:
3066         // * An existing file to which we have write access, or
3067         // * A file that doesn't yet exist but that would exist in a writeable
3068         //   directory.
3069
3070         bool success = true;
3071         string str;
3072
3073         if (name.empty()) {
3074                 success = false;
3075                 str = N_("WARNING! No file input.");
3076         }
3077
3078         string const dir = OnlyPath(name);
3079         if (success && !AbsolutePath(dir)) {
3080                 success = false;
3081                 str = N_("WARNING! The absolute path is required.");
3082         }
3083
3084 #if 0
3085         // This is not a nice way to use FileInfo (Lgb)
3086         FileInfo d;
3087         
3088         {
3089                 FileInfo d1(dir);
3090                 FileInfo d2(name);
3091                 if (d2.isDir() )
3092                         d = d2;
3093                 else
3094                         d = d1;
3095         }
3096 #else
3097         // This should be equivalent (Lgb)
3098         FileInfo d(name);
3099         if (!d.isDir()) {
3100                 d.newFile(dir);
3101         }
3102 #endif
3103         if (success && !d.isDir()) {
3104                 success = false;
3105                 str = N_("WARNING! Directory does not exist.");
3106         }
3107         
3108         if (success && !d.writable()) {
3109                 success = false;
3110                 str = N_("WARNING! Cannot write to this directory.");
3111         }
3112
3113         FileInfo f(name+suffix);
3114         if (success && (dir == name || f.isDir())) {
3115                 success = false;
3116                 str = N_("WARNING! A file is required, not a directory.");
3117         }
3118
3119         if (success && (f.exist() && !f.writable())) {
3120                 success = false;
3121                 str = N_("WARNING! Cannot write to this file.");
3122         }
3123         
3124         if (!success)
3125                 printWarning( str );
3126
3127         return success;
3128 }
3129
3130
3131 void FormPreferences::printWarning( string const & warning )
3132 {
3133         warningPosted = true;
3134
3135         string str = formatted( warning, dialog_->text_warning->w-10,
3136                                 FL_SMALL_SIZE, FL_NORMAL_STYLE );
3137
3138         fl_set_object_label(dialog_->text_warning, str.c_str());
3139         fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
3140 }
3141
3142
3143 void FormPreferences::ComboLanguageCB(int, void * v, Combox * combox)
3144 {
3145     FormPreferences * pre = static_cast<FormPreferences*>(v);
3146     // This is safe, as nothing is done to the pointer, other than
3147     // to use its address in a block-if statement.
3148     pre->bc_.valid( pre->input( reinterpret_cast<FL_OBJECT *>(combox), 0 ));
3149 }
3150
3151
3152 // C function wrapper, required by xforms.
3153 C_PREPOSTHANDLER(FormPreferences, FeedbackCB)
3154
3155 int FormPreferences::FeedbackCB(FL_OBJECT * ob, int event,
3156                                 FL_Coord, FL_Coord, int, void *)
3157 {
3158         // Note that the return value is important in the pre-emptive handler.
3159         // Don't return anything other than 0.
3160
3161         Assert(ob);
3162         // Don't Assert this one, as it can happen quite reasonably when things
3163         // are being deleted in the d-tor.
3164         //Assert(ob->form);
3165         if( !ob->form ) return 0;
3166
3167         FormPreferences * pre =
3168                 static_cast<FormPreferences*>(ob->form->u_vdata);
3169         pre->Feedback(ob, event);
3170         return 0;
3171 }
3172
3173
3174 // preemptive handler for feedback messages
3175 void FormPreferences::Feedback(FL_OBJECT * ob, int event)
3176 {
3177         Assert(ob);
3178
3179         switch( event ) {
3180         case FL_ENTER:
3181                 warningPosted = false;
3182                 feedback( ob );
3183                 break;
3184
3185         case FL_LEAVE:
3186                 if( !warningPosted )
3187                         fl_set_object_label( dialog_->text_warning, "" );
3188                 break;
3189
3190         default:
3191                 break;
3192         }
3193 }
3194
3195
3196 void FormPreferences::setPreHandler(FL_OBJECT * ob) const
3197 {
3198         Assert(ob);
3199         fl_set_object_prehandler( ob, C_FormPreferencesFeedbackCB );
3200 }