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