]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormPreferences.C
More pref work from Angus
[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
33 #ifdef SIGC_CXX_NAMESPACES
34 using SigC::slot;
35 #endif
36
37 using std::find;
38 using std::getline;
39 using std::istream;
40 using std::pair;
41 using std::vector;
42
43 extern string fmt(char const * fmtstr ...);
44 extern Languages languages;
45
46 typedef pair<string, FormPreferences::RGB> X11Colour;
47
48 static vector<X11Colour> colourDB;
49 static string const colourFile = "/usr/lib/X11/rgb.txt";
50
51
52 FormPreferences::FormPreferences(LyXView * lv, Dialogs * d)
53         : FormBaseBI(lv, d, _("Preferences"), new PreferencesPolicy),
54           dialog_(0),
55           converters_tab_(0), inputs_tab_(0), look_n_feel_tab_(0),
56           outputs_tab_(0),  usage_tab_(0),
57           colours_(0), converters_(0), formats_(0), inputs_misc_(0),
58           interface_(0), language_(0), lnf_misc_(0), outputs_misc_(0),
59           paths_(0), printer_(0), screen_fonts_(0), spellchecker_(0),
60           combo_default_lang(0), combo_kbmap_1(0), combo_kbmap_2(0),
61           feedbackObj(0)
62 {
63         // let the dialog be shown
64         // This is a permanent connection so we won't bother
65         // storing a copy because we won't be disconnecting.
66         d->showPreferences.connect(slot(this, &FormPreferences::show));
67 }
68
69
70 FormPreferences::~FormPreferences()
71 {
72         delete combo_default_lang;
73         delete combo_kbmap_1;
74         delete combo_kbmap_2;
75
76         delete converters_tab_;
77         delete inputs_tab_;
78         delete look_n_feel_tab_;
79         delete outputs_tab_;
80         delete usage_tab_;
81
82         delete colours_;
83         delete converters_;
84         delete formats_;
85         delete inputs_misc_;
86         delete interface_;
87         delete language_;
88         delete lnf_misc_;
89         delete outputs_misc_;
90         delete paths_;
91         delete printer_;
92         delete screen_fonts_;
93         delete spellchecker_;
94
95         // Must delete dialog last or we'll end up with a SIGSEGV trying to
96         // access dialog_->timer_feedback in feedbackPost().
97         delete dialog_;
98 }
99
100
101 FL_FORM * FormPreferences::form() const
102 {
103         if (dialog_) return dialog_->form;
104         return 0;
105 }
106
107
108 void FormPreferences::ok()
109 {
110         FormBase::ok();
111         lv_->getLyXFunc()->Dispatch(LFUN_SAVEPREFERENCES);
112 }
113
114
115 void FormPreferences::hide()
116 {
117         // We need to hide the active tabfolder otherwise we get a
118         // BadDrawable error from X windows and LyX crashes without saving.
119         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabfolder_prefs);
120         if (outer_form
121             && outer_form->visible) {
122                 fl_hide_form(outer_form);
123         }
124         FormBase::hide();
125 }
126
127
128 void FormPreferences::build()
129 {
130         dialog_ = build_preferences();
131
132         // manage the restore, save, apply and cancel/close buttons
133         bc_.setOK(dialog_->button_ok);
134         bc_.setApply(dialog_->button_apply);
135         bc_.setCancel(dialog_->button_cancel);
136         bc_.setUndoAll(dialog_->button_restore);
137         bc_.refresh();
138
139         // Workaround dumb xforms sizing bug
140         minw_ = form()->w;
141         minh_ = form()->h;
142
143         // build the tab folders
144         converters_tab_ = build_outer_tab();
145         look_n_feel_tab_ = build_outer_tab();
146         inputs_tab_ = build_outer_tab();
147         outputs_tab_ = build_outer_tab();
148         usage_tab_ = build_outer_tab();
149
150         // build actual tabfolder contents
151         // these will become nested tabfolders
152         buildColours();
153         buildConverters();
154         buildFormats();
155         buildInputsMisc();
156         buildInterface();
157         buildLanguage();
158         buildLnFmisc();
159         buildOutputsMisc();
160         buildPaths();
161         buildPrinter();
162         buildScreenFonts();
163         buildSpellchecker();
164
165         // Now add them to the tabfolder
166         fl_addto_tabfolder(dialog_->tabfolder_prefs,
167                            _("Look and Feel"),
168                            look_n_feel_tab_->form);
169         fl_addto_tabfolder(dialog_->tabfolder_prefs,
170                            _("Usage"),
171                            usage_tab_->form);
172         fl_addto_tabfolder(dialog_->tabfolder_prefs,
173                            _("Converters"),
174                            converters_tab_->form);
175         fl_addto_tabfolder(dialog_->tabfolder_prefs,
176                            _("Inputs"),
177                            inputs_tab_->form);
178         fl_addto_tabfolder(dialog_->tabfolder_prefs,
179                            _("Outputs"),
180                            outputs_tab_->form);
181
182         // now build the nested tabfolders
183         // Starting with look and feel
184         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
185                            _("Screen Fonts"),
186                            screen_fonts_->form);
187         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
188                            _("Interface"),
189                            interface_->form);
190         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
191                            _("Colours"),
192                            colours_->form);
193         fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
194                            _("Misc"),
195                            lnf_misc_->form);
196
197         // then build converters
198         fl_addto_tabfolder(converters_tab_->tabfolder_outer,
199                            _("Formats"),
200                            formats_->form);
201         fl_addto_tabfolder(converters_tab_->tabfolder_outer,
202                            _("Converters"),
203                            converters_->form);
204
205         // then build inputs
206         // Paths should probably go in a few outer_tab called Files
207         fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
208                            _("Paths"),
209                            paths_->form);
210         fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
211                            _("Misc"),
212                            inputs_misc_->form);
213
214         // then building outputs
215         fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
216                            _("Printer"),
217                            printer_->form);
218         fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
219                            _("Misc"),
220                            outputs_misc_->form);
221
222         // then building usage
223         fl_addto_tabfolder(usage_tab_->tabfolder_outer,
224                            _("Spell checker"),
225                            spellchecker_->form);
226         fl_addto_tabfolder(usage_tab_->tabfolder_outer,
227                            _("Language"),
228                            language_->form);
229 }
230
231
232 void FormPreferences::apply()
233 {
234         // set the new lyxrc entries
235         // many of these need to trigger other functions when the assignment
236         // is made.  For example, screen zoom and font types.  These could be
237         // handled either by signals/slots in lyxrc or just directly call the
238         // associated functions here.
239         // There are other problems with this scheme.  We really should check
240         // what we copy to make sure that it really is necessary to do things
241         // like update the screen fonts because that flushes the textcache
242         // and other stuff which may cost us a lot on slower/high-load machines.
243
244         applyColours();
245         applyConverters();
246         applyFormats();
247         applyInputsMisc();
248         applyInterface();
249         applyLanguage();
250         applyLnFmisc();
251         applyOutputsMisc();
252         applyPaths();
253         applyPrinter();
254         applyScreenFonts();
255         applySpellChecker();
256 }
257
258
259 void FormPreferences::feedback( FL_OBJECT * ob )
260 {
261         string str;
262
263         if( ob->form->fdui == colours_ ) {
264                 str = feedbackColours( ob );
265         } else if( ob->form->fdui == converters_ ) {
266                 str = feedbackConverters( ob );
267         } else if( ob->form->fdui == formats_ ) {
268                 str = feedbackFormats( ob );
269         } else if( ob->form->fdui == inputs_misc_ ) {
270                 str = feedbackInputsMisc( ob );
271         } else if( ob->form->fdui == interface_ ) {
272                 str = feedbackInterface( ob );
273         } else if( ob->form->fdui == language_ ) {
274                 str = feedbackLanguage( ob );
275         } else if( ob->form->fdui == lnf_misc_ ) {
276                 str = feedbackLnFmisc( ob );
277         } else if( ob->form->fdui == outputs_misc_ ) {
278                 str = feedbackOutputsMisc( ob );
279         } else if( ob->form->fdui == paths_ ) {
280                 str = feedbackPaths( ob );
281         } else if( ob->form->fdui == printer_ ) {
282                 str = feedbackPrinter( ob );
283         } else if( ob->form->fdui == screen_fonts_ ) {
284                 str = feedbackScreenFonts( ob );
285         } else if( ob->form->fdui == spellchecker_ ) {
286                 str = feedbackSpellChecker( ob );
287         }
288
289         str = formatted( str, dialog_->text_warning->w-10,
290                          FL_SMALL_SIZE, FL_NORMAL_STYLE );
291
292         fl_set_object_label(dialog_->text_warning, str.c_str());
293         fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
294 }
295
296
297 bool FormPreferences::input(FL_OBJECT * ob, long)
298 {
299         bool activate = true;
300
301         // whatever checks you need to ensure the user hasn't entered
302         // some totally ridiculous value somewhere.  Change activate to suit.
303         // comments before each test describe what is _valid_
304
305         if( ob->form->fdui == colours_ ) {
306                 if( ! inputColours( ob ) )
307                         activate = false;
308         } else if( ob->form->fdui == language_ ) {
309                 if( ! inputLanguage( ob ) )
310                         activate = false;
311         } else if( ob->form->fdui == paths_ ) {
312                 if( ! inputPaths( ob ) )
313                         activate = false;
314         } else if( ob->form->fdui == screen_fonts_ ) {
315                 if( ! inputScreenFonts() )
316                         activate = false;
317         } else if( ob->form->fdui == spellchecker_ ) {
318                 if( ! inputSpellChecker( ob ) )
319                         activate = false;
320         }
321
322         return activate;
323 }
324
325
326 void FormPreferences::update()
327 {
328         if (!dialog_) return;
329     
330         // read lyxrc entries
331         updateColours();
332         updateConverters();
333         updateFormats();
334         updateInputsMisc();
335         updateInterface();
336         updateLanguage();
337         updateLnFmisc();
338         updateOutputsMisc();
339         updatePaths();
340         updatePrinter();
341         updateScreenFonts();
342         updateSpellChecker();
343 }
344
345
346 void FormPreferences::applyColours() const
347 {
348 }
349
350
351 void FormPreferences::buildColours()
352 {
353         colours_ = build_colours();
354
355         FL_OBJECT *obj;
356         obj = colours_->valslider_red;
357         fl_set_slider_bounds(obj, 0, 255);
358         fl_set_slider_precision(obj, 0);
359         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
360         
361         obj = colours_->valslider_green;
362         fl_set_slider_bounds(obj, 0, 255);
363         fl_set_slider_precision(obj, 0);
364         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
365         
366         obj = colours_->valslider_blue;
367         fl_set_slider_bounds(obj, 0, 255);
368         fl_set_slider_precision(obj, 0);
369         fl_set_slider_return(obj, FL_RETURN_END_CHANGED);
370
371         fl_set_object_color(colours_->button_colour,
372                             FL_FREE_COL4, FL_FREE_COL4);
373         
374         fl_set_input_return(colours_->input_name, FL_RETURN_END_CHANGED);
375
376         if( ColoursLoadBrowser(colourFile) )
377                 fl_set_input(colours_->input_name, colourFile.c_str());
378         else
379                 fl_set_input(colours_->input_name, N_("No file found"));
380
381         // deactivate the browse button because it isn't implemented
382         fl_deactivate_object(colours_->button_browse);
383         fl_set_object_lcol(colours_->button_browse, FL_INACTIVE);
384 }
385
386
387 string FormPreferences::feedbackColours( FL_OBJECT const * const ) const
388 {
389         return string();
390 }
391
392
393 bool FormPreferences::inputColours( FL_OBJECT const * const ob )
394 {
395         bool activate = true;
396         
397         if( ob == colours_->browser_x11 ) {
398                 int i = fl_get_browser(colours_->browser_x11);
399                 if( i > 0) {
400                         ColoursUpdateBrowser(i-1);
401                 }
402
403         } else if( ob == colours_->valslider_red
404                    || ob == colours_->valslider_green
405                    || ob == colours_->valslider_blue ) {
406                 ColoursUpdateRGB();
407
408         } else if( ob == colours_->input_name) {
409                 string file = fl_get_input(colours_->input_name);
410                 if( ColoursLoadBrowser(file) )
411                         fl_set_input(colours_->input_name, file.c_str());
412                 else if( ColoursLoadBrowser(colourFile) )
413                         fl_set_input(colours_->input_name, colourFile.c_str());
414                 else
415                         fl_set_input(colours_->input_name, N_("No file found"));
416         }
417
418         return activate;
419 }
420
421
422 bool FormPreferences::ColoursLoadBrowser( string const & filename )
423 {
424         LyXLex lex(0, 0);
425
426         if (!lex.setFile(filename))
427                 return false;
428
429         istream & is = lex.getStream();
430         string line;
431
432         vector<RGB> cols;
433         vector<string> names;
434         
435         while( 1 ) {
436                 getline( is, line );
437                 if( line.empty() )
438                         break;
439
440                 if( line[0] != '!' ) {
441                         RGB col;
442                         string name;
443                         
444                         istringstream iss(line);
445                         iss >> col.r >> col.g >> col.b;
446                         while( iss.good() ) {
447                                 string next;
448                                 iss >> next;
449                                 if( !name.empty() ) name += " ";
450                                 name += next;
451                         }
452
453                         // remove redundant entries on the fly
454                         bool add = cols.empty();
455                         if( !add ) {
456                                 vector<RGB>::const_iterator it =
457                                         find( cols.begin(), cols.end(), col );
458                                 add = (it == cols.end());
459                         }
460                         
461                         if ( add ) {
462                                 name = lowercase( name );
463                                 if( name == "gray0" )   name = "black";
464                                 if( name == "gray100" ) name = "white";
465
466                                 if( name == "black" || name == "white" ) {
467                                         cols.insert(cols.begin(), col);
468                                         names.insert(names.begin(), name);
469                                 } else {
470                                         cols.push_back(col);
471                                         names.push_back(name);
472                                 }
473                         }
474                 }
475         }
476
477         vector<string>::iterator sit = names.begin();
478         for( vector<RGB>::const_iterator iit = cols.begin();
479              iit != cols.end(); ++iit, ++sit ) {
480                 colourDB.push_back( X11Colour(*sit, *iit) );
481         }
482         
483         FL_OBJECT * colbr = colours_->browser_x11;
484         fl_freeze_form(colours_->form);
485         fl_clear_browser( colbr );
486
487         for( vector<X11Colour>::const_iterator cit = colourDB.begin();
488              cit != colourDB.end(); ++cit ) {
489                 string name = (*cit).first;
490                 //RGB col     = (*cit).second;
491                 //name += "  (" + tostr(col.r) + ", " + tostr(col.g) +
492                 //      ", " + tostr(col.b) + ")";
493                 fl_addto_browser(colbr, name.c_str());
494         }
495
496         fl_set_browser_topline(colbr, 1);
497         fl_select_browser_line(colbr, 1);
498         ColoursUpdateBrowser(0);
499         fl_unfreeze_form(colours_->form);
500         
501         return true;
502 }
503
504
505 int FormPreferences::ColoursSearchEntry(RGB const & col ) const
506 {
507         int mindiff = 0x7fffffff;
508         vector<X11Colour>::const_iterator mincit = colourDB.begin();
509
510         for( vector<X11Colour>::const_iterator cit = colourDB.begin();
511              cit != colourDB.end(); ++cit ) {
512                 RGB colDB = (*cit).second;
513                 RGB diff;
514                 diff.r = col.r - colDB.r;
515                 diff.g = col.g - colDB.g;
516                 diff.b = col.b - colDB.b;
517
518                 int d = (2 * (diff.r * diff.r) +
519                          3 * (diff.g * diff.g) +
520                              (diff.b * diff.b));
521
522                 if( mindiff > d ) {
523                         mindiff = d;
524                         mincit = cit;
525                 }
526         }
527         return static_cast<int>(mincit - colourDB.begin());
528 }
529
530
531 void FormPreferences::ColoursUpdateBrowser( int i )
532 {
533         fl_freeze_form(colours_->form);
534
535         RGB col = colourDB[i].second;
536     
537         fl_mapcolor(FL_FREE_COL4+i, col.r, col.g, col.b);
538         fl_mapcolor(FL_FREE_COL4,   col.r, col.g, col.b);
539         fl_set_slider_value(colours_->valslider_red,   col.r);
540         fl_set_slider_value(colours_->valslider_green, col.g);
541         fl_set_slider_value(colours_->valslider_blue,  col.b);
542         fl_redraw_object(colours_->button_colour);
543
544         fl_unfreeze_form(colours_->form);
545 }
546
547
548 void FormPreferences::ColoursUpdateRGB()
549 {
550         fl_freeze_form(colours_->form);
551
552         RGB col;
553         col.r = int(fl_get_slider_value(colours_->valslider_red));
554         col.g = int(fl_get_slider_value(colours_->valslider_green));
555         col.b = int(fl_get_slider_value(colours_->valslider_blue));
556     
557         fl_mapcolor(FL_FREE_COL4, col.r, col.g, col.b);
558         fl_redraw_object(colours_->button_colour);
559
560         int i = ColoursSearchEntry( col );
561         // change topline only if necessary
562         // int top = fl_get_browser_topline(colours_->browser_x11);
563         // if(i < top || i > (top+15))
564         fl_set_browser_topline(colours_->browser_x11, i-5);
565         fl_select_browser_line(colours_->browser_x11, i + 1);
566
567         fl_unfreeze_form(colours_->form);
568 }
569
570
571 void FormPreferences::updateColours()
572 {
573 }
574
575
576 void FormPreferences::applyConverters() const
577 {
578 }
579
580
581 void FormPreferences::buildConverters()
582 {
583         converters_ = build_converters();
584
585 }
586
587
588 string FormPreferences::feedbackConverters( FL_OBJECT const * const ) const
589 {
590         return string();
591 }
592
593
594 void FormPreferences::updateConverters()
595 {
596 }
597
598
599 void FormPreferences::applyFormats() const
600 {
601 }
602
603
604 void FormPreferences::buildFormats()
605 {
606         formats_ = build_formats();
607
608         fl_set_input_return(formats_->input_format, FL_RETURN_CHANGED);
609         fl_set_input_return(formats_->input_viewer, FL_RETURN_CHANGED);
610         fl_set_input_return(formats_->input_gui_name, FL_RETURN_CHANGED);
611         fl_set_input_return(formats_->input_extension, FL_RETURN_CHANGED);
612
613         fl_set_input_filter(formats_->input_format, fl_lowercase_filter);
614 }
615
616
617 string FormPreferences::feedbackFormats( FL_OBJECT const * const ) const
618 {
619         string str;
620
621         return str;
622 }
623
624
625 bool FormPreferences::inputFormats( FL_OBJECT const * const )
626 {
627         return true;
628 }
629
630
631 void FormPreferences::updateFormats()
632 {
633 }
634
635
636 void FormPreferences::applyInputsMisc() const
637 {
638         lyxrc.date_insert_format = fl_get_input(inputs_misc_->input_date_format);
639 }
640
641
642 void FormPreferences::buildInputsMisc()
643 {
644         inputs_misc_ = build_inputs_misc();
645
646         fl_set_input_return(inputs_misc_->input_date_format,
647                             FL_RETURN_CHANGED);
648
649         // set up the feedback mechanism
650         fl_addto_form(inputs_misc_->form);
651
652         setPostHandler( inputs_misc_->input_date_format );
653
654         fl_end_form();
655 }
656
657
658 string FormPreferences::feedbackInputsMisc( FL_OBJECT const * const ob ) const
659 {
660         string str;
661
662         if( ob == inputs_misc_->input_date_format )
663                 str = lyxrc.getDescription( LyXRC::RC_DATE_INSERT_FORMAT );
664
665         return str;
666 }
667
668
669 void FormPreferences::updateInputsMisc()
670 {
671         fl_set_input(inputs_misc_->input_date_format,
672                      lyxrc.date_insert_format.c_str());
673 }
674
675
676 void FormPreferences::applyInterface() const
677 {
678         lyxrc.popup_font_name =
679                 fl_get_input(interface_->input_popup_font);
680         lyxrc.menu_font_name = fl_get_input(interface_->input_menu_font);
681         lyxrc.font_norm_menu =
682                 fl_get_input(interface_->input_popup_encoding);
683         lyxrc.bind_file = fl_get_input(interface_->input_bind_file);
684         lyxrc.ui_file = fl_get_input(interface_->input_ui_file);
685         lyxrc.override_x_deadkeys =
686                 fl_get_button(interface_->check_override_x_dead_keys);
687 }
688
689
690 void FormPreferences::buildInterface()
691 {
692         interface_ = build_interface();
693
694         fl_set_input_return(interface_->input_popup_font, FL_RETURN_CHANGED);
695         fl_set_input_return(interface_->input_menu_font, FL_RETURN_CHANGED);
696         fl_set_input_return(interface_->input_popup_encoding, 
697                             FL_RETURN_CHANGED);
698         fl_set_input_return(interface_->input_bind_file, FL_RETURN_CHANGED);
699         fl_set_input_return(interface_->input_ui_file, FL_RETURN_CHANGED);
700
701         // deactivate the browse buttons because they aren't implemented
702         fl_deactivate_object(interface_->button_bind_file_browse);
703         fl_deactivate_object(interface_->button_ui_file_browse);
704         fl_set_object_lcol(interface_->button_bind_file_browse, FL_INACTIVE);
705         fl_set_object_lcol(interface_->button_ui_file_browse, FL_INACTIVE);
706
707         // set up the feedback mechanism
708         fl_addto_form(interface_->form);
709
710         setPostHandler( interface_->input_popup_font );
711         setPostHandler( interface_->input_menu_font );
712         setPostHandler( interface_->input_popup_encoding );
713         setPostHandler( interface_->input_bind_file );
714         setPostHandler( interface_->button_bind_file_browse );
715         setPostHandler( interface_->input_ui_file );
716         setPostHandler( interface_->button_ui_file_browse );
717         setPostHandler( interface_->check_override_x_dead_keys );
718
719         fl_end_form();
720 }
721
722
723
724 string FormPreferences::feedbackInterface( FL_OBJECT const * const ob ) const
725 {
726         string str;
727
728         if( ob == interface_->input_popup_font )
729                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_POPUP );
730         else if ( ob == interface_->input_menu_font )
731                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_MENU );
732         else if ( ob == interface_->input_popup_encoding )
733                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ENCODING_MENU );
734         else if ( ob == interface_->input_bind_file )
735                 str = lyxrc.getDescription( LyXRC::RC_BINDFILE );
736         else if ( ob == interface_->input_ui_file )
737                 str = lyxrc.getDescription( LyXRC::RC_UIFILE );
738         else if ( ob == interface_->check_override_x_dead_keys )
739                 str = lyxrc.getDescription( LyXRC::RC_OVERRIDE_X_DEADKEYS );
740
741         return str;
742 }
743
744
745 void FormPreferences::updateInterface()
746 {
747         fl_set_input(interface_->input_popup_font,
748                      lyxrc.popup_font_name.c_str());
749         fl_set_input(interface_->input_menu_font,
750                      lyxrc.menu_font_name.c_str());
751         fl_set_input(interface_->input_popup_encoding,
752                      lyxrc.font_norm_menu.c_str());
753         fl_set_input(interface_->input_bind_file,
754                      lyxrc.bind_file.c_str());
755         fl_set_input(interface_->input_ui_file,
756                      lyxrc.ui_file.c_str());
757         fl_set_button(interface_->check_override_x_dead_keys,
758                       lyxrc.override_x_deadkeys);
759 }
760
761
762 void FormPreferences::applyLanguage() const
763 {
764         lyxrc.default_language = combo_default_lang->getline();
765
766         int button = fl_get_button(language_->check_use_kbmap);
767         lyxrc.use_kbmap = static_cast<bool>(button);
768
769         if( button ) {
770             lyxrc.primary_kbmap = combo_kbmap_1->getline();
771             lyxrc.secondary_kbmap = combo_kbmap_2->getline();
772         }
773         
774         button = fl_get_button(language_->check_rtl_support);
775         lyxrc.rtl_support = static_cast<bool>(button);
776
777         button = fl_get_button(language_->check_auto_begin);
778         lyxrc.language_auto_begin = static_cast<bool>(button);
779
780         button = fl_get_button(language_->check_auto_end);
781         lyxrc.language_auto_end = static_cast<bool>(button);
782
783         button = fl_get_button(language_->check_mark_foreign);
784         lyxrc.mark_foreign_language = static_cast<bool>(button);
785
786         lyxrc.language_package = fl_get_input(language_->input_package);
787         lyxrc.language_command_begin = fl_get_input(language_->input_command_begin);
788         lyxrc.language_command_end = fl_get_input(language_->input_command_end);
789 }
790
791
792 void FormPreferences::buildLanguage()
793 {
794         language_ = build_language();
795
796         fl_set_input_return(language_->input_package, FL_RETURN_CHANGED);
797         fl_set_input_return(language_->input_command_begin, FL_RETURN_CHANGED);
798         fl_set_input_return(language_->input_command_end, FL_RETURN_CHANGED);
799
800         // The default_language is a combo-box and has to be inserted manually
801         fl_freeze_form(language_->form);
802         fl_addto_form(language_->form);
803
804         FL_OBJECT * obj = language_->choice_default_lang;
805         fl_deactivate_object(language_->choice_default_lang);
806         combo_default_lang = new Combox(FL_COMBOX_DROPLIST);
807         combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400);
808         combo_default_lang->shortcut("#L",1);
809         combo_default_lang->setcallback(ComboLanguageCB, this);
810         LanguagesAdd( *combo_default_lang );
811         
812         // ditto kbmap_1
813         obj = language_->choice_kbmap_1;
814         fl_deactivate_object(language_->choice_kbmap_1);
815         combo_kbmap_1 = new Combox(FL_COMBOX_DROPLIST);
816         combo_kbmap_1->add(obj->x, obj->y, obj->w, obj->h, 400);
817         combo_kbmap_1->shortcut("#1",1);
818         combo_kbmap_1->setcallback(ComboLanguageCB, this);
819         LanguagesAdd( *combo_kbmap_1 );
820         
821         // ditto kbmap_2
822         obj = language_->choice_kbmap_2;
823         fl_deactivate_object(language_->choice_kbmap_2);
824         combo_kbmap_2 = new Combox(FL_COMBOX_DROPLIST);
825         combo_kbmap_2->add(obj->x, obj->y, obj->w, obj->h, 400);
826         combo_kbmap_2->shortcut("#2",1);
827         combo_kbmap_2->setcallback(ComboLanguageCB, this);
828         LanguagesAdd( *combo_kbmap_2 );
829
830         fl_end_form();
831         fl_unfreeze_form(language_->form);
832
833         // set up the feedback mechanism
834         fl_addto_form(language_->form);
835
836         setPostHandler( language_->input_package );
837         setPostHandler( language_->check_use_kbmap );
838
839         // This is safe, as nothing is done to the pointer, other than
840         // to use its address in a block-if statement.
841         //setPostHandler( reinterpret_cast<FL_OBJECT *>(combo_default_lang) );
842         //setPostHandler( reinterpret_cast<FL_OBJECT *>(combo_kbmap_1) );
843         //setPostHandler( reinterpret_cast<FL_OBJECT *>(combo_kbmap_2) );
844
845         setPostHandler( language_->check_rtl_support );
846         setPostHandler( language_->check_mark_foreign );
847         setPostHandler( language_->check_auto_begin );
848         setPostHandler( language_->check_auto_end );
849         setPostHandler( language_->input_command_begin );
850         setPostHandler( language_->input_command_end );
851
852         fl_end_form();
853 }
854
855
856 string FormPreferences::feedbackLanguage( FL_OBJECT const * const ob ) const
857 {
858         string str;
859
860         if( reinterpret_cast<Combox const *>(ob) == combo_default_lang )
861                 str = lyxrc.getDescription( LyXRC::RC_DEFAULT_LANGUAGE );
862         else if( ob == language_->check_use_kbmap )
863                 str = lyxrc.getDescription( LyXRC::RC_KBMAP );
864         else if( reinterpret_cast<Combox const *>(ob) == combo_kbmap_1)
865                 str = lyxrc.getDescription( LyXRC::RC_KBMAP_PRIMARY );
866         else if( reinterpret_cast<Combox const *>(ob) == combo_kbmap_2 )
867                 str = lyxrc.getDescription( LyXRC::RC_KBMAP_SECONDARY );
868         else if( ob == language_->check_rtl_support )
869                 str = lyxrc.getDescription( LyXRC::RC_RTL_SUPPORT );
870         else if( ob == language_->check_auto_begin )
871                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_AUTO_BEGIN );
872         else if( ob == language_->check_auto_end )
873                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_AUTO_END );
874         else if( ob == language_->check_mark_foreign )
875                 str = lyxrc.getDescription( LyXRC::RC_MARK_FOREIGN_LANGUAGE );
876         else if( ob == language_->input_package )
877                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_PACKAGE );
878         else if( ob == language_->input_command_begin )
879                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_COMMAND_BEGIN );
880         else if( ob == language_->input_command_end )
881                 str = lyxrc.getDescription( LyXRC::RC_LANGUAGE_COMMAND_END );
882
883         return str;
884 }
885
886
887 bool FormPreferences::inputLanguage( FL_OBJECT const * const ob )
888 {
889         bool activate = true;
890
891         if( !ob || ob == language_->check_use_kbmap ) {
892                 if( fl_get_button(language_->check_use_kbmap) ) {
893                         combo_kbmap_1->activate();
894                         combo_kbmap_2->activate();
895                 } else {
896                         combo_kbmap_1->deactivate();
897                         combo_kbmap_2->deactivate();
898                 }
899         }
900
901         return activate;
902 }
903
904
905 void FormPreferences::updateLanguage()
906 {
907         fl_set_button(language_->check_use_kbmap,
908                       lyxrc.use_kbmap);
909
910         combo_default_lang->select_text( lyxrc.default_language );
911
912         if( lyxrc.use_kbmap ) {
913                 combo_kbmap_1->select_text( lyxrc.primary_kbmap );
914                 combo_kbmap_2->select_text( lyxrc.secondary_kbmap );
915         } else {
916                 combo_kbmap_1->select_text( lyxrc.default_language );
917                 combo_kbmap_2->select_text( lyxrc.default_language );
918         }
919         
920         fl_set_button(language_->check_rtl_support, lyxrc.rtl_support);
921         fl_set_button(language_->check_auto_begin,  lyxrc.language_auto_begin);
922         fl_set_button(language_->check_auto_end,    lyxrc.language_auto_end);
923         fl_set_button(language_->check_mark_foreign,
924                       lyxrc.mark_foreign_language);
925
926         fl_set_input(language_->input_package,
927                      lyxrc.language_package.c_str());
928         fl_set_input(language_->input_command_begin,
929                      lyxrc.language_command_begin.c_str());
930         fl_set_input(language_->input_command_end,
931                      lyxrc.language_command_end.c_str());
932
933         // Activate/Deactivate the input fields dependent on the state of the
934         // buttons.
935         inputLanguage( 0 );
936 }
937
938
939 void FormPreferences::LanguagesAdd( Combox & combo ) const
940 {
941         for(Languages::const_iterator cit = languages.begin();
942             cit != languages.end(); cit++) {
943                 combo.addto((*cit).second.lang());
944         }
945 }
946
947
948 void FormPreferences::applyLnFmisc() const
949 {
950         lyxrc.show_banner = fl_get_button(lnf_misc_->check_banner);
951         lyxrc.auto_region_delete = fl_get_button(lnf_misc_->
952                                                  check_auto_region_delete);
953         lyxrc.exit_confirmation = fl_get_button(lnf_misc_->check_exit_confirm);
954         lyxrc.display_shortcuts =
955                 fl_get_button(lnf_misc_->check_display_shortcuts);
956         lyxrc.new_ask_filename = fl_get_button(lnf_misc_->check_ask_new_file);
957         lyxrc.cursor_follows_scrollbar =
958                 fl_get_button(lnf_misc_->check_cursor_follows_scrollbar);
959         lyxrc.autosave = static_cast<unsigned int>
960                 (fl_get_counter_value(lnf_misc_->counter_autosave));
961         lyxrc.wheel_jump = static_cast<unsigned int>
962                 (fl_get_counter_value(lnf_misc_->counter_wm_jump));
963 }
964
965
966 void FormPreferences::buildLnFmisc()
967 {
968         lnf_misc_ = build_lnf_misc();
969
970         fl_set_counter_return(lnf_misc_->counter_autosave,
971                               FL_RETURN_CHANGED);
972         fl_set_counter_return(lnf_misc_->counter_wm_jump,
973                               FL_RETURN_CHANGED);
974
975         // set up the feedback mechanism
976         fl_addto_form(lnf_misc_->form);
977
978         setPostHandler( lnf_misc_->check_banner );
979         setPostHandler( lnf_misc_->check_auto_region_delete );
980         setPostHandler( lnf_misc_->check_exit_confirm );
981         setPostHandler( lnf_misc_->check_display_shortcuts );
982         setPostHandler( lnf_misc_->counter_autosave );
983         setPostHandler( lnf_misc_->check_ask_new_file );
984         setPostHandler( lnf_misc_->check_cursor_follows_scrollbar );
985         setPostHandler( lnf_misc_->counter_wm_jump );
986
987         fl_end_form();
988 }
989
990
991 string FormPreferences::feedbackLnFmisc( FL_OBJECT const * const ob ) const
992 {
993         string str;
994
995         if( ob == lnf_misc_->check_banner )
996                 str = lyxrc.getDescription( LyXRC::RC_SHOW_BANNER );
997         else if( ob == lnf_misc_->check_auto_region_delete )
998                 str = lyxrc.getDescription( LyXRC::RC_AUTOREGIONDELETE );
999         else if( ob == lnf_misc_->check_exit_confirm )
1000                 str = lyxrc.getDescription( LyXRC::RC_EXIT_CONFIRMATION );
1001         else if( ob == lnf_misc_->check_display_shortcuts )
1002                 str = lyxrc.getDescription( LyXRC::RC_DISPLAY_SHORTCUTS );
1003         else if( ob == lnf_misc_->check_ask_new_file )
1004                 str = lyxrc.getDescription( LyXRC::RC_NEW_ASK_FILENAME );
1005         else if( ob == lnf_misc_->check_cursor_follows_scrollbar )
1006                 str = lyxrc.getDescription( LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR );
1007         else if( ob == lnf_misc_->counter_autosave )
1008                 str = lyxrc.getDescription( LyXRC::RC_AUTOSAVE );
1009         else if( ob == lnf_misc_->counter_wm_jump )
1010                 str = lyxrc.getDescription( LyXRC::RC_WHEEL_JUMP );
1011
1012         return str;
1013 }
1014
1015 void FormPreferences::updateLnFmisc()
1016 {
1017         fl_set_button(lnf_misc_->check_banner,
1018                       lyxrc.show_banner);
1019         fl_set_button(lnf_misc_->check_auto_region_delete,
1020                       lyxrc.auto_region_delete);
1021         fl_set_button(lnf_misc_->check_exit_confirm,
1022                       lyxrc.exit_confirmation);
1023         fl_set_button(lnf_misc_->check_display_shortcuts,
1024                       lyxrc.display_shortcuts);
1025         fl_set_button(lnf_misc_->check_ask_new_file,
1026                       lyxrc.new_ask_filename);
1027         fl_set_button(lnf_misc_->check_cursor_follows_scrollbar,
1028                       lyxrc.cursor_follows_scrollbar);
1029         fl_set_counter_value(lnf_misc_->counter_autosave,
1030                              lyxrc.autosave);
1031         fl_set_counter_value(lnf_misc_->counter_wm_jump,
1032                              lyxrc.wheel_jump);
1033 }
1034
1035
1036 void FormPreferences::applyOutputsMisc() const
1037 {
1038         lyxrc.ascii_linelen = static_cast<unsigned int>
1039                 (fl_get_counter_value(outputs_misc_->counter_line_len));
1040         lyxrc.fontenc = fl_get_input(outputs_misc_->input_tex_encoding);
1041
1042         int choice =
1043                 fl_get_choice(outputs_misc_->choice_default_papersize) - 1;
1044         lyxrc.default_papersize = static_cast<BufferParams::PAPER_SIZE>(choice);
1045
1046         lyxrc.ascii_roff_command = fl_get_input(outputs_misc_->input_ascii_roff);
1047         lyxrc.chktex_command = fl_get_input(outputs_misc_->input_checktex);
1048 }
1049
1050
1051 void FormPreferences::buildOutputsMisc()
1052 {
1053         outputs_misc_ = build_outputs_misc();
1054
1055         fl_set_counter_return(outputs_misc_->counter_line_len,
1056                               FL_RETURN_CHANGED);
1057         fl_set_input_return(outputs_misc_->input_tex_encoding,
1058                             FL_RETURN_CHANGED);
1059         fl_set_input_return(outputs_misc_->input_ascii_roff,
1060                             FL_RETURN_CHANGED);
1061         fl_set_input_return(outputs_misc_->input_checktex,
1062                             FL_RETURN_CHANGED);
1063         fl_addto_choice(outputs_misc_->choice_default_papersize,
1064                         _(" default | US letter | legal | executive | A3 | A4 | A5 | B5 "));
1065
1066         // set up the feedback mechanism
1067         fl_addto_form(outputs_misc_->form);
1068
1069         setPostHandler( outputs_misc_->counter_line_len );
1070         setPostHandler( outputs_misc_->input_tex_encoding );
1071         setPostHandler( outputs_misc_->choice_default_papersize );
1072         setPostHandler( outputs_misc_->input_ascii_roff );
1073         setPostHandler( outputs_misc_->input_checktex );
1074
1075         fl_end_form();
1076 }
1077
1078
1079 string FormPreferences::feedbackOutputsMisc(FL_OBJECT const * const ob ) const
1080 {
1081         string str;
1082
1083         if( ob == outputs_misc_->counter_line_len )
1084                 str = lyxrc.getDescription( LyXRC::RC_ASCII_LINELEN );
1085         else if( ob == outputs_misc_->input_tex_encoding )
1086                 str = lyxrc.getDescription( LyXRC::RC_FONT_ENCODING );
1087         else if( ob == outputs_misc_->input_ascii_roff )
1088                 str = lyxrc.getDescription( LyXRC::RC_ASCIIROFF_COMMAND );
1089         else if( ob == outputs_misc_->input_checktex )
1090                 str = lyxrc.getDescription( LyXRC::RC_CHKTEX_COMMAND );
1091         else if( ob == outputs_misc_->choice_default_papersize )
1092                 str = lyxrc.getDescription( LyXRC::RC_DEFAULT_PAPERSIZE );
1093
1094         return str;
1095 }
1096
1097
1098 void FormPreferences::updateOutputsMisc()
1099 {
1100         fl_set_counter_value(outputs_misc_->counter_line_len,
1101                              lyxrc.ascii_linelen);
1102         fl_set_input(outputs_misc_->input_tex_encoding,
1103                      lyxrc.fontenc.c_str());
1104         fl_set_choice(outputs_misc_->choice_default_papersize,
1105                       lyxrc.default_papersize+1);
1106         fl_set_input(outputs_misc_->input_ascii_roff,
1107                      lyxrc.ascii_roff_command.c_str());
1108         fl_set_input(outputs_misc_->input_checktex,
1109                      lyxrc.chktex_command.c_str());
1110 }
1111
1112
1113 void FormPreferences::applyPaths()
1114 {
1115         lyxrc.document_path = fl_get_input(paths_->input_default_path);
1116         lyxrc.template_path = fl_get_input(paths_->input_template_path);
1117
1118         int button = fl_get_button(paths_->check_use_temp_dir);
1119         string str  = fl_get_input(paths_->input_temp_dir);
1120         if( !button ) str.erase();
1121
1122         lyxrc.use_tempdir = button;
1123         lyxrc.tempdir_path = str;
1124
1125         button = fl_get_button(paths_->check_last_files);
1126         str = fl_get_input(paths_->input_lastfiles);
1127         if( !button ) str.erase();
1128         
1129         lyxrc.check_lastfiles = button;
1130         lyxrc.lastfiles = str;
1131         lyxrc.num_lastfiles = static_cast<unsigned int>
1132                 (fl_get_counter_value(paths_->counter_lastfiles));
1133
1134         button = fl_get_button(paths_->check_make_backups);
1135         str = fl_get_input(paths_->input_backup_path);
1136         if( !button ) str.erase();
1137
1138         lyxrc.make_backup = button;
1139         lyxrc.backupdir_path = str;
1140
1141         lyxrc.lyxpipes = fl_get_input(paths_->input_serverpipe);
1142
1143         // update view
1144         updatePaths();
1145 }
1146
1147
1148 void FormPreferences::buildPaths()
1149 {
1150         paths_ = build_paths();
1151
1152         fl_set_input_return(paths_->input_default_path, FL_RETURN_CHANGED);
1153         fl_set_input_return(paths_->input_template_path, FL_RETURN_CHANGED);
1154         fl_set_input_return(paths_->input_temp_dir, FL_RETURN_CHANGED);
1155         fl_set_input_return(paths_->input_lastfiles, FL_RETURN_CHANGED);
1156         fl_set_input_return(paths_->input_backup_path, FL_RETURN_CHANGED);
1157         fl_set_counter_return(paths_->counter_lastfiles, FL_RETURN_CHANGED);
1158         fl_set_input_return(paths_->input_serverpipe, FL_RETURN_CHANGED);
1159
1160         // deactivate the browse buttons because they aren't implemented
1161         fl_deactivate_object(paths_->button_document_browse);
1162         fl_deactivate_object(paths_->button_template_browse);
1163         fl_deactivate_object(paths_->button_temp_dir_browse);
1164         fl_deactivate_object(paths_->button_lastfiles_browse);
1165         fl_deactivate_object(paths_->button_backup_path_browse);
1166         fl_deactivate_object(paths_->button_serverpipe_browse);
1167         fl_set_object_lcol(paths_->button_document_browse, FL_INACTIVE);
1168         fl_set_object_lcol(paths_->button_template_browse, FL_INACTIVE);
1169         fl_set_object_lcol(paths_->button_temp_dir_browse, FL_INACTIVE);
1170         fl_set_object_lcol(paths_->button_lastfiles_browse, FL_INACTIVE);
1171         fl_set_object_lcol(paths_->button_backup_path_browse, FL_INACTIVE);
1172         fl_set_object_lcol(paths_->button_serverpipe_browse, FL_INACTIVE);
1173
1174         // set up the feedback mechanism
1175         fl_addto_form(paths_->form);
1176
1177         setPostHandler( paths_->input_default_path );
1178         setPostHandler( paths_->button_document_browse );
1179         setPostHandler( paths_->counter_lastfiles );
1180         setPostHandler( paths_->input_template_path );
1181         setPostHandler( paths_->button_template_browse );
1182         setPostHandler( paths_->check_last_files );
1183         setPostHandler( paths_->button_temp_dir_browse );
1184         setPostHandler( paths_->input_lastfiles );
1185         setPostHandler( paths_->button_lastfiles_browse );
1186         setPostHandler( paths_->check_make_backups );
1187         setPostHandler( paths_->input_backup_path );
1188         setPostHandler( paths_->button_backup_path_browse );
1189         setPostHandler( paths_->input_serverpipe );
1190         setPostHandler( paths_->button_serverpipe_browse );
1191         setPostHandler( paths_->input_temp_dir );
1192         setPostHandler( paths_->check_use_temp_dir );
1193
1194         fl_end_form();
1195 }
1196
1197
1198 string FormPreferences::feedbackPaths( FL_OBJECT const * const ob ) const
1199 {
1200         string str;
1201
1202         if( ob == paths_->input_default_path )
1203                 str = lyxrc.getDescription( LyXRC::RC_DOCUMENTPATH );
1204         else if ( ob == paths_->input_template_path )
1205                 str = lyxrc.getDescription( LyXRC::RC_TEMPLATEPATH );
1206         else if ( ob == paths_->check_use_temp_dir )
1207                 str = lyxrc.getDescription( LyXRC::RC_USETEMPDIR );
1208         else if ( ob == paths_->input_temp_dir )
1209                 str = lyxrc.getDescription( LyXRC::RC_TEMPDIRPATH );
1210         else if ( ob == paths_->check_last_files )
1211                 str = lyxrc.getDescription( LyXRC::RC_CHECKLASTFILES );
1212         else if ( ob == paths_->input_lastfiles )
1213                 str = lyxrc.getDescription( LyXRC::RC_LASTFILES );
1214         else if ( ob == paths_->counter_lastfiles )
1215                 str = lyxrc.getDescription( LyXRC::RC_NUMLASTFILES );
1216         else if ( ob == paths_->check_make_backups )
1217                 str = lyxrc.getDescription( LyXRC::RC_MAKE_BACKUP );
1218         else if ( ob == paths_->input_backup_path )
1219                 str = lyxrc.getDescription( LyXRC::RC_BACKUPDIR_PATH );
1220         else if ( ob == paths_->input_serverpipe )
1221                 str = lyxrc.getDescription( LyXRC::RC_SERVERPIPE );
1222
1223         return str;
1224 }
1225
1226
1227 bool FormPreferences::inputPaths( FL_OBJECT const * const ob )
1228 {
1229         bool activate = true;
1230         
1231         if( !ob || ob == paths_->check_use_temp_dir ) {
1232                 if( fl_get_button(paths_->check_use_temp_dir) ) {
1233                         fl_activate_object(paths_->input_temp_dir);
1234                         fl_set_object_lcol(paths_->input_temp_dir,
1235                                            FL_BLACK);
1236                 } else {
1237                         fl_deactivate_object(paths_->input_temp_dir);
1238                         fl_set_object_lcol(paths_->input_temp_dir,
1239                                            FL_INACTIVE);
1240                 }
1241         }
1242
1243         if( !ob || ob == paths_->check_last_files ) {
1244                 if( fl_get_button(paths_->check_last_files) ) {
1245                         fl_activate_object(paths_->input_lastfiles);
1246                         fl_set_object_lcol(paths_->input_lastfiles,
1247                                            FL_BLACK);
1248                 } else {
1249                         fl_deactivate_object(paths_->input_lastfiles);
1250                         fl_set_object_lcol(paths_->input_lastfiles,
1251                                            FL_INACTIVE);
1252                 }
1253         }
1254
1255         if( !ob || ob == paths_->check_make_backups ) {
1256                 if( fl_get_button(paths_->check_make_backups) ) {
1257                         fl_activate_object(paths_->input_backup_path);
1258                         fl_set_object_lcol(paths_->input_backup_path,
1259                                            FL_BLACK);
1260                 } else {
1261                         fl_deactivate_object(paths_->input_backup_path);
1262                         fl_set_object_lcol(paths_->input_backup_path,
1263                                            FL_INACTIVE);
1264                 }
1265         }
1266
1267         if( !ob || ob == paths_->input_default_path ) {
1268                 string name = fl_get_input(paths_->input_default_path);
1269                 if( !WriteableDir(name) )
1270                         return false;
1271         }
1272
1273         if( !ob || ob == paths_->input_template_path ) {
1274                 string name = fl_get_input(paths_->input_template_path);
1275                 if( !ReadableDir(name) )
1276                     return false;
1277         }
1278
1279         if( !ob || ob == paths_->input_temp_dir ) {
1280                 string name = fl_get_input(paths_->input_temp_dir);
1281                 if( fl_get_button(paths_->check_make_backups)
1282                     && !name.empty()
1283                     && !WriteableDir(name) )
1284                         return false;
1285         }
1286
1287         if( !ob || ob == paths_->input_backup_path ) {
1288                 string name = fl_get_input(paths_->input_backup_path);
1289                 if( fl_get_button(paths_->check_make_backups)
1290                     && !name.empty()
1291                     && !WriteableDir(name) )
1292                         return false;
1293         }
1294
1295         if( !ob || ob == paths_->input_lastfiles ) {
1296                 string name = fl_get_input(paths_->input_lastfiles);
1297                 if( fl_get_button(paths_->check_last_files)
1298                     && !name.empty()
1299                     && !WriteableFile(name) )
1300                         return false;
1301         }
1302
1303         if( !ob || ob == paths_->input_serverpipe ) {
1304                 string name = fl_get_input(paths_->input_serverpipe);
1305                 if( !name.empty() ) {
1306                         if( !WriteableFile(name, ".in") )
1307                                 return false;
1308                         if( !WriteableFile(name, ".out") )
1309                                 return false;
1310                 }
1311         }
1312
1313         return activate;
1314 }
1315
1316
1317 void FormPreferences::updatePaths()
1318 {
1319         fl_set_input(paths_->input_default_path,
1320                      lyxrc.document_path.c_str());
1321         fl_set_input(paths_->input_template_path,
1322                      lyxrc.template_path.c_str());
1323
1324         string str = string();
1325         if( lyxrc.make_backup ) str = lyxrc.backupdir_path;
1326
1327         fl_set_button(paths_->check_make_backups,
1328                       lyxrc.make_backup);
1329         fl_set_input(paths_->input_backup_path, str.c_str());
1330
1331         str.erase();
1332         if( lyxrc.use_tempdir ) str = lyxrc.tempdir_path;
1333
1334         fl_set_button(paths_->check_use_temp_dir,
1335                       lyxrc.use_tempdir);
1336         fl_set_input(paths_->input_temp_dir, str.c_str());
1337
1338         str.erase();
1339         if( lyxrc.check_lastfiles ) str = lyxrc.lastfiles;
1340
1341         fl_set_button(paths_->check_last_files,
1342                       lyxrc.check_lastfiles);           
1343         fl_set_input(paths_->input_lastfiles, str.c_str());
1344         fl_set_counter_value(paths_->counter_lastfiles,
1345                              lyxrc.num_lastfiles);
1346
1347         fl_set_input(paths_->input_serverpipe, lyxrc.lyxpipes.c_str());
1348
1349         // Activate/Deactivate the input fields dependent on the state of the
1350         // buttons.
1351         inputPaths( 0 );
1352 }
1353
1354
1355 void FormPreferences::applyPrinter() const
1356 {
1357         lyxrc.print_adapt_output = fl_get_button(printer_->check_adapt_output);
1358         lyxrc.print_command = fl_get_input(printer_->input_command);
1359         lyxrc.print_pagerange_flag = fl_get_input(printer_->input_page_range);
1360         lyxrc.print_copies_flag = fl_get_input(printer_->input_copies);
1361         lyxrc.print_reverse_flag = fl_get_input(printer_->input_reverse);
1362         lyxrc.print_to_printer = fl_get_input(printer_->input_to_printer);
1363         lyxrc.print_file_extension =
1364                 fl_get_input(printer_->input_file_extension);
1365         lyxrc.print_spool_command =
1366                 fl_get_input(printer_->input_spool_command);
1367         lyxrc.print_paper_flag = fl_get_input(printer_->input_paper_type);
1368         lyxrc.print_evenpage_flag = fl_get_input(printer_->input_even_pages);
1369         lyxrc.print_oddpage_flag = fl_get_input(printer_->input_odd_pages);
1370         lyxrc.print_collcopies_flag = fl_get_input(printer_->input_collated);
1371         lyxrc.print_landscape_flag = fl_get_input(printer_->input_landscape);
1372         lyxrc.print_to_file = fl_get_input(printer_->input_to_file);
1373         lyxrc.print_extra_options =
1374                 fl_get_input(printer_->input_extra_options);
1375         lyxrc.print_spool_printerprefix =
1376                 fl_get_input(printer_->input_spool_prefix);
1377         lyxrc.print_paper_dimension_flag =
1378                 fl_get_input(printer_->input_paper_size);
1379         lyxrc.printer = fl_get_input(printer_->input_name);
1380 }
1381
1382
1383 string FormPreferences::feedbackPrinter( FL_OBJECT const * const ob ) const
1384 {
1385         string str;
1386
1387         if( ob == printer_->input_command )
1388                 str = lyxrc.getDescription( LyXRC::RC_PRINT_COMMAND );
1389         else if( ob == printer_->check_adapt_output )
1390                 str = lyxrc.getDescription( LyXRC::RC_PRINT_ADAPTOUTPUT );
1391         else if( ob == printer_->input_to_printer )
1392                 str = lyxrc.getDescription( LyXRC::RC_PRINTTOPRINTER );
1393         else if( ob == printer_->input_to_file )
1394                 str = lyxrc.getDescription( LyXRC::RC_PRINTTOFILE );
1395         else if( ob == printer_->input_file_extension )
1396                 str = lyxrc.getDescription( LyXRC::RC_PRINTFILEEXTENSION );
1397         else if( ob == printer_->input_extra_options )
1398                 str = lyxrc.getDescription( LyXRC::RC_PRINTEXSTRAOPTIONS );
1399         else if( ob == printer_->input_spool_command )
1400                 str = lyxrc.getDescription( LyXRC::RC_PRINTSPOOL_COMMAND );
1401         else if( ob == printer_->input_spool_prefix )
1402                 str = lyxrc.getDescription( LyXRC::RC_PRINTSPOOL_PRINTERPREFIX );
1403         else if( ob == printer_->input_name )
1404                 str = lyxrc.getDescription( LyXRC::RC_PRINTER );
1405         else if( ob == printer_->input_even_pages )
1406                 str = lyxrc.getDescription( LyXRC::RC_PRINTEVENPAGEFLAG );
1407         else if( ob == printer_->input_odd_pages )
1408                 str = lyxrc.getDescription( LyXRC::RC_PRINTODDPAGEFLAG );
1409         else if( ob == printer_->input_page_range )
1410                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAGERANGEFLAG );
1411         else if( ob == printer_->input_reverse )
1412                 str = lyxrc.getDescription( LyXRC::RC_PRINTREVERSEFLAG );
1413         else if( ob == printer_->input_landscape )
1414                 str = lyxrc.getDescription( LyXRC::RC_PRINTLANDSCAPEFLAG );
1415         else if( ob == printer_->input_copies )
1416                 str = lyxrc.getDescription( LyXRC::RC_PRINTCOLLCOPIESFLAG );
1417         else if( ob == printer_->input_collated )
1418                 str = lyxrc.getDescription( LyXRC::RC_PRINTCOPIESFLAG );
1419         else if( ob == printer_->input_paper_type )
1420                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAPERFLAG );
1421         else if( ob == printer_->input_paper_size )
1422                 str = lyxrc.getDescription( LyXRC::RC_PRINTPAPERDIMENSIONFLAG );
1423
1424         return str;
1425 }
1426
1427
1428 void FormPreferences::buildPrinter()
1429 {
1430         printer_ = build_printer();
1431
1432         fl_set_input_return(printer_->input_command, FL_RETURN_CHANGED);
1433         fl_set_input_return(printer_->input_page_range, FL_RETURN_CHANGED);
1434         fl_set_input_return(printer_->input_copies, FL_RETURN_CHANGED);
1435         fl_set_input_return(printer_->input_reverse, FL_RETURN_CHANGED);
1436         fl_set_input_return(printer_->input_to_printer, FL_RETURN_CHANGED);
1437         fl_set_input_return(printer_->input_file_extension, FL_RETURN_CHANGED);
1438         fl_set_input_return(printer_->input_spool_command, FL_RETURN_CHANGED);
1439         fl_set_input_return(printer_->input_paper_type, FL_RETURN_CHANGED);
1440         fl_set_input_return(printer_->input_even_pages, FL_RETURN_CHANGED);
1441         fl_set_input_return(printer_->input_odd_pages, FL_RETURN_CHANGED);
1442         fl_set_input_return(printer_->input_collated, FL_RETURN_CHANGED);
1443         fl_set_input_return(printer_->input_landscape, FL_RETURN_CHANGED);
1444         fl_set_input_return(printer_->input_to_file, FL_RETURN_CHANGED);
1445         fl_set_input_return(printer_->input_extra_options, FL_RETURN_CHANGED);
1446         fl_set_input_return(printer_->input_spool_prefix, FL_RETURN_CHANGED);
1447         fl_set_input_return(printer_->input_paper_size, FL_RETURN_CHANGED);
1448         fl_set_input_return(printer_->input_name, FL_RETURN_CHANGED);
1449
1450         // set up the feedback mechanism
1451         fl_addto_form(printer_->form);
1452
1453         setPostHandler( printer_->input_command );
1454         setPostHandler( printer_->input_page_range );
1455         setPostHandler( printer_->input_copies );
1456         setPostHandler( printer_->input_reverse );
1457         setPostHandler( printer_->input_to_printer );
1458         setPostHandler( printer_->input_file_extension );
1459         setPostHandler( printer_->input_spool_command );
1460         setPostHandler( printer_->input_paper_type );
1461         setPostHandler( printer_->input_even_pages );
1462         setPostHandler( printer_->input_odd_pages );
1463         setPostHandler( printer_->input_collated );
1464         setPostHandler( printer_->input_landscape );
1465         setPostHandler( printer_->input_to_file );
1466         setPostHandler( printer_->input_extra_options );
1467         setPostHandler( printer_->input_spool_prefix );
1468         setPostHandler( printer_->input_paper_size );
1469         setPostHandler( printer_->input_name );
1470         setPostHandler( printer_->check_adapt_output );
1471
1472         fl_end_form();
1473 }
1474
1475
1476 void FormPreferences::updatePrinter()
1477 {
1478         fl_set_button(printer_->check_adapt_output,
1479                       lyxrc.print_adapt_output);
1480         fl_set_input(printer_->input_command,
1481                      lyxrc.print_command.c_str());
1482         fl_set_input(printer_->input_page_range,
1483                      lyxrc.print_pagerange_flag.c_str());
1484         fl_set_input(printer_->input_copies,
1485                      lyxrc.print_copies_flag.c_str());
1486         fl_set_input(printer_->input_reverse,
1487                      lyxrc.print_reverse_flag.c_str());
1488         fl_set_input(printer_->input_to_printer,
1489                      lyxrc.print_to_printer.c_str());
1490         fl_set_input(printer_->input_file_extension,
1491                      lyxrc.print_file_extension.c_str());
1492         fl_set_input(printer_->input_spool_command,
1493                      lyxrc.print_spool_command.c_str());
1494         fl_set_input(printer_->input_paper_type,
1495                      lyxrc.print_paper_flag.c_str());
1496         fl_set_input(printer_->input_even_pages,
1497                      lyxrc.print_evenpage_flag.c_str());
1498         fl_set_input(printer_->input_odd_pages,
1499                      lyxrc.print_oddpage_flag.c_str());
1500         fl_set_input(printer_->input_collated,
1501                      lyxrc.print_collcopies_flag.c_str());
1502         fl_set_input(printer_->input_landscape,
1503                      lyxrc.print_landscape_flag.c_str());
1504         fl_set_input(printer_->input_to_file,
1505                      lyxrc.print_to_file.c_str());
1506         fl_set_input(printer_->input_extra_options,
1507                      lyxrc.print_extra_options.c_str());
1508         fl_set_input(printer_->input_spool_prefix,
1509                      lyxrc.print_spool_printerprefix.c_str());
1510         fl_set_input(printer_->input_paper_size,
1511                      lyxrc.print_paper_dimension_flag.c_str());
1512         fl_set_input(printer_->input_name,
1513                      lyxrc.printer.c_str());
1514 }
1515
1516
1517 void FormPreferences::applyScreenFonts() const
1518 {
1519         bool changed = false;
1520
1521         string str = fl_get_input(screen_fonts_->input_roman);
1522         if( lyxrc.roman_font_name != str ) {
1523                 changed = true;
1524                 lyxrc.roman_font_name = str;
1525         }
1526
1527         str = fl_get_input(screen_fonts_->input_sans);
1528         if( lyxrc.sans_font_name != str ) {
1529                 changed = true;
1530                 lyxrc.sans_font_name = str;
1531         }
1532
1533         str = fl_get_input(screen_fonts_->input_typewriter);
1534         if( lyxrc.typewriter_font_name != str ) {
1535                 changed = true;
1536                 lyxrc.typewriter_font_name = str;
1537         }
1538
1539         str = fl_get_input(screen_fonts_->input_screen_encoding);
1540         if( lyxrc.font_norm != str ) {
1541                 changed = true;
1542                 lyxrc.font_norm = str;
1543         }
1544
1545         bool button = fl_get_button(screen_fonts_->check_scalable);
1546         if( lyxrc.use_scalable_fonts != button ) {
1547                 changed = true;
1548                 lyxrc.use_scalable_fonts = button;
1549         }
1550
1551         unsigned int ivalue = static_cast<unsigned int>
1552                 (fl_get_counter_value(screen_fonts_->counter_zoom));
1553         if( lyxrc.zoom != ivalue) {
1554                 changed = true;
1555                 lyxrc.zoom = ivalue;
1556         }
1557
1558         ivalue = static_cast<unsigned int>
1559                 (fl_get_counter_value(screen_fonts_->counter_dpi));
1560         if (lyxrc.dpi != ivalue) {
1561                 changed = true;
1562                 lyxrc.dpi = ivalue;
1563         }
1564         
1565         double dvalue = strToDbl(fl_get_input(screen_fonts_->input_tiny));
1566         if( lyxrc.font_sizes[LyXFont::SIZE_TINY] != dvalue ) {
1567                 changed = true;
1568                 lyxrc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
1569         }
1570
1571         dvalue = strToDbl(fl_get_input(screen_fonts_->input_script));
1572         if( lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue ) {
1573                 changed = true;
1574                 lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
1575         }
1576
1577         dvalue = strToDbl(fl_get_input(screen_fonts_->input_footnote));
1578         if( lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue ) {
1579                 changed = true;
1580                 lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
1581         }
1582
1583         dvalue = strToDbl(fl_get_input(screen_fonts_->input_small));
1584         if( lyxrc.font_sizes[LyXFont::SIZE_SMALL] != dvalue ) {
1585                 changed = true;
1586                 lyxrc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
1587         }
1588
1589         dvalue = strToDbl(fl_get_input(screen_fonts_->input_normal));
1590         if( lyxrc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue ) {
1591                 changed = true;
1592                 lyxrc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
1593         }
1594
1595         dvalue = strToDbl(fl_get_input(screen_fonts_->input_large));
1596         if( lyxrc.font_sizes[LyXFont::SIZE_LARGE] != dvalue ) {
1597                 changed = true;
1598                 lyxrc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
1599         }
1600
1601         dvalue = strToDbl(fl_get_input(screen_fonts_->input_larger));
1602         if( lyxrc.font_sizes[LyXFont::SIZE_LARGER] != dvalue ) {
1603                 changed = true;
1604                 lyxrc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
1605         }
1606
1607         dvalue = strToDbl(fl_get_input(screen_fonts_->input_largest));
1608         if( lyxrc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue ) {
1609                 changed = true;
1610                 lyxrc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
1611         }
1612
1613         dvalue = strToDbl(fl_get_input(screen_fonts_->input_huge));
1614         if( lyxrc.font_sizes[LyXFont::SIZE_HUGE] != dvalue ) {
1615                 changed = true;
1616                 lyxrc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
1617         }
1618
1619         dvalue = strToDbl(fl_get_input(screen_fonts_->input_huger));
1620         if( lyxrc.font_sizes[LyXFont::SIZE_HUGER] != dvalue ) {
1621                 changed = true;
1622                 lyxrc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
1623         }
1624
1625         if( changed ) {
1626                 // Now update the buffers
1627                 // Can anything below here affect the redraw process?
1628                 lv_->getLyXFunc()->Dispatch(LFUN_SCREEN_FONT_UPDATE);
1629         }
1630 }
1631
1632
1633 void FormPreferences::buildScreenFonts()
1634 {
1635         screen_fonts_ = build_screen_fonts();
1636
1637         fl_set_input_return(screen_fonts_->input_roman, FL_RETURN_CHANGED);
1638         fl_set_input_return(screen_fonts_->input_sans, FL_RETURN_CHANGED);
1639         fl_set_input_return(screen_fonts_->input_typewriter,
1640                             FL_RETURN_CHANGED);
1641         fl_set_input_return(screen_fonts_->input_screen_encoding,
1642                             FL_RETURN_CHANGED);
1643         fl_set_counter_return(screen_fonts_->counter_zoom, FL_RETURN_CHANGED);
1644         fl_set_counter_return(screen_fonts_->counter_dpi, FL_RETURN_CHANGED);
1645         fl_set_input_return(screen_fonts_->input_tiny, FL_RETURN_CHANGED);
1646         fl_set_input_return(screen_fonts_->input_script, FL_RETURN_CHANGED);
1647         fl_set_input_return(screen_fonts_->input_footnote, FL_RETURN_CHANGED);
1648         fl_set_input_return(screen_fonts_->input_small, FL_RETURN_CHANGED);
1649         fl_set_input_return(screen_fonts_->input_normal, FL_RETURN_CHANGED);
1650         fl_set_input_return(screen_fonts_->input_large, FL_RETURN_CHANGED);
1651         fl_set_input_return(screen_fonts_->input_larger, FL_RETURN_CHANGED);
1652         fl_set_input_return(screen_fonts_->input_largest, FL_RETURN_CHANGED);
1653         fl_set_input_return(screen_fonts_->input_huge, FL_RETURN_CHANGED);
1654         fl_set_input_return(screen_fonts_->input_huger, FL_RETURN_CHANGED);
1655
1656         fl_set_input_filter(screen_fonts_->input_tiny,
1657                             fl_unsigned_int_filter);
1658         fl_set_input_filter(screen_fonts_->input_script,
1659                             fl_unsigned_int_filter);
1660         fl_set_input_filter(screen_fonts_->input_footnote,
1661                             fl_unsigned_int_filter);
1662         fl_set_input_filter(screen_fonts_->input_small,
1663                             fl_unsigned_int_filter);
1664         fl_set_input_filter(screen_fonts_->input_normal,
1665                             fl_unsigned_int_filter);
1666         fl_set_input_filter(screen_fonts_->input_large,
1667                             fl_unsigned_int_filter);
1668         fl_set_input_filter(screen_fonts_->input_larger,
1669                             fl_unsigned_int_filter);
1670         fl_set_input_filter(screen_fonts_->input_largest,
1671                             fl_unsigned_int_filter);
1672         fl_set_input_filter(screen_fonts_->input_huge,
1673                             fl_unsigned_int_filter);
1674         fl_set_input_filter(screen_fonts_->input_huger,
1675                             fl_unsigned_int_filter);
1676
1677         // set up the feedback mechanism
1678         fl_addto_form(screen_fonts_->form);
1679
1680         setPostHandler( screen_fonts_->input_roman );
1681         setPostHandler( screen_fonts_->input_sans );
1682         setPostHandler( screen_fonts_->input_typewriter );
1683         setPostHandler( screen_fonts_->counter_zoom );
1684         setPostHandler( screen_fonts_->counter_dpi );
1685         setPostHandler( screen_fonts_->check_scalable );
1686         setPostHandler( screen_fonts_->input_screen_encoding );
1687         setPostHandler( screen_fonts_->input_tiny );
1688         setPostHandler( screen_fonts_->input_script );
1689         setPostHandler( screen_fonts_->input_footnote );
1690         setPostHandler( screen_fonts_->input_small );
1691         setPostHandler( screen_fonts_->input_large );
1692         setPostHandler( screen_fonts_->input_larger );
1693         setPostHandler( screen_fonts_->input_largest );
1694         setPostHandler( screen_fonts_->input_normal );
1695         setPostHandler( screen_fonts_->input_huge );
1696         setPostHandler( screen_fonts_->input_huger );
1697
1698         fl_end_form();
1699 }
1700
1701         
1702 string FormPreferences::feedbackScreenFonts(FL_OBJECT const * const ob ) const
1703 {
1704         string str;
1705
1706         if( ob == screen_fonts_->input_roman )
1707                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ROMAN );
1708         else if( ob == screen_fonts_->input_sans )
1709                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SANS );
1710         else if( ob == screen_fonts_->input_typewriter )
1711                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_TYPEWRITER );
1712         else if( ob == screen_fonts_->check_scalable )
1713                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SCALABLE );
1714         else if( ob == screen_fonts_->input_screen_encoding )
1715                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_ENCODING );
1716         else if( ob == screen_fonts_->counter_zoom )
1717                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_ZOOM );
1718         else if( ob == screen_fonts_->counter_dpi ) 
1719                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_DPI );
1720         else if( ob == screen_fonts_->input_tiny
1721                  || ob == screen_fonts_->input_script
1722                  || ob == screen_fonts_->input_footnote
1723                  || ob == screen_fonts_->input_small
1724                  || ob == screen_fonts_->input_large
1725                  || ob == screen_fonts_->input_larger
1726                  || ob == screen_fonts_->input_larger
1727                  || ob == screen_fonts_->input_largest
1728                  || ob == screen_fonts_->input_normal
1729                  || ob == screen_fonts_->input_huge
1730                  || ob == screen_fonts_->input_huger )
1731                 str = lyxrc.getDescription( LyXRC::RC_SCREEN_FONT_SIZES );
1732
1733         return str;
1734 }
1735
1736
1737 bool FormPreferences::inputScreenFonts()
1738 {
1739         bool activate = true;
1740         string str;
1741
1742         // Make sure that all fonts all have positive entries
1743         // Also note that an empty entry is returned as 0.0 by strToDbl
1744         if (0.0 >= strToDbl(fl_get_input(screen_fonts_->input_tiny))
1745             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_script))
1746             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_footnote))
1747             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_small))
1748             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_normal))
1749             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_large))
1750             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_larger))
1751             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_largest))
1752             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_huge))
1753             || 0.0 >= strToDbl(fl_get_input(screen_fonts_->input_huger))) {
1754                 activate = false;
1755                 str = N_("WARNING! Fonts must be positive!");
1756
1757         // Fontsizes -- tiny < script < footnote etc.
1758         } else if (strToDbl(fl_get_input(screen_fonts_->input_tiny)) >
1759                    strToDbl(fl_get_input(screen_fonts_->input_script)) ||
1760                    strToDbl(fl_get_input(screen_fonts_->input_script)) >
1761                    strToDbl(fl_get_input(screen_fonts_->input_footnote)) ||
1762                    strToDbl(fl_get_input(screen_fonts_->input_footnote)) >
1763                    strToDbl(fl_get_input(screen_fonts_->input_small)) ||
1764                    strToDbl(fl_get_input(screen_fonts_->input_small)) >
1765                    strToDbl(fl_get_input(screen_fonts_->input_normal)) ||
1766                    strToDbl(fl_get_input(screen_fonts_->input_normal)) >
1767                    strToDbl(fl_get_input(screen_fonts_->input_large)) ||
1768                    strToDbl(fl_get_input(screen_fonts_->input_large)) >
1769                    strToDbl(fl_get_input(screen_fonts_->input_larger)) ||
1770                    strToDbl(fl_get_input(screen_fonts_->input_larger)) >
1771                    strToDbl(fl_get_input(screen_fonts_->input_largest)) ||
1772                    strToDbl(fl_get_input(screen_fonts_->input_largest)) >
1773                    strToDbl(fl_get_input(screen_fonts_->input_huge)) ||
1774                    strToDbl(fl_get_input(screen_fonts_->input_huge)) >
1775                    strToDbl(fl_get_input(screen_fonts_->input_huger))) {
1776                 activate = false;
1777
1778                 str = N_("WARNING! Fonts must be input in the order tiny > script>\nfootnote > small > normal > large > larger > largest > huge > huger.");
1779         }
1780
1781         if( !activate ) {
1782                 fl_set_object_label(dialog_->text_warning, str.c_str());
1783                 fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
1784         }
1785         
1786         return activate;
1787 }
1788
1789
1790 void FormPreferences::updateScreenFonts()
1791 {
1792         fl_set_input(screen_fonts_->input_roman,
1793                      lyxrc.roman_font_name.c_str());
1794         fl_set_input(screen_fonts_->input_sans,
1795                      lyxrc.sans_font_name.c_str());
1796         fl_set_input(screen_fonts_->input_typewriter,
1797                      lyxrc.typewriter_font_name.c_str());
1798         fl_set_input(screen_fonts_->input_screen_encoding,
1799                      lyxrc.font_norm.c_str());
1800         fl_set_button(screen_fonts_->check_scalable,
1801                       lyxrc.use_scalable_fonts);
1802         fl_set_counter_value(screen_fonts_->counter_zoom, lyxrc.zoom);
1803         fl_set_counter_value(screen_fonts_->counter_dpi,  lyxrc.dpi);
1804         fl_set_input(screen_fonts_->input_tiny,
1805                      tostr(lyxrc.font_sizes[LyXFont::SIZE_TINY]).c_str());
1806         fl_set_input(screen_fonts_->input_script,
1807                      tostr(lyxrc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
1808         fl_set_input(screen_fonts_->input_footnote,
1809                      tostr(lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
1810         fl_set_input(screen_fonts_->input_small,
1811                      tostr(lyxrc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
1812         fl_set_input(screen_fonts_->input_normal,
1813                      tostr(lyxrc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
1814         fl_set_input(screen_fonts_->input_large,
1815                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
1816         fl_set_input(screen_fonts_->input_larger,
1817                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
1818         fl_set_input(screen_fonts_->input_largest,
1819                      tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
1820         fl_set_input(screen_fonts_->input_huge,
1821                      tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
1822         fl_set_input(screen_fonts_->input_huger,
1823                      tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
1824 }
1825
1826
1827 void FormPreferences::applySpellChecker()
1828 {
1829
1830         string choice = "none";
1831         switch(fl_get_choice(spellchecker_->choice_spell_command)) {
1832         case 1:
1833                 choice = "none";
1834                 break;
1835         case 2:
1836                 choice = "ispell";
1837                 break;
1838         case 3:
1839                 choice = "aspell";
1840                 break;
1841         default:
1842                 break;
1843         }
1844         lyxrc.isp_command = choice;
1845
1846         // If spell checker == "none", all other input set to off.
1847         if( fl_get_choice(spellchecker_->choice_spell_command) == 1 ) {
1848                 lyxrc.isp_use_alt_lang = false;
1849                 lyxrc.isp_alt_lang.erase();
1850
1851                 lyxrc.isp_use_esc_chars = false;
1852                 lyxrc.isp_esc_chars.erase();
1853
1854                 lyxrc.isp_use_pers_dict = false;
1855                 lyxrc.isp_pers_dict.erase();
1856
1857                 lyxrc.isp_accept_compound = false;
1858                 lyxrc.isp_use_input_encoding = false;
1859         } else {
1860                 int button = fl_get_button(spellchecker_->check_alt_lang);
1861                 choice = fl_get_input(spellchecker_->input_alt_lang);
1862                 if( button && choice.empty() ) button = 0;
1863                 if( !button ) choice.erase();
1864
1865                 lyxrc.isp_use_alt_lang = static_cast<bool>(button);
1866                 lyxrc.isp_alt_lang = choice;
1867
1868                 button = fl_get_button(spellchecker_->check_escape_chars);
1869                 choice = fl_get_input(spellchecker_->input_escape_chars);
1870                 if( button && choice.empty() ) button = 0;
1871                 if( !button ) choice.erase();
1872         
1873                 lyxrc.isp_use_esc_chars = static_cast<bool>(button);
1874                 lyxrc.isp_esc_chars = choice;
1875
1876                 button = fl_get_button(spellchecker_->check_personal_dict);
1877                 choice = fl_get_input(spellchecker_->input_personal_dict);
1878                 if( button && choice.empty() ) button = 0;
1879                 if( !button ) choice.erase();
1880
1881                 lyxrc.isp_use_pers_dict = static_cast<bool>(button);
1882                 lyxrc.isp_pers_dict = choice;
1883
1884                 button = fl_get_button(spellchecker_->check_compound_words);
1885                 lyxrc.isp_accept_compound = static_cast<bool>(button);
1886
1887                 button = fl_get_button(spellchecker_->check_input_enc);
1888                 lyxrc.isp_use_input_encoding = static_cast<bool>(button);
1889         }
1890
1891         // Reset view
1892         updateSpellChecker();
1893 }
1894
1895
1896 void FormPreferences::buildSpellchecker()
1897 {
1898         spellchecker_ = build_spellchecker();
1899
1900         fl_addto_choice(spellchecker_->choice_spell_command,
1901                         _(" none | ispell | aspell "));
1902         fl_set_input_return(spellchecker_->input_alt_lang,
1903                             FL_RETURN_CHANGED);
1904         fl_set_input_return(spellchecker_->input_escape_chars,
1905                             FL_RETURN_CHANGED);
1906         fl_set_input_return(spellchecker_->input_personal_dict,
1907                             FL_RETURN_CHANGED);
1908
1909         // deactivate the browse button because it isn't implemented
1910         fl_deactivate_object(spellchecker_->button_personal_dict);
1911         fl_set_object_lcol(spellchecker_->button_personal_dict,
1912                            FL_INACTIVE);
1913
1914         // set up the feedback mechanism
1915         fl_addto_form(spellchecker_->form);
1916
1917         setPostHandler( spellchecker_->choice_spell_command );
1918         setPostHandler( spellchecker_->check_alt_lang );
1919         setPostHandler( spellchecker_->input_alt_lang );
1920         setPostHandler( spellchecker_->check_escape_chars );
1921         setPostHandler( spellchecker_->input_escape_chars );
1922         setPostHandler( spellchecker_->check_personal_dict );
1923         setPostHandler( spellchecker_->input_personal_dict );
1924         setPostHandler( spellchecker_->button_personal_dict );
1925         setPostHandler( spellchecker_->check_compound_words );
1926         setPostHandler( spellchecker_->check_input_enc );
1927
1928         fl_end_form();
1929 }
1930
1931
1932 string FormPreferences::feedbackSpellChecker( FL_OBJECT const * const ob ) const
1933 {
1934         string str;
1935
1936         if( ob == spellchecker_->choice_spell_command )
1937                 str = lyxrc.getDescription( LyXRC::RC_SPELL_COMMAND );
1938         else if( ob == spellchecker_->check_alt_lang )
1939                 str = lyxrc.getDescription( LyXRC::RC_USE_ALT_LANG );
1940         else if( ob == spellchecker_->input_alt_lang )
1941                 str = lyxrc.getDescription( LyXRC::RC_ALT_LANG );
1942         else if( ob == spellchecker_->check_escape_chars )
1943                 str = lyxrc.getDescription( LyXRC::RC_USE_ESC_CHARS );
1944         else if( ob == spellchecker_->input_escape_chars )
1945                 str = lyxrc.getDescription( LyXRC::RC_ESC_CHARS );
1946         else if( ob == spellchecker_->check_personal_dict )
1947                 str = lyxrc.getDescription( LyXRC::RC_USE_PERS_DICT );
1948         else if( ob == spellchecker_->input_personal_dict )
1949                 str = lyxrc.getDescription( LyXRC::RC_PERS_DICT );
1950         else if( ob == spellchecker_->check_compound_words )
1951                 str = lyxrc.getDescription( LyXRC::RC_ACCEPT_COMPOUND );
1952         else if( ob == spellchecker_->check_input_enc )
1953                 str = lyxrc.getDescription( LyXRC::RC_USE_INP_ENC );
1954
1955         return str;
1956 }
1957
1958
1959 bool FormPreferences::inputSpellChecker( FL_OBJECT const * const ob )
1960 {
1961         // Allow/dissallow input
1962
1963         // If spell checker == "none", disable all input.
1964         if( !ob || ob == spellchecker_->choice_spell_command ) {
1965                 if( fl_get_choice(spellchecker_->choice_spell_command) == 1 ) {
1966                         fl_deactivate_object( spellchecker_->check_alt_lang );
1967                         fl_deactivate_object( spellchecker_->input_alt_lang );
1968                         fl_deactivate_object( spellchecker_->check_escape_chars );
1969                         fl_deactivate_object( spellchecker_->input_escape_chars );
1970                         fl_deactivate_object( spellchecker_->check_personal_dict );
1971                         fl_deactivate_object( spellchecker_->input_personal_dict );
1972                         fl_deactivate_object( spellchecker_->check_compound_words );
1973                         fl_deactivate_object( spellchecker_->check_input_enc );
1974                         return true;
1975                 } else {
1976                         fl_activate_object( spellchecker_->check_alt_lang );
1977                         fl_activate_object( spellchecker_->check_escape_chars );
1978                         fl_activate_object( spellchecker_->check_personal_dict );
1979                         fl_activate_object( spellchecker_->check_compound_words );
1980                         fl_activate_object( spellchecker_->check_input_enc );
1981                 }
1982         }
1983
1984         if( !ob || ob == spellchecker_->check_alt_lang ) {
1985                 if( fl_get_button(spellchecker_->check_alt_lang) ) {
1986                         fl_activate_object(spellchecker_->input_alt_lang);
1987                         fl_set_object_lcol(spellchecker_->input_alt_lang,
1988                                            FL_BLACK);
1989                 } else {
1990                         fl_deactivate_object(spellchecker_->input_alt_lang);
1991                         fl_set_object_lcol(spellchecker_->input_alt_lang,
1992                                            FL_INACTIVE);
1993                 }
1994         }
1995
1996         if( !ob || ob == spellchecker_->check_escape_chars ) {
1997                 if( fl_get_button(spellchecker_->check_escape_chars) ) {
1998                         fl_activate_object(spellchecker_->input_escape_chars);
1999                         fl_set_object_lcol(spellchecker_->input_escape_chars,
2000                                            FL_BLACK);
2001                 } else {
2002                         fl_deactivate_object(spellchecker_->input_escape_chars);
2003                         fl_set_object_lcol(spellchecker_->input_escape_chars,
2004                                            FL_INACTIVE);
2005                 }
2006         }
2007
2008         if( !ob || ob == spellchecker_->check_personal_dict ) {
2009                 if( fl_get_button(spellchecker_->check_personal_dict) ) {
2010                         fl_activate_object(spellchecker_->input_personal_dict);
2011                         fl_set_object_lcol(spellchecker_->input_personal_dict,
2012                                            FL_BLACK);
2013                 } else {
2014                         fl_deactivate_object(spellchecker_->input_personal_dict);
2015                         fl_set_object_lcol(spellchecker_->input_personal_dict,
2016                                            FL_INACTIVE);
2017                 }
2018         }
2019         
2020         return true; // All input is valid!
2021 }
2022
2023
2024 void FormPreferences::updateSpellChecker()
2025 {
2026         int choice = 1;
2027         if( lyxrc.isp_command == "none" )
2028                 choice = 1;
2029         else if( lyxrc.isp_command == "ispell" )
2030                 choice = 2;
2031         else if( lyxrc.isp_command == "aspell" )
2032                 choice = 3;
2033         fl_set_choice(spellchecker_->choice_spell_command, choice);
2034         
2035         string str = string();
2036         if( lyxrc.isp_use_alt_lang ) str = lyxrc.isp_alt_lang;
2037
2038         fl_set_button(spellchecker_->check_alt_lang,
2039                       lyxrc.isp_use_alt_lang);
2040         fl_set_input(spellchecker_->input_alt_lang, str.c_str());
2041         
2042         str.erase();
2043         if( lyxrc.isp_use_esc_chars ) str = lyxrc.isp_esc_chars;
2044
2045         fl_set_button(spellchecker_->check_escape_chars,
2046                       lyxrc.isp_use_esc_chars);
2047         fl_set_input(spellchecker_->input_escape_chars, str.c_str());
2048
2049         str.erase();
2050         if( lyxrc.isp_use_pers_dict ) str = lyxrc.isp_pers_dict;
2051
2052         fl_set_button(spellchecker_->check_personal_dict,
2053                       lyxrc.isp_use_pers_dict);
2054         fl_set_input(spellchecker_->input_personal_dict, str.c_str());
2055
2056         fl_set_button(spellchecker_->check_compound_words,
2057                       lyxrc.isp_accept_compound);
2058         fl_set_button(spellchecker_->check_input_enc,
2059                       lyxrc.isp_use_input_encoding);
2060
2061         // Activate/Deactivate the input fields dependent on the state of the
2062         // buttons.
2063         inputSpellChecker( 0 );
2064 }
2065
2066
2067 bool FormPreferences::WriteableDir( string const & name ) const
2068 {
2069         bool success = true;
2070         string str;
2071
2072         if( !AbsolutePath(name) ) {
2073                 success = false;
2074                 str = N_("WARNING! The absolute path is required.");
2075         }
2076
2077         FileInfo tp(name);
2078         if( success && !tp.isDir() ) {
2079                 success = false;
2080                 str = N_("WARNING! Directory does not exist.");
2081         }
2082
2083         if( success && !tp.writable() ) {
2084                 success = false;
2085                 str = N_("WARNING! Cannot write to this directory.");
2086         }
2087
2088         if( !success ) {
2089                 fl_set_object_label(dialog_->text_warning, str.c_str());
2090                 fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
2091         }
2092         
2093         return success;
2094 }
2095
2096
2097 bool FormPreferences::ReadableDir( string const & name ) const
2098 {
2099         bool success = true;
2100         string str;
2101
2102         if( !AbsolutePath(name) ) {
2103                 success = false;
2104                 str = N_("WARNING! The absolute path is required.");
2105         }
2106
2107         FileInfo tp(name);
2108         if( success && !tp.isDir() ) {
2109                 success = false;
2110                 str = N_("WARNING! Directory does not exist.");
2111         }
2112
2113         if( success && !tp.readable() ) {
2114                 success = false;
2115                 str = N_("WARNING! Cannot read this directory.");
2116         }
2117
2118         if( !success ) {
2119                 fl_set_object_label(dialog_->text_warning, str.c_str());
2120                 fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
2121         }
2122
2123         return success;
2124 }
2125
2126
2127 bool FormPreferences::WriteableFile( string const & name, string const & suffix ) const
2128 {
2129         // A writeable file is either:
2130         // * An existing file to which we have write access, or
2131         // * A file that doesn't yet exist but that would exist in a writeable
2132         //   directory.
2133
2134         bool success = true;
2135         string str;
2136
2137         if( name.empty() ) {
2138                 success = false;
2139                 str = N_("WARNING! No file input.");
2140         }
2141
2142         string dir = OnlyPath(name);
2143         if( success && !AbsolutePath(dir) ) {
2144                 success = false;
2145                 str = N_("WARNING! The absolute path is required.");
2146         }
2147
2148         FileInfo d;
2149         {
2150                 FileInfo d1(dir);
2151                 FileInfo d2(name);
2152                 if( d2.isDir() )
2153                         d = d2;
2154                 else
2155                         d = d1;
2156         }
2157         
2158         if( success && !d.isDir()) {
2159                 success = false;
2160                 str = N_("WARNING! Directory does not exist.");
2161         }
2162         
2163         if( success && !d.writable() ) {
2164                 success = false;
2165                 str = N_("WARNING! Cannot write to this directory.");
2166         }
2167
2168         FileInfo f(name+suffix);
2169         if( success && (dir == name || f.isDir()) ) {
2170                 success = false;
2171                 str = N_("WARNING! A file is required, not a directory.");
2172         }
2173
2174         if( success && (f.exist() && !f.writable()) ) {
2175                 success = false;
2176                 str = N_("WARNING! Cannot write to this file.");
2177         }
2178         
2179         if( !success ) {
2180                 fl_set_object_label(dialog_->text_warning, str.c_str());
2181                 fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
2182         }
2183
2184         return success;
2185 }
2186
2187
2188 void FormPreferences::ComboLanguageCB(int, void * v, Combox * combox)
2189 {
2190     FormPreferences * pre = static_cast<FormPreferences*>(v);
2191     // This is safe, as nothing is done to the pointer, other than
2192     // to use its address in a block-if statement.
2193     pre->bc_.valid( pre->input( reinterpret_cast<FL_OBJECT *>(combox), 0 ));
2194 }
2195
2196
2197 // C functions for the timer callback used to give the user feedback
2198 C_GENERICCB(FormPreferences, FeedbackCB)
2199
2200 void FormPreferences::FeedbackCB(FL_OBJECT * ob, long)
2201 {
2202         FormPreferences * pre =
2203                 static_cast<FormPreferences*>(ob->form->u_vdata);
2204         pre->feedback( pre->feedbackObj );
2205 }
2206
2207 extern "C" int C_FormPreferencesFeedbackPost(FL_OBJECT * ob, int event,
2208                                              FL_Coord, FL_Coord, int, void *)
2209 {
2210         // can occur when form is being deleted. This seems an easier fix than
2211         // a call "fl_set_object_posthandler(ob, 0)" for each and every object
2212         // in the destructor.
2213         if( !ob->form ) return 0;
2214
2215         FormPreferences * pre =
2216                 static_cast<FormPreferences*>(ob->form->u_vdata);
2217         pre->feedbackPost(ob, event);
2218         return 0;
2219 }
2220
2221
2222 // post_handler for feedback messages
2223 void FormPreferences::feedbackPost(FL_OBJECT *ob, int event)
2224 {
2225         // We do not test for empty help here, since this can never happen
2226         if(event == FL_ENTER){
2227                 // Used as a placeholder for ob, so that we don't have to
2228                 // a horrible reinterpret_cast to long and pass it as an
2229                 // argument in fl_set_object_callback.
2230                 feedbackObj = ob;
2231                 fl_set_object_callback(dialog_->timer_feedback,
2232                                        C_FormPreferencesFeedbackCB,
2233                                        0);
2234                 fl_set_timer(dialog_->timer_feedback, 0.5);
2235         }
2236         else if(event != FL_MOTION){
2237                 fl_set_timer(dialog_->timer_feedback, 0);
2238                 feedbackObj = 0;
2239                 fl_set_object_label(dialog_->text_warning, "");
2240         }
2241 }
2242
2243
2244 void FormPreferences::setPostHandler( FL_OBJECT * ob ) const
2245 {
2246         fl_set_object_posthandler(ob, C_FormPreferencesFeedbackPost);
2247 }