]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormDocument.C
Bugfixes: checkboxes to radiobuttons (from J�rgen S) and remove a little
[lyx.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  
1005         fl_set_input(class_->input_doc_spacing, "");
1006         setEnabled(class_->input_doc_spacing, false);
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                 setEnabled(class_->input_doc_spacing, true);
1029                 break;
1030         }
1031         }
1032         if (!params.options.empty())
1033                 fl_set_input(class_->input_doc_extra, params.options.c_str());
1034         else
1035                 fl_set_input(class_->input_doc_extra, "");
1036 }
1037
1038
1039 void FormDocument::language_update(BufferParams const & params)
1040 {
1041         if (!language_.get())
1042                 return;
1043
1044         combo_language->select(params.language->lang());
1045         fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
1046         fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
1047         fl_set_button(language_->radio_single, 0);
1048         fl_set_button(language_->radio_double, 0);
1049         if (params.quotes_times == InsetQuotes::SingleQ)
1050                 fl_set_button(language_->radio_single, 1);
1051         else
1052                 fl_set_button(language_->radio_double, 1);
1053 }
1054
1055
1056 void FormDocument::options_update(BufferParams const & params)
1057 {
1058         if (!options_.get())
1059                 return;
1060
1061         fl_set_choice_text(options_->choice_postscript_driver,
1062                            params.graphicsDriver.c_str());
1063         fl_set_button(options_->check_use_amsmath, params.use_amsmath);
1064         fl_set_button(options_->check_use_natbib,  params.use_natbib);
1065         fl_set_choice(options_->choice_citation_format,
1066                       int(params.use_numerical_citations)+1);
1067         setEnabled(options_->choice_citation_format, params.use_natbib);
1068         fl_set_counter_value(options_->slider_secnumdepth, params.secnumdepth);
1069         fl_set_counter_value(options_->slider_tocdepth, params.tocdepth);
1070         if (!params.float_placement.empty())
1071                 fl_set_input(options_->input_float_placement,
1072                              params.float_placement.c_str());
1073         else
1074                 fl_set_input(options_->input_float_placement, "");
1075 }
1076
1077
1078 void FormDocument::paper_update(BufferParams const & params)
1079 {
1080         if (!paper_.get())
1081                 return;
1082
1083         fl_set_choice(paper_->choice_papersize, params.papersize2 + 1);
1084         fl_set_choice(paper_->choice_paperpackage, params.paperpackage + 1);
1085         fl_set_button(paper_->check_use_geometry, params.use_geometry);
1086
1087         int const paperchoice = fl_get_choice(paper_->choice_papersize);
1088         bool const useCustom = paperchoice == 2;
1089         bool const useGeom = fl_get_button(paper_->check_use_geometry);
1090
1091         fl_set_button(paper_->radio_portrait, 0);
1092         setEnabled(paper_->radio_portrait, !useCustom);
1093         fl_set_button(paper_->radio_landscape, 0);
1094         setEnabled(paper_->radio_landscape, !useCustom);
1095
1096         if (params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
1097                 fl_set_button(paper_->radio_landscape, 1);
1098         else
1099                 fl_set_button(paper_->radio_portrait, 1);
1100         setEnabled(paper_->choice_paperpackage,
1101                    //either default papersize (preferences)
1102                    //or document papersize has to be A4
1103                    (paperchoice == 7
1104                     || paperchoice == 1 && lyxrc.default_papersize == 5)
1105                    && fl_get_button(paper_->radio_portrait));
1106
1107         // Default unit choice is cm if metric, inches if US paper.
1108         bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
1109                         || paperchoice == 2 || paperchoice > 5;
1110         string const default_unit = metric ? "cm" : "in";
1111         updateWidgetsFromLengthString(paper_->input_custom_width,
1112                               paper_->choice_custom_width_units,
1113                               params.paperwidth, default_unit);
1114         setEnabled(paper_->input_custom_width, useCustom);
1115         setEnabled(paper_->choice_custom_width_units, useCustom);
1116
1117         updateWidgetsFromLengthString(paper_->input_custom_height,
1118                                       paper_->choice_custom_height_units,
1119                                       params.paperheight, default_unit);
1120         setEnabled(paper_->input_custom_height, useCustom);
1121         setEnabled(paper_->choice_custom_height_units, useCustom);
1122
1123         updateWidgetsFromLengthString(paper_->input_inner_margin,
1124                                       paper_->choice_inner_margin_units,
1125                                       params.leftmargin, default_unit);
1126         setEnabled(paper_->input_inner_margin, useGeom);
1127         setEnabled(paper_->choice_inner_margin_units, useGeom);
1128
1129         updateWidgetsFromLengthString(paper_->input_top_margin,
1130                                       paper_->choice_top_margin_units,
1131                                       params.topmargin, default_unit);
1132         setEnabled(paper_->input_top_margin, useGeom);
1133         setEnabled(paper_->choice_top_margin_units, useGeom);
1134
1135         updateWidgetsFromLengthString(paper_->input_outer_margin,
1136                                       paper_->choice_outer_margin_units,
1137                                       params.rightmargin, default_unit);
1138         setEnabled(paper_->input_outer_margin, useGeom);
1139         setEnabled(paper_->choice_outer_margin_units, useGeom);
1140
1141         updateWidgetsFromLengthString(paper_->input_bottom_margin,
1142                                       paper_->choice_bottom_margin_units,
1143                                       params.bottommargin, default_unit);
1144         setEnabled(paper_->input_bottom_margin, useGeom);
1145         setEnabled(paper_->choice_bottom_margin_units, useGeom);
1146
1147         updateWidgetsFromLengthString(paper_->input_head_height,
1148                                       paper_->choice_head_height_units,
1149                                       params.headheight, default_unit);
1150         setEnabled(paper_->input_head_height, useGeom);
1151         setEnabled(paper_->choice_head_height_units, useGeom);
1152
1153         updateWidgetsFromLengthString(paper_->input_head_sep,
1154                                       paper_->choice_head_sep_units,
1155                                       params.headsep, default_unit);
1156         setEnabled(paper_->input_head_sep, useGeom);
1157         setEnabled(paper_->choice_head_sep_units, useGeom);
1158
1159         updateWidgetsFromLengthString(paper_->input_foot_skip,
1160                                       paper_->choice_foot_skip_units,
1161                                       params.footskip, default_unit);
1162         setEnabled(paper_->input_foot_skip, useGeom);
1163         setEnabled(paper_->choice_foot_skip_units, useGeom);
1164
1165         fl_set_focus_object(paper_->form, paper_->choice_papersize);
1166 }
1167
1168
1169 void FormDocument::bullets_update(BufferParams const & params)
1170 {
1171         if (!bullets_.get() ||
1172             ((XpmVersion<4) ||
1173              (XpmVersion==4 && XpmRevision<7)))
1174                 return;
1175
1176         bool const isLinuxDoc = lv_->buffer()->isLinuxDoc();
1177         setEnabled(fbullet, !isLinuxDoc);
1178
1179         if (isLinuxDoc) return;
1180
1181         fl_set_button(bullets_->radio_bullet_depth_1, 1);
1182         fl_set_input(bullets_->input_bullet_latex,
1183                      params.user_defined_bullets[0].getText().c_str());
1184         fl_set_choice(bullets_->choice_bullet_size,
1185                       params.user_defined_bullets[0].getSize() + 2);
1186 }
1187
1188
1189 void FormDocument::checkReadOnly()
1190 {
1191         if (bc().readOnly(lv_->buffer()->isReadonly())) {
1192                 combo_doc_class->deactivate();
1193                 combo_language->deactivate();
1194                 fl_set_object_label(dialog_->text_warning,
1195                                     _("Document is read-only."
1196                                       " No changes to layout permitted."));
1197                 fl_show_object(dialog_->text_warning);
1198         } else {
1199                 combo_doc_class->activate();
1200                 combo_language->activate();
1201                 fl_hide_object(dialog_->text_warning);
1202         }
1203 }
1204
1205
1206 bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
1207 {
1208         string str;
1209         bool ok = true;
1210         char const * input;
1211
1212         // this has to be all out of if/elseif because it has to deactivate
1213         // the document buttons and so the whole stuff has to be tested again.
1214         // disable OK/Apply if input is not valid
1215         str = fl_get_input(class_->input_doc_skip);
1216         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1217         str = fl_get_input(paper_->input_custom_width);
1218         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1219         str = fl_get_input(paper_->input_custom_height);
1220         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1221         str = fl_get_input(paper_->input_outer_margin);
1222         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1223         str = fl_get_input(paper_->input_inner_margin);
1224         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1225         str = fl_get_input(paper_->input_top_margin);
1226         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1227         str = fl_get_input(paper_->input_bottom_margin);
1228         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1229         str = fl_get_input(paper_->input_head_height);
1230         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1231         str = fl_get_input(paper_->input_head_sep);
1232         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1233         str = fl_get_input(paper_->input_foot_skip);
1234         ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
1235
1236         //display warning if input is not valid
1237         if (ob == class_->input_doc_skip
1238                         || ob == paper_->input_custom_width
1239                         || ob == paper_->input_custom_height
1240                         || ob == paper_->input_outer_margin
1241                         || ob == paper_->input_inner_margin
1242                         || ob == paper_->input_top_margin
1243                         || ob == paper_->input_bottom_margin
1244                         || ob == paper_->input_head_height
1245                         || ob == paper_->input_head_sep
1246                         || ob == paper_->input_foot_skip) {
1247                 if (!ok) {
1248                         fl_set_object_label(dialog_->text_warning,
1249                                 _("Warning: Invalid Length (valid example: 10mm)"));
1250                         fl_show_object(dialog_->text_warning);
1251                         return false;
1252                 } else {
1253                         fl_hide_object(dialog_->text_warning);
1254                         return true;
1255                 }
1256         }
1257
1258         // "Synchronize" the choice and the input field, so that it
1259         // is impossible to commit senseless data.
1260         input = fl_get_input (class_->input_doc_skip);
1261         if ((fl_get_choice(class_->choice_doc_skip) == 4) && !*input)
1262                 ok = false;
1263         else if (fl_get_choice(class_->choice_doc_skip) != 4)
1264                 fl_set_input (class_->input_doc_skip, "");
1265
1266         input = fl_get_input(class_->input_doc_spacing);
1267         if ((fl_get_choice(class_->choice_doc_spacing) == 4) && !*input)
1268                 ok = false;
1269         else if (fl_get_choice(class_->choice_doc_spacing) != 4)
1270                 fl_set_input (class_->input_doc_spacing, "");
1271         return ok;
1272 }
1273
1274
1275 void FormDocument::ChoiceBulletSize(FL_OBJECT * ob, long /*data*/ )
1276 {
1277         BufferParams & param = lv_->buffer()->params;
1278
1279         // convert from 1-6 range to -1-4 
1280         param.temp_bullets[current_bullet_depth].setSize(fl_get_choice(ob) - 2);
1281         fl_set_input(bullets_->input_bullet_latex,
1282                      param.temp_bullets[current_bullet_depth].getText().c_str());
1283 }
1284
1285
1286 void FormDocument::InputBulletLaTeX(FL_OBJECT *, long)
1287 {
1288         BufferParams & param = lv_->buffer()->params;
1289
1290         param.temp_bullets[current_bullet_depth].
1291                 setText(fl_get_input(bullets_->input_bullet_latex));
1292 }
1293
1294
1295 void FormDocument::BulletDepth(FL_OBJECT * ob, State cb)
1296 {
1297         /* Should I do the following:                                 */
1298         /*  1. change to the panel that the current bullet belongs in */
1299         /*  2. show that bullet as selected                           */
1300         /*  3. change the size setting to the size of the bullet in Q.*/
1301         /*  4. display the latex equivalent in the latex box          */
1302         /*                                                            */
1303         /* I'm inclined to just go with 3 and 4 at the moment and     */
1304         /* maybe try to support the others later                      */
1305         BufferParams & param = lv_->buffer()->params;
1306
1307         int data = 0;
1308         if (cb == BULLETDEPTH1 )
1309                 data = 0;
1310         else if (cb == BULLETDEPTH2 )
1311                 data = 1;
1312         else if (cb == BULLETDEPTH3 )
1313                 data = 2;
1314         else if (cb == BULLETDEPTH4 )
1315                 data = 3;
1316
1317         switch (fl_get_button_numb(ob)) {
1318         case 3:
1319                 // right mouse button resets to default
1320                 param.temp_bullets[data] = ITEMIZE_DEFAULTS[data];
1321         default:
1322                 current_bullet_depth = data;
1323                 fl_set_input(bullets_->input_bullet_latex,
1324                              param.temp_bullets[data].getText().c_str());
1325                 fl_set_choice(bullets_->choice_bullet_size,
1326                               param.temp_bullets[data].getSize() + 2);
1327         }
1328 }
1329
1330
1331 void FormDocument::BulletPanel(FL_OBJECT * /*ob*/, State cb)
1332 {
1333         /* Here we have to change the background pixmap to that selected */
1334         /* by the user. (eg. standard.xpm, psnfss1.xpm etc...)           */
1335     
1336         int data = 0;
1337         if (cb == BULLETPANEL1 )
1338                 data = 0;
1339         else if (cb == BULLETPANEL2 )
1340                 data = 1;
1341         else if (cb == BULLETPANEL3 )
1342                 data = 2;
1343         else if (cb == BULLETPANEL4 )
1344                 data = 3;
1345         else if (cb == BULLETPANEL5 )
1346                 data = 4;
1347         else if (cb == BULLETPANEL6 )
1348                 data = 5;
1349
1350         if (data != current_bullet_panel) {
1351                 fl_freeze_form(bullets_->form);
1352                 current_bullet_panel = data;
1353
1354                 /* free the current pixmap */
1355                 fl_free_bmtable_pixmap(bullets_->bmtable_bullet_panel);
1356                 string new_panel;
1357                 switch (cb) {
1358                         /* display the new one */
1359                 case BULLETPANEL1 :
1360                         new_panel = "standard";
1361                         break;
1362                 case BULLETPANEL2 :
1363                         new_panel = "amssymb";
1364                         break;
1365                 case BULLETPANEL3 :
1366                         new_panel = "psnfss1";
1367                         break;
1368                 case BULLETPANEL4 :
1369                         new_panel = "psnfss2";
1370                         break;
1371                 case BULLETPANEL5 :
1372                         new_panel = "psnfss3";
1373                         break;
1374                 case BULLETPANEL6 :
1375                         new_panel = "psnfss4";
1376                         break;
1377                 default :
1378                         /* something very wrong happened */
1379                         // play it safe for now but should be an exception
1380                         current_bullet_panel = 0;  // standard panel
1381                         new_panel = "standard";
1382                         break;
1383                 }
1384                 new_panel += ".xpm";
1385                 fl_set_bmtable_pixmap_file(bullets_->bmtable_bullet_panel, 6, 6,
1386                                            LibFileSearch("images", new_panel).c_str());
1387                 fl_redraw_object(bullets_->bmtable_bullet_panel);
1388                 fl_unfreeze_form(bullets_->form);
1389         }
1390 }
1391
1392
1393 void FormDocument::BulletBMTable(FL_OBJECT * ob, long /*data*/ )
1394 {
1395         /* handle the user input by setting the current bullet depth's pixmap */
1396         /* to that extracted from the current chosen position of the BMTable  */
1397         /* Don't forget to free the button's old pixmap first.                */
1398         
1399         BufferParams & param = lv_->buffer()->params;
1400         int bmtable_button = fl_get_bmtable(ob);
1401         
1402         /* try to keep the button held down till another is pushed */
1403         /*  fl_set_bmtable(ob, 1, bmtable_button); */
1404         param.temp_bullets[current_bullet_depth].setFont(current_bullet_panel);
1405         param.temp_bullets[current_bullet_depth].setCharacter(bmtable_button);
1406         fl_set_input(bullets_->input_bullet_latex,
1407                      param.temp_bullets[current_bullet_depth].getText().c_str());
1408 }
1409
1410
1411 void FormDocument::CheckChoiceClass(FL_OBJECT * ob, long)
1412 {
1413         if (!ob)
1414                 ob = class_->choice_doc_class;
1415
1416         lv_->prohibitInput();
1417
1418         unsigned int tc = combo_doc_class->get() - 1;
1419         if (textclasslist.Load(tc)) {
1420                 // we use a copy of the bufferparams because we do not
1421                 // want to modify them yet.
1422                 BufferParams params = lv_->buffer()->params;
1423
1424                 if (lyxrc.auto_reset_options) {
1425                         params.textclass = tc;
1426                         params.useClassDefaults();
1427                         UpdateLayoutDocument(params);
1428                 }
1429         } else {
1430                 // unable to load new style
1431                 Alert::alert(_("Conversion Errors!"),
1432                            _("Unable to switch to new document class."),
1433                            _("Reverting to original document class."));
1434                 combo_doc_class->select(int(lv_->buffer()->params.textclass) + 1);
1435         }
1436         lv_->allowInput();
1437 }
1438
1439
1440 void FormDocument::UpdateLayoutDocument(BufferParams const & params)
1441 {
1442         if (!dialog_.get())
1443                 return;
1444
1445         checkReadOnly();
1446         class_update(params);
1447         paper_update(params);
1448         language_update(params);
1449         options_update(params);
1450         bullets_update(params);
1451 }