]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormDocument.C
J�rgen S's "power user" patch
[features.git] / src / frontends / xforms / FormDocument.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *           Copyright 2000-2001 The LyX Team.
7  *
8  *           @author Jürgen Vigna
9  *
10  *======================================================*/
11
12 #include <config.h>
13
14 #include FORMS_H_LOCATION
15 #include XPM_H_LOCATION
16
17 #ifdef __GNUG_
18 #pragma implementation
19 #endif
20
21 #include "FormDocument.h"
22 #include "form_document.h"
23 #include "Alert.h"
24 #include "Dialogs.h"
25 #include "lyxtextclasslist.h"
26 #include "combox.h"
27 #include "tex-strings.h"
28 #include "bufferparams.h"
29 #include "vspace.h"
30 #include "bmtable.h"
31 #include "language.h"
32 #include "LyXView.h"
33 #include "lyxfunc.h"
34 #include "lyxrc.h"
35 #include "BufferView.h"
36 #include "buffer.h"
37 #include "Liason.h"
38 #include "CutAndPaste.h"
39 #include "bufferview_funcs.h"
40 #include "xforms_helpers.h" 
41 #include "debug.h"
42 #include "input_validators.h" // fl_unsigned_float_filter
43 #include "helper_funcs.h" 
44 #include "lyx_main.h" // for user_lyxdir
45
46 #include "insets/insetquotes.h"
47
48 #include "support/filetools.h"
49 #include "support/lstrings.h"
50
51 using Liason::setMinibuffer;
52 using SigC::slot;
53
54 FormDocument::FormDocument(LyXView * lv, Dialogs * d)
55         : FormBaseBD(lv, d, _("Document Layout")),
56           ActCell(0), Confirmed(0),
57           current_bullet_panel(0), current_bullet_depth(0), fbullet(0)
58 {
59         // let the dialog be shown
60         // This is a permanent connection so we won't bother
61         // storing a copy because we won't be disconnecting.
62         d->showDocument.connect(slot(this, &FormDocument::show));
63 }
64
65
66 void FormDocument::redraw()
67 {
68         if( form() && form()->visible )
69                 fl_redraw_form( form() );
70         else
71                 return;
72
73         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabbed_folder);
74         if (outer_form && outer_form->visible)
75                 fl_redraw_form( outer_form );
76 }
77
78
79 FL_FORM * FormDocument::form() const
80 {
81         if (dialog_.get()) return dialog_->form;
82         return 0;
83 }
84
85
86 void FormDocument::build()
87 {
88         int n;
89
90         // the tabbed folder
91         dialog_.reset(build_tabbed_document());
92
93         // Manage the restore, ok, apply, restore and cancel/close buttons
94         bc().setOK(dialog_->button_ok);
95         bc().setApply(dialog_->button_apply);
96         bc().setCancel(dialog_->button_cancel);
97         bc().setRestore(dialog_->button_restore);
98         bc().addReadOnly (dialog_->button_save_defaults);
99         bc().addReadOnly (dialog_->button_reset_defaults);
100
101         // the document paper form
102         paper_.reset(build_doc_paper());
103         fl_addto_choice(paper_->choice_papersize,
104                         _(" Default | Custom | USletter | USlegal "
105                           "| USexecutive | A3 | A4 | A5 | B3 | B4 | B5 "));
106         fl_addto_choice(paper_->choice_paperpackage,
107                         _(" None "
108                           "| Small Margins "
109                           "| Very small Margins "
110                           "| Very wide Margins "));
111
112         fl_set_input_return(paper_->input_custom_width,  FL_RETURN_CHANGED);
113         fl_set_input_return(paper_->input_custom_height, FL_RETURN_CHANGED);
114         fl_set_input_return(paper_->input_top_margin,    FL_RETURN_CHANGED);
115         fl_set_input_return(paper_->input_bottom_margin, FL_RETURN_CHANGED);
116         fl_set_input_return(paper_->input_inner_margin,  FL_RETURN_CHANGED);
117         fl_set_input_return(paper_->input_outer_margin,  FL_RETURN_CHANGED);
118         fl_set_input_return(paper_->input_head_height,   FL_RETURN_CHANGED);
119         fl_set_input_return(paper_->input_head_sep,      FL_RETURN_CHANGED);
120         fl_set_input_return(paper_->input_foot_skip,     FL_RETURN_CHANGED);
121
122
123         // Create the contents of the unit choices
124         // Don't include the "%" terms...
125         std::vector<string> units_vec = getLatexUnits();
126         for (std::vector<string>::iterator it = units_vec.begin();
127                 it != units_vec.end(); ++it) {
128                 if (contains(*it, "%"))
129                         it = units_vec.erase(it, it+1) - 1;
130         }
131         string units = getStringFromVector(units_vec, "|");
132
133         fl_addto_choice(paper_->choice_custom_width_units,  units.c_str());
134         fl_addto_choice(paper_->choice_custom_height_units, units.c_str());
135         fl_addto_choice(paper_->choice_top_margin_units,    units.c_str());
136         fl_addto_choice(paper_->choice_bottom_margin_units, units.c_str());
137         fl_addto_choice(paper_->choice_inner_margin_units,  units.c_str());
138         fl_addto_choice(paper_->choice_outer_margin_units,  units.c_str());
139         fl_addto_choice(paper_->choice_head_height_units,   units.c_str());
140         fl_addto_choice(paper_->choice_head_sep_units,      units.c_str());
141         fl_addto_choice(paper_->choice_foot_skip_units,     units.c_str());
142
143         bc().addReadOnly (paper_->choice_paperpackage);
144         bc().addReadOnly (paper_->group_radio_orientation);
145         bc().addReadOnly (paper_->radio_portrait);
146         bc().addReadOnly (paper_->radio_landscape);
147         bc().addReadOnly (paper_->choice_papersize);
148         bc().addReadOnly (paper_->check_use_geometry);
149         bc().addReadOnly (paper_->input_custom_width);
150         bc().addReadOnly (paper_->input_custom_height);
151         bc().addReadOnly (paper_->input_top_margin);
152         bc().addReadOnly (paper_->input_bottom_margin);
153         bc().addReadOnly (paper_->input_inner_margin);
154         bc().addReadOnly (paper_->input_outer_margin);
155         bc().addReadOnly (paper_->input_head_height);
156         bc().addReadOnly (paper_->input_head_sep);
157         bc().addReadOnly (paper_->input_foot_skip);
158
159         // the document class form
160         class_.reset(build_doc_class());
161
162         FL_OBJECT * obj;
163         // The language is a combo-box and has to be inserted manually
164         obj = class_->choice_doc_class;
165         fl_deactivate_object(obj);
166         fl_addto_form(class_->form);
167         combo_doc_class.reset(new Combox(FL_COMBOX_DROPLIST));
168         combo_doc_class->add(obj->x, obj->y, obj->w, obj->h, 400,
169                              dialog_->tabbed_folder);
170         combo_doc_class->shortcut("#C",1);
171         combo_doc_class->setcallback(ComboInputCB, this);
172         fl_end_form();
173         for (LyXTextClassList::const_iterator cit = textclasslist.begin();
174              cit != textclasslist.end(); ++cit) {
175                 combo_doc_class->addto(cit->description());
176         }
177
178         fl_addto_choice(class_->choice_doc_spacing,
179                         _(" Single | OneHalf | Double | Other "));
180         fl_addto_choice(class_->choice_doc_fontsize, "default|10|11|12");
181         for (n=0; tex_fonts[n][0]; ++n) {
182                 fl_addto_choice(class_->choice_doc_fonts,tex_fonts[n]);
183         }
184         fl_addto_choice(class_->choice_doc_pagestyle,
185                         "default|empty|plain|headings|fancy");
186         fl_addto_choice(class_->choice_doc_skip,
187                         _(" Smallskip | Medskip | Bigskip | Length "));
188         fl_addto_choice(class_->choice_default_skip_units,  units.c_str());
189         fl_set_input_return(class_->input_doc_extra, FL_RETURN_CHANGED);
190         fl_set_input_return(class_->input_doc_skip, FL_RETURN_CHANGED);
191         fl_set_input_return(class_->input_doc_spacing, FL_RETURN_CHANGED);
192
193         // Set input filters on doc spacing to make it accept only
194         // unsigned numbers.
195         fl_set_input_filter(class_->input_doc_spacing, fl_unsigned_float_filter);
196
197         bc().addReadOnly (class_->radio_doc_indent);
198         bc().addReadOnly (class_->radio_doc_skip);
199
200         bc().addReadOnly (class_->choice_doc_pagestyle);
201         bc().addReadOnly (class_->choice_doc_fonts);
202         bc().addReadOnly (class_->choice_doc_fontsize);
203         bc().addReadOnly (class_->radio_doc_sides_one);
204         bc().addReadOnly (class_->radio_doc_sides_two);
205         bc().addReadOnly (class_->radio_doc_columns_one);
206         bc().addReadOnly (class_->radio_doc_columns_two);
207         bc().addReadOnly (class_->input_doc_extra);
208         bc().addReadOnly (class_->input_doc_skip);
209         bc().addReadOnly (class_->choice_doc_skip);
210         bc().addReadOnly (class_->choice_doc_spacing);
211         bc().addReadOnly (class_->input_doc_spacing);
212
213         // the document language form
214         language_.reset(build_doc_language());
215         fl_addto_choice(language_->choice_inputenc,
216                         "default|auto|latin1|latin2|latin3|latin4|latin5|latin9"
217                         "|koi8-r|koi8-u|cp866|cp1251|iso88595");
218
219         // The language is a combo-box and has to be inserted manually
220         obj = language_->choice_language;
221         fl_deactivate_object(obj);
222         fl_addto_form(language_->form);
223         combo_language.reset(new Combox(FL_COMBOX_DROPLIST));
224         combo_language->add(obj->x, obj->y, obj->w, obj->h, 400,
225                             dialog_->tabbed_folder);
226         combo_language->shortcut("#L",1);
227         combo_language->setcallback(ComboInputCB, this);
228         fl_end_form();
229
230         for (Languages::const_iterator cit = languages.begin();
231              cit != languages.end(); ++cit) {
232                 combo_language->addto(cit->second.lang());
233         }
234
235         fl_addto_choice(language_->choice_quotes_language,
236                         _(" ``text'' | ''text'' | ,,text`` | ,,text'' |"
237                           " «text» | »text« "));
238
239         bc().addReadOnly (language_->choice_inputenc);
240         bc().addReadOnly (language_->choice_quotes_language);
241         bc().addReadOnly (language_->radio_single);
242         bc().addReadOnly (language_->radio_double);
243
244         // the document options form
245         options_.reset(build_doc_options());
246         fl_set_input_return(options_->input_float_placement, FL_RETURN_CHANGED);
247         fl_set_counter_bounds(options_->slider_secnumdepth,-2,5);
248         fl_set_counter_bounds(options_->slider_tocdepth,-1,5);
249         fl_set_counter_step(options_->slider_secnumdepth,1,1);
250         fl_set_counter_step(options_->slider_tocdepth,1,1);
251         fl_set_counter_precision(options_->slider_secnumdepth, 0);
252         fl_set_counter_precision(options_->slider_tocdepth, 0);
253         for (n=0; tex_graphics[n][0]; ++n) {
254                 fl_addto_choice(options_->choice_postscript_driver,
255                                 tex_graphics[n]);
256         }
257         fl_addto_choice(options_->choice_citation_format,
258                         _(" Author-year | Numerical "));
259
260         bc_.addReadOnly (options_->slider_secnumdepth);
261         bc_.addReadOnly (options_->slider_tocdepth);
262         bc_.addReadOnly (options_->check_use_amsmath);
263         bc_.addReadOnly (options_->check_use_natbib);
264         bc_.addReadOnly (options_->choice_citation_format);
265         bc_.addReadOnly (options_->input_float_placement);
266         bc_.addReadOnly (options_->choice_postscript_driver);
267
268         // the document bullets form
269         bullets_.reset(build_doc_bullet());
270         fl_addto_choice(bullets_->choice_bullet_size,
271                         _(" default | tiny | script | footnote | small |"
272                           " normal | large | Large | LARGE | huge | Huge"));
273         fl_set_choice(bullets_->choice_bullet_size, 1);
274         fl_set_input_return(bullets_->input_bullet_latex, FL_RETURN_CHANGED);
275         fl_set_input_maxchars(bullets_->input_bullet_latex, 80);
276
277         bc().addReadOnly (bullets_->bmtable_bullet_panel);
278         bc().addReadOnly (bullets_->choice_bullet_size);
279         bc().addReadOnly (bullets_->input_bullet_latex);
280         bc().addReadOnly (bullets_->radio_bullet_depth);
281         bc().addReadOnly (bullets_->radio_bullet_panel);
282
283         fl_addto_tabfolder(dialog_->tabbed_folder,_("Document"),
284                            class_->form);
285         fl_addto_tabfolder(dialog_->tabbed_folder,_("Paper"),
286                            paper_->form);
287         fl_addto_tabfolder(dialog_->tabbed_folder,_("Language"),
288                            language_->form);
289         fl_addto_tabfolder(dialog_->tabbed_folder,_("Extra"),
290                            options_->form);
291         fbullet = fl_addto_tabfolder(dialog_->tabbed_folder,_("Bullets"),
292                                      bullets_->form);
293         if ((XpmVersion < 4) || (XpmVersion == 4 && XpmRevision < 7)) {
294                 lyxerr << _("Your version of libXpm is older than 4.7.\n"
295                             "The `bullet' tab of the document dialog "
296                             "has been disabled") << '\n';
297                 fl_deactivate_object(fbullet);
298                 fl_set_object_lcol(fbullet, FL_INACTIVE);
299         }
300 }
301
302
303 void FormDocument::apply()
304 {
305         if (!lv_->view()->available() || !dialog_.get())
306                 return;
307
308         bool redo = class_apply();
309         paper_apply();
310         redo = language_apply() || redo;
311         redo = options_apply() || redo;
312         bullets_apply();
313
314         if (redo) {
315                 lv_->view()->redoCurrentBuffer();
316         }
317         lv_->buffer()->markDirty();
318         setMinibuffer(lv_, _("Document layout set"));
319 }
320
321
322 void FormDocument::cancel()
323 {
324         // this avoids confusion when reopening
325         BufferParams & param = lv_->buffer()->params;
326         param.temp_bullets[0] = param.user_defined_bullets[0];
327         param.temp_bullets[1] = param.user_defined_bullets[1];
328         param.temp_bullets[2] = param.user_defined_bullets[2];
329         param.temp_bullets[3] = param.user_defined_bullets[3];
330         hide();
331 }
332
333
334 void FormDocument::update()
335 {
336         if (!dialog_.get())
337                 return;
338
339         checkReadOnly();
340
341         BufferParams const & params = lv_->buffer()->params;
342
343         class_update(params);
344         paper_update(params);
345         language_update(params);
346         options_update(params);
347         bullets_update(params);
348 }
349
350
351 namespace {
352 // should this go elsewhere? Maybe a ControllerDocument? (JMarc)
353 /** Save the buffer's parameters as user default.
354     This function saves a file \c user_lyxdir/templates/defaults.lyx
355     which parameters are those of the current buffer. This file
356     is used as a default template when creating a new
357     file. Returns \c true on success.
358 */
359 bool saveParamsAsDefault(BufferParams const &params)
360 {
361         if (!Alert::askQuestion(_("Do you want to save the current settings"),
362                          _("for the document layout as default?"),
363                          _("(they will be valid for any new document)")))
364                 return false;
365         
366         string const fname = AddName(AddPath(user_lyxdir, "templates/"),
367                                      "defaults.lyx");
368         Buffer defaults = Buffer(fname);
369         defaults.params = params;
370         
371         // add an empty paragraph. Is this enough?
372         defaults.paragraph = new Paragraph;
373                 
374         return defaults.writeFile(defaults.fileName(), false);
375 }
376
377 } //namespace
378
379 bool FormDocument::input( FL_OBJECT * ob, long data )
380 {
381         State cb = static_cast<State>( data );
382
383         switch (cb) {
384         case CHECKCHOICECLASS:
385                 CheckChoiceClass(ob, 0);
386                 break;
387         case CHOICEBULLETSIZE:
388                 ChoiceBulletSize(ob, 0);
389                 break;
390         case INPUTBULLETLATEX:
391                 InputBulletLaTeX(ob, 0);
392                 break;
393         case BULLETDEPTH1:
394         case BULLETDEPTH2:
395         case BULLETDEPTH3:
396         case BULLETDEPTH4:
397                 BulletDepth(ob, cb);
398                 break;
399         case BULLETPANEL1:
400         case BULLETPANEL2:
401         case BULLETPANEL3:
402         case BULLETPANEL4:
403         case BULLETPANEL5:
404         case BULLETPANEL6:
405                 BulletPanel(ob, cb);
406                 break;
407         case BULLETBMTABLE:
408                 BulletBMTable(ob, 0);
409                 break;
410         default:
411                 break;
412         }
413
414         bool const length_input = fl_get_choice(class_->choice_doc_skip) == 4;
415         if (ob == class_->choice_doc_skip) {
416                 setEnabled(class_->input_doc_skip, length_input);
417                 setEnabled(class_->choice_default_skip_units, length_input);
418         }
419
420         if (ob == class_->choice_doc_spacing)
421                 setEnabled(class_->input_doc_spacing,
422                            fl_get_choice(class_->choice_doc_spacing) == 4);
423
424         bool const skip_used = fl_get_button(class_->radio_doc_skip);
425         if (ob == class_->radio_doc_skip ||
426             ob == class_->radio_doc_indent) {
427                 setEnabled(class_->choice_doc_skip, skip_used);
428                 setEnabled(class_->input_doc_skip,
429                            skip_used && length_input);
430                 setEnabled(class_->choice_default_skip_units,
431                            skip_used && length_input);
432                 // Default unit choice is cm if metric, inches if US paper.
433                 // If papersize is default, check the lyxrc-settings
434                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
435                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
436                         || paperchoice == 2 || paperchoice > 5;
437                 int const default_unit = metric ? 8 : 9;
438                 if (strip(fl_get_input(class_->input_doc_skip)).empty())
439                         fl_set_choice(class_->choice_default_skip_units,
440                                       default_unit);
441         }
442
443         if (ob == options_->check_use_natbib) {
444                 setEnabled(options_->choice_citation_format,
445                            fl_get_button(options_->check_use_natbib));
446         }
447
448         if (ob == dialog_->button_save_defaults) {
449                 BufferParams params;
450                 class_apply(params);
451                 paper_apply(params);
452                 language_apply(params);
453                 options_apply(params);
454                 bullets_apply(params);
455                 saveParamsAsDefault(params);
456         }
457
458         if (ob == dialog_->button_reset_defaults) {
459                 BufferParams params = lv_->buffer()->params;
460                 params.textclass = combo_doc_class->get() - 1;
461                 params.useClassDefaults();
462                 UpdateLayoutDocument(params);
463         }
464
465         if (ob == paper_->radio_landscape)
466                 fl_set_choice(paper_->choice_paperpackage,
467                 BufferParams::PACKAGE_NONE + 1);
468
469         if (ob == paper_->choice_papersize) {
470                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
471                 bool const defsize = paperchoice == 1;
472                 bool const custom = paperchoice == 2;
473                 bool const a3size = paperchoice == 6;
474                 bool const b3size = paperchoice == 9;
475                 bool const b4size = paperchoice == 10;
476
477                 if (custom)
478                         fl_set_button(paper_->radio_portrait, 1);
479
480                 bool const use_geom = (custom || a3size || b3size || b4size);
481
482                 fl_set_button(paper_->check_use_geometry, int(use_geom));
483
484                 setEnabled(paper_->input_top_margin,    use_geom);
485                 setEnabled(paper_->input_bottom_margin, use_geom);
486                 setEnabled(paper_->input_inner_margin,  use_geom);
487                 setEnabled(paper_->input_outer_margin,  use_geom);
488                 setEnabled(paper_->input_head_height,   use_geom);
489                 setEnabled(paper_->input_head_sep,      use_geom);
490                 setEnabled(paper_->input_foot_skip,     use_geom);
491                 setEnabled(paper_->choice_top_margin_units,    use_geom);
492                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
493                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
494                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
495                 setEnabled(paper_->choice_head_height_units,   use_geom);
496                 setEnabled(paper_->choice_head_sep_units,      use_geom);
497                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
498                 setEnabled(paper_->choice_custom_width_units,  use_geom);
499                 setEnabled(paper_->choice_custom_height_units, use_geom);
500
501                 setEnabled(paper_->input_custom_width,  custom);
502                 setEnabled(paper_->input_custom_height, custom);
503                 setEnabled(paper_->choice_custom_width_units,  custom);
504                 setEnabled(paper_->choice_custom_height_units, custom);
505                 setEnabled(paper_->radio_portrait,  !custom);
506                 setEnabled(paper_->radio_landscape, !custom);
507
508                 // Default unit choice is cm if metric, inches if US paper.
509                 // If papersize is default, use the lyxrc-settings
510                 bool const metric = (defsize && lyxrc.default_papersize > 3)
511                         || paperchoice == 2 || paperchoice > 5;
512                 int const default_unit = metric ? 8 : 9;
513                 if (strip(fl_get_input(paper_->input_custom_width)).empty())
514                 fl_set_choice(paper_->choice_custom_width_units,
515                               default_unit);
516                 if (strip(fl_get_input(paper_->input_custom_height)).empty())
517                         fl_set_choice(paper_->choice_custom_height_units,
518                                       default_unit);
519                 if (strip(fl_get_input(paper_->input_top_margin)).empty())
520                         fl_set_choice(paper_->choice_top_margin_units,
521                                       default_unit);
522                 if (strip(fl_get_input(paper_->input_bottom_margin)).empty())
523                         fl_set_choice(paper_->choice_bottom_margin_units,
524                                       default_unit);
525                 if (strip(fl_get_input(paper_->input_inner_margin)).empty())
526                         fl_set_choice(paper_->choice_inner_margin_units,
527                                       default_unit);
528                 if (strip(fl_get_input(paper_->input_outer_margin)).empty())
529                         fl_set_choice(paper_->choice_outer_margin_units,
530                                       default_unit);
531                 if (strip(fl_get_input(paper_->input_head_height)).empty())
532                         fl_set_choice(paper_->choice_head_height_units,
533                                       default_unit);
534                 if (strip(fl_get_input(paper_->input_head_sep)).empty())
535                         fl_set_choice(paper_->choice_head_sep_units,
536                                       default_unit);
537                 if (strip(fl_get_input(paper_->input_foot_skip)).empty())
538                         fl_set_choice(paper_->choice_foot_skip_units,
539                                       default_unit);
540         }
541
542         if (ob == paper_->choice_papersize ||
543             ob == paper_->radio_portrait ||
544             ob == paper_->radio_landscape) {
545
546                 setEnabled(paper_->choice_paperpackage,
547                            //either default papersize (preferences)
548                            //or document papersize has to be A4
549                            (fl_get_choice(paper_->choice_papersize) == 7
550                             || fl_get_choice(paper_->choice_papersize) == 1
551                             && lyxrc.default_papersize == 5)
552                            && fl_get_button(paper_->radio_portrait));
553         }
554
555         if (ob == paper_->choice_paperpackage) {
556                 if (fl_get_choice(paper_->choice_paperpackage) != 1) {
557                         fl_set_button(paper_->check_use_geometry, 0);
558
559                         setEnabled(paper_->input_top_margin,    false);
560                         setEnabled(paper_->input_bottom_margin, false);
561                         setEnabled(paper_->input_inner_margin,  false);
562                         setEnabled(paper_->input_outer_margin,  false);
563                         setEnabled(paper_->input_head_height,   false);
564                         setEnabled(paper_->input_head_sep,      false);
565                         setEnabled(paper_->input_foot_skip,     false);
566                         setEnabled(paper_->choice_top_margin_units,    false);
567                         setEnabled(paper_->choice_bottom_margin_units, false);
568                         setEnabled(paper_->choice_inner_margin_units,  false);
569                         setEnabled(paper_->choice_outer_margin_units,  false);
570                         setEnabled(paper_->choice_head_height_units,   false);
571                         setEnabled(paper_->choice_head_sep_units,      false);
572                         setEnabled(paper_->choice_foot_skip_units,     false);
573                 }
574         }
575
576         if (ob == paper_->check_use_geometry) {
577                 //don't allow switching geometry off in custom papersize mode
578                 //nor in A3, B3, and B4
579                 int const choice = fl_get_choice(paper_->choice_papersize);
580                 if (choice == 2 || choice == 6 || choice == 9 || choice == 10)
581                         fl_set_button(paper_->check_use_geometry, 1);
582
583                 fl_set_choice(paper_->choice_paperpackage,
584                               BufferParams::PACKAGE_NONE + 1);
585
586                 bool const use_geom = fl_get_button(paper_->check_use_geometry);
587                 setEnabled(paper_->input_top_margin,    use_geom);
588                 setEnabled(paper_->input_bottom_margin, use_geom);
589                 setEnabled(paper_->input_inner_margin,  use_geom);
590                 setEnabled(paper_->input_outer_margin,  use_geom);
591                 setEnabled(paper_->input_head_height,   use_geom);
592                 setEnabled(paper_->input_head_sep,      use_geom);
593                 setEnabled(paper_->input_foot_skip,     use_geom);
594                 setEnabled(paper_->choice_top_margin_units,    use_geom);
595                 setEnabled(paper_->choice_bottom_margin_units, use_geom);
596                 setEnabled(paper_->choice_inner_margin_units,  use_geom);
597                 setEnabled(paper_->choice_outer_margin_units,  use_geom);
598                 setEnabled(paper_->choice_head_height_units,   use_geom);
599                 setEnabled(paper_->choice_head_sep_units,      use_geom);
600                 setEnabled(paper_->choice_foot_skip_units,     use_geom);
601         }
602
603         switch (data) {
604         case INPUT:
605         case CHECKCHOICECLASS:
606         case CHOICEBULLETSIZE:
607         case INPUTBULLETLATEX:
608         case BULLETBMTABLE:
609                 return CheckDocumentInput(ob, 0);
610         default:
611                 break;
612         }
613
614         return true;
615 }
616
617
618 void FormDocument::ComboInputCB(int, void * v, Combox * combox)
619 {
620         FormDocument * pre = static_cast<FormDocument*>(v);
621         if (combox == pre->combo_doc_class.get())
622                 pre->CheckChoiceClass(0, 0);
623         pre->bc().valid(pre->CheckDocumentInput(0,0));
624 }
625
626
627 bool FormDocument::class_apply(BufferParams &params)
628 {
629         bool redo = false;
630
631         // If default skip is a "Length" but there's no text in the
632         // input field, reset the kind to "Medskip", which is the default.
633         if ((fl_get_choice (class_->choice_doc_skip) == 4) &&
634             !*(fl_get_input (class_->input_doc_skip))) {
635                 fl_set_choice (class_->choice_doc_skip, 2);
636         }
637         params.fonts = fl_get_choice_text(class_->choice_doc_fonts);
638         params.fontsize = fl_get_choice_text(class_->choice_doc_fontsize);
639         params.pagestyle = fl_get_choice_text(class_->choice_doc_pagestyle);
640
641         params.textclass = combo_doc_class->get() - 1;
642         
643         BufferParams::PARSEP tmpsep = params.paragraph_separation;
644         if (fl_get_button(class_->radio_doc_indent))
645                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
646         else
647                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
648         if (tmpsep != params.paragraph_separation)
649                 redo = true;
650         
651         VSpace tmpdefskip = params.getDefSkip();
652         switch (fl_get_choice (class_->choice_doc_skip)) {
653         case 1:
654                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
655                 break;
656         case 2:
657                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
658                 break;
659         case 3:
660             params.setDefSkip(VSpace(VSpace::BIGSKIP));
661             break;
662         case 4:
663         {
664                 string const length =
665                         getLengthFromWidgets(class_->input_doc_skip,
666                                              class_->choice_default_skip_units);
667
668                 params.setDefSkip(VSpace(LyXGlueLength(length)));
669                 break;
670         }
671         default:
672                 // DocumentDefskipCB assures that this never happens
673                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
674                 break;
675         }
676         if (!(tmpdefskip == params.getDefSkip()))
677                 redo = true;
678         
679         if (fl_get_button(class_->radio_doc_columns_two))
680                 params.columns = 2;
681         else
682                 params.columns = 1;
683         if (fl_get_button(class_->radio_doc_sides_two))
684                 params.sides = LyXTextClass::TwoSides;
685         else
686                 params.sides = LyXTextClass::OneSide;
687         
688         Spacing tmpSpacing = params.spacing;
689         switch (fl_get_choice(class_->choice_doc_spacing)) {
690         case 1:
691                 lyxerr[Debug::INFO] << "Spacing: SINGLE\n";
692                 params.spacing.set(Spacing::Single);
693                 break;
694         case 2:
695                 lyxerr[Debug::INFO] << "Spacing: ONEHALF\n";
696                 params.spacing.set(Spacing::Onehalf);
697                 break;
698         case 3:
699                 lyxerr[Debug::INFO] << "Spacing: DOUBLE\n";
700                 params.spacing.set(Spacing::Double);
701                 break;
702         case 4:
703                 lyxerr[Debug::INFO] << "Spacing: OTHER\n";
704                 params.spacing.set(Spacing::Other, 
705                                    fl_get_input(class_->input_doc_spacing));
706                 break;
707         }
708         if (tmpSpacing != params.spacing)
709                 redo = true;
710         
711         params.options = fl_get_input(class_->input_doc_extra);
712         
713         return redo;
714 }
715
716
717 bool FormDocument::class_apply()
718 {
719         BufferParams &params = lv_->buffer()->params;
720
721         unsigned int const old_class = params.textclass;
722
723         bool redo = class_apply(params);
724
725         if (params.textclass != old_class) {
726                 // try to load new_class
727                 if (textclasslist.Load(params.textclass)) {
728                         // successfully loaded
729                         redo = true;
730                         setMinibuffer(lv_, _("Converting document to new document class..."));
731                         int ret = CutAndPaste::SwitchLayoutsBetweenClasses(
732                                 old_class, params.textclass,
733                                 lv_->buffer()->paragraph,
734                                 lv_->buffer()->params);
735                         if (ret) {
736                                 string s;
737                                 if (ret==1) {
738                                         s = _("One paragraph couldn't be converted");
739                                 } else {
740                                         s += tostr(ret);
741                                         s += _(" paragraphs couldn't be converted");
742                                 }
743                                 Alert::alert(_("Conversion Errors!"),s,
744                                            _("into chosen document class"));
745                         }
746                         
747                 } else {
748                         // problem changing class -- warn user and retain old style
749                         Alert::alert(_("Conversion Errors!"),
750                                    _("Errors loading new document class."),
751                                    _("Reverting to original document class."));
752                         combo_doc_class->select(int(old_class) + 1);
753                 }
754         }
755         
756         return redo;
757 }
758
759
760 void FormDocument::paper_apply(BufferParams & params)
761 {
762         params.papersize2 = char(fl_get_choice(paper_->choice_papersize)-1);
763
764         params.paperpackage =
765                 char(fl_get_choice(paper_->choice_paperpackage)-1);
766
767         // set params.papersize from params.papersize2 and params.paperpackage
768         params.setPaperStuff();
769
770         params.use_geometry = fl_get_button(paper_->check_use_geometry);
771
772         if (fl_get_button(paper_->radio_landscape))
773                 params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
774         else
775                 params.orientation = BufferParams::ORIENTATION_PORTRAIT;
776
777         params.paperwidth =
778                 getLengthFromWidgets(paper_->input_custom_width,
779                                      paper_->choice_custom_width_units);
780
781         params.paperheight =
782                 getLengthFromWidgets(paper_->input_custom_height,
783                                      paper_->choice_custom_height_units);
784
785         params.leftmargin =
786                 getLengthFromWidgets(paper_->input_inner_margin,
787                                      paper_->choice_inner_margin_units);
788
789         params.topmargin =
790                 getLengthFromWidgets(paper_->input_top_margin,
791                                      paper_->choice_top_margin_units);
792
793         params.rightmargin =
794                 getLengthFromWidgets(paper_->input_outer_margin,
795                                      paper_->choice_outer_margin_units);
796
797         params.bottommargin =
798                 getLengthFromWidgets(paper_->input_bottom_margin,
799                                      paper_->choice_bottom_margin_units);
800
801         params.headheight =
802                 getLengthFromWidgets(paper_->input_head_height,
803                                      paper_->choice_head_height_units);
804
805         params.headsep =
806                 getLengthFromWidgets(paper_->input_head_sep,
807                                      paper_->choice_head_sep_units);
808
809         params.footskip =
810                 getLengthFromWidgets(paper_->input_foot_skip,
811                                      paper_->choice_foot_skip_units);
812 }
813
814
815 void FormDocument::paper_apply()
816 {
817         paper_apply(lv_->buffer()->params);
818 }
819
820
821 bool FormDocument::language_apply(BufferParams & params)
822 {
823         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
824         bool redo = false;
825
826         switch (fl_get_choice(language_->choice_quotes_language) - 1) {
827         case 0:
828                 lga = InsetQuotes::EnglishQ;
829                 break;
830         case 1:
831                 lga = InsetQuotes::SwedishQ;
832                 break;
833         case 2:
834                 lga = InsetQuotes::GermanQ;
835                 break;
836         case 3:
837                 lga = InsetQuotes::PolishQ;
838                 break;
839         case 4:
840                 lga = InsetQuotes::FrenchQ;
841                 break;
842         case 5:
843                 lga = InsetQuotes::DanishQ;
844                 break;
845         }
846         params.quotes_language = lga;
847         if (fl_get_button(language_->radio_single))   
848                 params.quotes_times = InsetQuotes::SingleQ;
849         else
850                 params.quotes_times = InsetQuotes::DoubleQ;
851
852         Language const * old_language = params.language;
853         Language const * new_language = 
854                 languages.getLanguage(combo_language->getline());
855         if (!new_language)
856                 new_language = default_language;
857
858         if (old_language != new_language
859             && old_language->RightToLeft() == params.language->RightToLeft()
860             && !lv_->buffer()->isMultiLingual())
861                 lv_->buffer()->changeLanguage(old_language, params.language);
862
863         if (old_language != new_language) {
864                 redo = true;
865         }
866
867         params.language = new_language;
868         params.inputenc = fl_get_choice_text(language_->choice_inputenc);
869
870         return redo;
871 }
872
873
874 bool FormDocument::language_apply()
875 {
876         return language_apply(lv_->buffer()->params);
877 }
878
879
880 bool FormDocument::options_apply(BufferParams & params)
881 {
882         bool redo = false;
883
884         params.graphicsDriver =
885                 fl_get_choice_text(options_->choice_postscript_driver);
886         params.use_amsmath = fl_get_button(options_->check_use_amsmath);
887         params.use_natbib  = fl_get_button(options_->check_use_natbib);
888         params.use_numerical_citations  =
889                 fl_get_choice(options_->choice_citation_format)-1;
890
891         int tmpchar = int(fl_get_counter_value(options_->slider_secnumdepth));
892         if (params.secnumdepth != tmpchar)
893                 redo = true;
894         params.secnumdepth = tmpchar;
895    
896         params.tocdepth = int(fl_get_counter_value(options_->slider_tocdepth));
897
898         params.float_placement =
899                 fl_get_input(options_->input_float_placement);
900
901         return redo;
902 }
903
904
905 bool FormDocument::options_apply()
906 {
907         return options_apply(lv_->buffer()->params);
908 }
909
910
911 void FormDocument::bullets_apply(BufferParams & params)
912 {
913         /* update the bullet settings */
914         BufferParams & buf_params = lv_->buffer()->params;
915
916         // a little bit of loop unrolling
917         params.user_defined_bullets[0] = buf_params.temp_bullets[0];
918         params.user_defined_bullets[1] = buf_params.temp_bullets[1];
919         params.user_defined_bullets[2] = buf_params.temp_bullets[2];
920         params.user_defined_bullets[3] = buf_params.temp_bullets[3];
921 }
922
923
924 void FormDocument::bullets_apply()
925 {
926         bullets_apply(lv_->buffer()->params);
927 }
928
929
930 void FormDocument::class_update(BufferParams const & params)
931 {
932         if (!class_.get())
933                 return;
934
935         LyXTextClass const & tclass = textclasslist.TextClass(params.textclass);
936
937         combo_doc_class->select(
938                 textclasslist.DescOfClass(params.textclass));
939         fl_set_choice_text(class_->choice_doc_fonts, params.fonts.c_str());
940         fl_clear_choice(class_->choice_doc_fontsize);
941         fl_addto_choice(class_->choice_doc_fontsize, "default");
942         fl_addto_choice(class_->choice_doc_fontsize,
943                         tclass.opt_fontsize().c_str());
944         fl_set_choice(class_->choice_doc_fontsize,
945                       tokenPos(tclass.opt_fontsize(), '|', params.fontsize)+2);
946         fl_clear_choice(class_->choice_doc_pagestyle);
947         fl_addto_choice(class_->choice_doc_pagestyle, "default");
948         fl_addto_choice(class_->choice_doc_pagestyle,
949                         tclass.opt_pagestyle().c_str());
950         fl_set_choice(class_->choice_doc_pagestyle,
951                       tokenPos(tclass.opt_pagestyle(), '|', params.pagestyle)+2);
952         fl_set_button(class_->radio_doc_indent, 0);
953         fl_set_button(class_->radio_doc_skip, 0);
954         if (params.paragraph_separation == BufferParams::PARSEP_INDENT)
955                 fl_set_button(class_->radio_doc_indent, 1);
956         else
957                 fl_set_button(class_->radio_doc_skip, 1);
958
959         bool const input_length = fl_get_choice(class_->choice_doc_skip) == 4;
960         setEnabled(class_->choice_default_skip_units, input_length);
961         setEnabled(class_->input_doc_skip, input_length);
962
963         switch (params.getDefSkip().kind()) {
964         case VSpace::SMALLSKIP: 
965                 fl_set_choice (class_->choice_doc_skip, 1);
966                 break;
967         case VSpace::MEDSKIP: 
968                 fl_set_choice (class_->choice_doc_skip, 2);
969                 break;
970         case VSpace::BIGSKIP: 
971                 fl_set_choice (class_->choice_doc_skip, 3);
972                 break;
973         case VSpace::LENGTH:
974         {
975                 int const paperchoice = fl_get_choice(paper_->choice_papersize);
976                 bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
977                         || paperchoice == 2 || paperchoice > 5;
978                 string const default_unit = metric ? "cm" : "in";
979                 string const length = params.getDefSkip().asLyXCommand();
980                 updateWidgetsFromLengthString(class_->input_doc_skip,
981                                       class_->choice_default_skip_units,
982                                       length, default_unit);
983                 break;
984         }
985         default:
986                 fl_set_choice (class_->choice_doc_skip, 2);
987                 break;
988         }
989         fl_set_button(class_->radio_doc_sides_one, 0);
990         fl_set_button(class_->radio_doc_sides_two, 0);
991         setEnabled(class_->choice_doc_skip,
992                    fl_get_button(class_->radio_doc_skip));
993
994         if (params.sides == LyXTextClass::TwoSides)
995                 fl_set_button(class_->radio_doc_sides_two, 1);
996         else
997                 fl_set_button(class_->radio_doc_sides_one, 1);
998         fl_set_button(class_->radio_doc_columns_one, 0);
999         fl_set_button(class_->radio_doc_columns_two, 0);
1000         if (params.columns == 2)
1001                 fl_set_button(class_->radio_doc_columns_two, 1);
1002         else
1003                 fl_set_button(class_->radio_doc_columns_one, 1);
1004         fl_set_input(class_->input_doc_spacing, "");
1005
1006         setEnabled(class_->input_doc_spacing, input_length);
1007
1008         switch (params.spacing.getSpace()) {
1009         case Spacing::Default: // nothing bad should happen with this
1010         case Spacing::Single:
1011                 // \singlespacing
1012                 fl_set_choice(class_->choice_doc_spacing, 1);
1013                 break;
1014         case Spacing::Onehalf:
1015                 // \onehalfspacing
1016                 fl_set_choice(class_->choice_doc_spacing, 2);
1017                 break;
1018         case Spacing::Double:
1019                 // \doublespacing
1020                 fl_set_choice(class_->choice_doc_spacing, 3);
1021                 break;
1022         case Spacing::Other:
1023         {
1024                 fl_set_choice(class_->choice_doc_spacing, 4);
1025                 char sval[20];
1026                 sprintf(sval,"%g",params.spacing.getValue()); 
1027                 fl_set_input(class_->input_doc_spacing, sval);
1028                 break;
1029         }
1030         }
1031         if (!params.options.empty())
1032                 fl_set_input(class_->input_doc_extra, params.options.c_str());
1033         else
1034                 fl_set_input(class_->input_doc_extra, "");
1035 }
1036
1037
1038 void FormDocument::language_update(BufferParams const & params)
1039 {
1040         if (!language_.get())
1041                 return;
1042
1043         combo_language->select(params.language->lang());
1044         fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
1045         fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
1046         fl_set_button(language_->radio_single, 0);
1047         fl_set_button(language_->radio_double, 0);
1048         if (params.quotes_times == InsetQuotes::SingleQ)
1049                 fl_set_button(language_->radio_single, 1);
1050         else
1051                 fl_set_button(language_->radio_double, 1);
1052 }
1053
1054
1055 void FormDocument::options_update(BufferParams const & params)
1056 {
1057         if (!options_.get())
1058                 return;
1059
1060         fl_set_choice_text(options_->choice_postscript_driver,
1061                            params.graphicsDriver.c_str());
1062         fl_set_button(options_->check_use_amsmath, params.use_amsmath);
1063         fl_set_button(options_->check_use_natbib,  params.use_natbib);
1064         fl_set_choice(options_->choice_citation_format,
1065                       int(params.use_numerical_citations)+1);
1066         setEnabled(options_->choice_citation_format, params.use_natbib);
1067         fl_set_counter_value(options_->slider_secnumdepth, params.secnumdepth);
1068         fl_set_counter_value(options_->slider_tocdepth, params.tocdepth);
1069         if (!params.float_placement.empty())
1070                 fl_set_input(options_->input_float_placement,
1071                              params.float_placement.c_str());
1072         else
1073                 fl_set_input(options_->input_float_placement, "");
1074 }
1075
1076
1077 void FormDocument::paper_update(BufferParams const & params)
1078 {
1079         if (!paper_.get())
1080                 return;
1081
1082         fl_set_choice(paper_->choice_papersize, params.papersize2 + 1);
1083         fl_set_choice(paper_->choice_paperpackage, params.paperpackage + 1);
1084         fl_set_button(paper_->check_use_geometry, params.use_geometry);
1085
1086         int const paperchoice = fl_get_choice(paper_->choice_papersize);
1087         bool const useCustom = paperchoice == 2;
1088         bool const useGeom = fl_get_button(paper_->check_use_geometry);
1089
1090         fl_set_button(paper_->radio_portrait, 0);
1091         setEnabled(paper_->radio_portrait, !useCustom);
1092         fl_set_button(paper_->radio_landscape, 0);
1093         setEnabled(paper_->radio_landscape, !useCustom);
1094
1095         if (params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
1096                 fl_set_button(paper_->radio_landscape, 1);
1097         else
1098                 fl_set_button(paper_->radio_portrait, 1);
1099         setEnabled(paper_->choice_paperpackage,
1100                    //either default papersize (preferences)
1101                    //or document papersize has to be A4
1102                    (paperchoice == 7
1103                     || paperchoice == 1 && lyxrc.default_papersize == 5)
1104                    && fl_get_button(paper_->radio_portrait));
1105
1106         // Default unit choice is cm if metric, inches if US paper.
1107         bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
1108                         || paperchoice == 2 || paperchoice > 5;
1109         string const default_unit = metric ? "cm" : "in";
1110         updateWidgetsFromLengthString(paper_->input_custom_width,
1111                               paper_->choice_custom_width_units,
1112                               params.paperwidth, default_unit);
1113         setEnabled(paper_->input_custom_width, useCustom);
1114         setEnabled(paper_->choice_custom_width_units, useCustom);
1115
1116         updateWidgetsFromLengthString(paper_->input_custom_height,
1117                                       paper_->choice_custom_height_units,
1118                                       params.paperheight, default_unit);
1119         setEnabled(paper_->input_custom_height, useCustom);
1120         setEnabled(paper_->choice_custom_height_units, useCustom);
1121
1122         updateWidgetsFromLengthString(paper_->input_inner_margin,
1123                                       paper_->choice_inner_margin_units,
1124                                       params.leftmargin, default_unit);
1125         setEnabled(paper_->input_inner_margin, useGeom);
1126         setEnabled(paper_->choice_inner_margin_units, useGeom);
1127
1128         updateWidgetsFromLengthString(paper_->input_top_margin,
1129                                       paper_->choice_top_margin_units,
1130                                       params.topmargin, default_unit);
1131         setEnabled(paper_->input_top_margin, useGeom);
1132         setEnabled(paper_->choice_top_margin_units, useGeom);
1133
1134         updateWidgetsFromLengthString(paper_->input_outer_margin,
1135                                       paper_->choice_outer_margin_units,
1136                                       params.rightmargin, default_unit);
1137         setEnabled(paper_->input_outer_margin, useGeom);
1138         setEnabled(paper_->choice_outer_margin_units, useGeom);
1139
1140         updateWidgetsFromLengthString(paper_->input_bottom_margin,
1141                                       paper_->choice_bottom_margin_units,
1142                                       params.bottommargin, default_unit);
1143         setEnabled(paper_->input_bottom_margin, useGeom);
1144         setEnabled(paper_->choice_bottom_margin_units, useGeom);
1145
1146         updateWidgetsFromLengthString(paper_->input_head_height,
1147                                       paper_->choice_head_height_units,
1148                                       params.headheight, default_unit);
1149         setEnabled(paper_->input_head_height, useGeom);
1150         setEnabled(paper_->choice_head_height_units, useGeom);
1151
1152         updateWidgetsFromLengthString(paper_->input_head_sep,
1153                                       paper_->choice_head_sep_units,
1154                                       params.headsep, default_unit);
1155         setEnabled(paper_->input_head_sep, useGeom);
1156         setEnabled(paper_->choice_head_sep_units, useGeom);
1157
1158         updateWidgetsFromLengthString(paper_->input_foot_skip,
1159                                       paper_->choice_foot_skip_units,
1160                                       params.footskip, default_unit);
1161         setEnabled(paper_->input_foot_skip, useGeom);
1162         setEnabled(paper_->choice_foot_skip_units, useGeom);
1163
1164         fl_set_focus_object(paper_->form, paper_->choice_papersize);
1165 }
1166
1167
1168 void FormDocument::bullets_update(BufferParams const & params)
1169 {
1170         if (!bullets_.get() ||
1171             ((XpmVersion<4) ||
1172              (XpmVersion==4 && XpmRevision<7)))
1173                 return;
1174
1175         bool const isLinuxDoc = lv_->buffer()->isLinuxDoc();
1176         setEnabled(fbullet, !isLinuxDoc);
1177
1178         if (isLinuxDoc) return;
1179
1180         fl_set_button(bullets_->radio_bullet_depth_1, 1);
1181         fl_set_input(bullets_->input_bullet_latex,
1182                      params.user_defined_bullets[0].getText().c_str());
1183         fl_set_choice(bullets_->choice_bullet_size,
1184                       params.user_defined_bullets[0].getSize() + 2);
1185 }
1186
1187
1188 void FormDocument::checkReadOnly()
1189 {
1190         if (bc().readOnly(lv_->buffer()->isReadonly())) {
1191                 combo_doc_class->deactivate();
1192                 combo_language->deactivate();
1193                 fl_set_object_label(dialog_->text_warning,
1194                                     _("Document is read-only."
1195                                       " No changes to layout permitted."));
1196                 fl_show_object(dialog_->text_warning);
1197         } else {
1198                 combo_doc_class->activate();
1199                 combo_language->activate();
1200                 fl_hide_object(dialog_->text_warning);
1201         }
1202 }
1203
1204
1205 bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
1206 {
1207         string str;
1208         bool ok = true;
1209         char const * input;
1210
1211         // this has to be all out of if/elseif because it has to deactivate
1212         // the document buttons and so the whole stuff has to be tested again.
1213         // disable OK/Apply if input is not valid
1214         str = fl_get_input(class_->input_doc_skip);
1215         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1216         str = fl_get_input(paper_->input_custom_width);
1217         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1218         str = fl_get_input(paper_->input_custom_height);
1219         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1220         str = fl_get_input(paper_->input_outer_margin);
1221         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1222         str = fl_get_input(paper_->input_inner_margin);
1223         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1224         str = fl_get_input(paper_->input_top_margin);
1225         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1226         str = fl_get_input(paper_->input_bottom_margin);
1227         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1228         str = fl_get_input(paper_->input_head_height);
1229         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1230         str = fl_get_input(paper_->input_head_sep);
1231         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1232         str = fl_get_input(paper_->input_foot_skip);
1233         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1234
1235         //display warning if input is not valid
1236         if (ob == class_->input_doc_skip
1237                         || ob == paper_->input_custom_width
1238                         || ob == paper_->input_custom_height
1239                         || ob == paper_->input_outer_margin
1240                         || ob == paper_->input_inner_margin
1241                         || ob == paper_->input_top_margin
1242                         || ob == paper_->input_bottom_margin
1243                         || ob == paper_->input_head_height
1244                         || ob == paper_->input_head_sep
1245                         || ob == paper_->input_foot_skip) {
1246                 if (!ok) {
1247                         fl_set_object_label(dialog_->text_warning,
1248                                 _("Warning: Invalid Length (valid example: 10mm)"));
1249                         fl_show_object(dialog_->text_warning);
1250                         return false;
1251                 } else {
1252                         fl_hide_object(dialog_->text_warning);
1253                         return true;
1254                 }
1255         }
1256
1257         // "Synchronize" the choice and the input field, so that it
1258         // is impossible to commit senseless data.
1259         input = fl_get_input (class_->input_doc_skip);
1260         if ((fl_get_choice(class_->choice_doc_skip) == 4) && !*input)
1261                 ok = false;
1262         else if (fl_get_choice(class_->choice_doc_skip) != 4)
1263                 fl_set_input (class_->input_doc_skip, "");
1264
1265         input = fl_get_input(class_->input_doc_spacing);
1266         if ((fl_get_choice(class_->choice_doc_spacing) == 4) && !*input)
1267                 ok = false;
1268         else if (fl_get_choice(class_->choice_doc_spacing) != 4)
1269                 fl_set_input (class_->input_doc_spacing, "");
1270         return ok;
1271 }
1272
1273
1274 void FormDocument::ChoiceBulletSize(FL_OBJECT * ob, long /*data*/ )
1275 {
1276         BufferParams & param = lv_->buffer()->params;
1277
1278         // convert from 1-6 range to -1-4 
1279         param.temp_bullets[current_bullet_depth].setSize(fl_get_choice(ob) - 2);
1280         fl_set_input(bullets_->input_bullet_latex,
1281                      param.temp_bullets[current_bullet_depth].getText().c_str());
1282 }
1283
1284
1285 void FormDocument::InputBulletLaTeX(FL_OBJECT *, long)
1286 {
1287         BufferParams & param = lv_->buffer()->params;
1288
1289         param.temp_bullets[current_bullet_depth].
1290                 setText(fl_get_input(bullets_->input_bullet_latex));
1291 }
1292
1293
1294 void FormDocument::BulletDepth(FL_OBJECT * ob, State cb)
1295 {
1296         /* Should I do the following:                                 */
1297         /*  1. change to the panel that the current bullet belongs in */
1298         /*  2. show that bullet as selected                           */
1299         /*  3. change the size setting to the size of the bullet in Q.*/
1300         /*  4. display the latex equivalent in the latex box          */
1301         /*                                                            */
1302         /* I'm inclined to just go with 3 and 4 at the moment and     */
1303         /* maybe try to support the others later                      */
1304         BufferParams & param = lv_->buffer()->params;
1305
1306         int data = 0;
1307         if (cb == BULLETDEPTH1 )
1308                 data = 0;
1309         else if (cb == BULLETDEPTH2 )
1310                 data = 1;
1311         else if (cb == BULLETDEPTH3 )
1312                 data = 2;
1313         else if (cb == BULLETDEPTH4 )
1314                 data = 3;
1315
1316         switch (fl_get_button_numb(ob)) {
1317         case 3:
1318                 // right mouse button resets to default
1319                 param.temp_bullets[data] = ITEMIZE_DEFAULTS[data];
1320         default:
1321                 current_bullet_depth = data;
1322                 fl_set_input(bullets_->input_bullet_latex,
1323                              param.temp_bullets[data].getText().c_str());
1324                 fl_set_choice(bullets_->choice_bullet_size,
1325                               param.temp_bullets[data].getSize() + 2);
1326         }
1327 }
1328
1329
1330 void FormDocument::BulletPanel(FL_OBJECT * /*ob*/, State cb)
1331 {
1332         /* Here we have to change the background pixmap to that selected */
1333         /* by the user. (eg. standard.xpm, psnfss1.xpm etc...)           */
1334     
1335         int data = 0;
1336         if (cb == BULLETPANEL1 )
1337                 data = 0;
1338         else if (cb == BULLETPANEL2 )
1339                 data = 1;
1340         else if (cb == BULLETPANEL3 )
1341                 data = 2;
1342         else if (cb == BULLETPANEL4 )
1343                 data = 3;
1344         else if (cb == BULLETPANEL5 )
1345                 data = 4;
1346         else if (cb == BULLETPANEL6 )
1347                 data = 5;
1348
1349         if (data != current_bullet_panel) {
1350                 fl_freeze_form(bullets_->form);
1351                 current_bullet_panel = data;
1352
1353                 /* free the current pixmap */
1354                 fl_free_bmtable_pixmap(bullets_->bmtable_bullet_panel);
1355                 string new_panel;
1356                 switch (cb) {
1357                         /* display the new one */
1358                 case BULLETPANEL1 :
1359                         new_panel = "standard";
1360                         break;
1361                 case BULLETPANEL2 :
1362                         new_panel = "amssymb";
1363                         break;
1364                 case BULLETPANEL3 :
1365                         new_panel = "psnfss1";
1366                         break;
1367                 case BULLETPANEL4 :
1368                         new_panel = "psnfss2";
1369                         break;
1370                 case BULLETPANEL5 :
1371                         new_panel = "psnfss3";
1372                         break;
1373                 case BULLETPANEL6 :
1374                         new_panel = "psnfss4";
1375                         break;
1376                 default :
1377                         /* something very wrong happened */
1378                         // play it safe for now but should be an exception
1379                         current_bullet_panel = 0;  // standard panel
1380                         new_panel = "standard";
1381                         break;
1382                 }
1383                 new_panel += ".xpm";
1384                 fl_set_bmtable_pixmap_file(bullets_->bmtable_bullet_panel, 6, 6,
1385                                            LibFileSearch("images", new_panel).c_str());
1386                 fl_redraw_object(bullets_->bmtable_bullet_panel);
1387                 fl_unfreeze_form(bullets_->form);
1388         }
1389 }
1390
1391
1392 void FormDocument::BulletBMTable(FL_OBJECT * ob, long /*data*/ )
1393 {
1394         /* handle the user input by setting the current bullet depth's pixmap */
1395         /* to that extracted from the current chosen position of the BMTable  */
1396         /* Don't forget to free the button's old pixmap first.                */
1397         
1398         BufferParams & param = lv_->buffer()->params;
1399         int bmtable_button = fl_get_bmtable(ob);
1400         
1401         /* try to keep the button held down till another is pushed */
1402         /*  fl_set_bmtable(ob, 1, bmtable_button); */
1403         param.temp_bullets[current_bullet_depth].setFont(current_bullet_panel);
1404         param.temp_bullets[current_bullet_depth].setCharacter(bmtable_button);
1405         fl_set_input(bullets_->input_bullet_latex,
1406                      param.temp_bullets[current_bullet_depth].getText().c_str());
1407 }
1408
1409
1410 void FormDocument::CheckChoiceClass(FL_OBJECT * ob, long)
1411 {
1412         if (!ob)
1413                 ob = class_->choice_doc_class;
1414
1415         lv_->prohibitInput();
1416
1417         unsigned int tc = combo_doc_class->get() - 1;
1418         if (textclasslist.Load(tc)) {
1419                 // we use a copy of the bufferparams because we do not
1420                 // want to modify them yet.
1421                 BufferParams params = lv_->buffer()->params;
1422
1423                 if (lyxrc.auto_reset_options) {
1424                         params.textclass = tc;
1425                         params.useClassDefaults();
1426                         UpdateLayoutDocument(params);
1427                 }
1428         } else {
1429                 // unable to load new style
1430                 Alert::alert(_("Conversion Errors!"),
1431                            _("Unable to switch to new document class."),
1432                            _("Reverting to original document class."));
1433                 combo_doc_class->select(int(lv_->buffer()->params.textclass) + 1);
1434         }
1435         lv_->allowInput();
1436 }
1437
1438
1439 void FormDocument::UpdateLayoutDocument(BufferParams const & params)
1440 {
1441         if (!dialog_.get())
1442                 return;
1443
1444         checkReadOnly();
1445         class_update(params);
1446         paper_update(params);
1447         language_update(params);
1448         options_update(params);
1449         bullets_update(params);
1450 }