]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormDocument.C
7e865f23a2c87492a2c3d6fbff7ecb1dbd8c94b8
[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 "lyx_gui_misc.h"
22
23 #include "FormDocument.h"
24 #include "form_document.h"
25 #include "Dialogs.h"
26 #include "layout.h"
27 #include "combox.h"
28 #include "tex-strings.h"
29 #include "bufferparams.h"
30 #include "insets/insetquotes.h"
31 #include "vspace.h"
32 #include "bmtable.h"
33 #include "support/filetools.h"
34 #include "language.h"
35 #include "LyXView.h"
36 #include "BufferView.h"
37 #include "buffer.h"
38 #include "Liason.h"
39 #include "CutAndPaste.h"
40 #include "bufferview_funcs.h"
41 #include "xforms_helpers.h" 
42 #include "debug.h"
43
44 using Liason::setMinibuffer;
45 using SigC::slot;
46
47 FormDocument::FormDocument(LyXView * lv, Dialogs * d)
48         : FormBaseBD(lv, d, _("Document Layout")), fbullet(0)
49 {
50     // let the dialog be shown
51     // This is a permanent connection so we won't bother
52     // storing a copy because we won't be disconnecting.
53     d->showDocument.connect(slot(this, &FormDocument::show));
54 }
55
56
57 void FormDocument::redraw()
58 {
59         if( form() && form()->visible )
60                 fl_redraw_form( form() );
61         else
62                 return;
63
64         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabbed_folder);
65         if (outer_form && outer_form->visible)
66                 fl_redraw_form( outer_form );
67 }
68
69
70 FL_FORM * FormDocument::form() const
71 {
72     if (dialog_.get()) return dialog_->form;
73     return 0;
74 }
75
76
77 void FormDocument::build()
78 {
79     int n;
80
81     // the tabbed folder
82     dialog_.reset(build_tabbed_document());
83
84     // Manage the restore, ok, apply, restore and cancel/close buttons
85     bc().setOK(dialog_->button_ok);
86     bc().setApply(dialog_->button_apply);
87     bc().setCancel(dialog_->button_cancel);
88     bc().setRestore(dialog_->button_restore);
89
90     // the document paper form
91     paper_.reset(build_doc_paper());
92     fl_addto_choice(paper_->choice_papersize2,
93                     _(" Default | Custom | USletter | USlegal "
94                       "| USexecutive | A3 | A4 | A5 | B3 | B4 | B5 "));
95     fl_addto_choice(paper_->choice_paperpackage,
96                     _(" None "
97                       "| A4 small Margins (only portrait) "
98                       "| A4 very small Margins (only portrait) "
99                       "| A4 very wide margins (only portrait) "));
100     fl_set_input_return(paper_->input_custom_width, FL_RETURN_CHANGED);
101     fl_set_input_return(paper_->input_custom_height, FL_RETURN_CHANGED);
102     fl_set_input_return(paper_->input_top_margin, FL_RETURN_CHANGED);
103     fl_set_input_return(paper_->input_bottom_margin, FL_RETURN_CHANGED);
104     fl_set_input_return(paper_->input_left_margin, FL_RETURN_CHANGED);
105     fl_set_input_return(paper_->input_right_margin, FL_RETURN_CHANGED);
106     fl_set_input_return(paper_->input_head_height, FL_RETURN_CHANGED);
107     fl_set_input_return(paper_->input_head_sep, FL_RETURN_CHANGED);
108     fl_set_input_return(paper_->input_foot_skip, FL_RETURN_CHANGED);
109
110     bc().addReadOnly (paper_->choice_paperpackage);
111     bc().addReadOnly (paper_->greoup_radio_orientation);
112     bc().addReadOnly (paper_->radio_portrait);
113     bc().addReadOnly (paper_->radio_landscape);
114     bc().addReadOnly (paper_->choice_papersize2);
115     bc().addReadOnly (paper_->push_use_geometry);
116     bc().addReadOnly (paper_->input_custom_width);
117     bc().addReadOnly (paper_->input_custom_height);
118     bc().addReadOnly (paper_->input_top_margin);
119     bc().addReadOnly (paper_->input_bottom_margin);
120     bc().addReadOnly (paper_->input_left_margin);
121     bc().addReadOnly (paper_->input_right_margin);
122     bc().addReadOnly (paper_->input_head_height);
123     bc().addReadOnly (paper_->input_head_sep);
124     bc().addReadOnly (paper_->input_foot_skip);
125
126     // the document class form
127     class_.reset(build_doc_class());
128
129     FL_OBJECT * obj;
130     // The language is a combo-box and has to be inserted manually
131     obj = class_->choice_doc_class;
132     fl_deactivate_object(obj);
133     fl_addto_form(class_->form);
134     combo_doc_class.reset(new Combox(FL_COMBOX_DROPLIST));
135     combo_doc_class->add(obj->x, obj->y, obj->w, obj->h, 400,
136                          dialog_->tabbed_folder);
137     combo_doc_class->shortcut("#C",1);
138     combo_doc_class->setcallback(ComboInputCB, this);
139     fl_end_form();
140     for (LyXTextClassList::const_iterator cit = textclasslist.begin();
141          cit != textclasslist.end(); ++cit)
142     {
143         combo_doc_class->addto(cit->description());
144     }
145
146     fl_addto_choice(class_->choice_doc_spacing,
147                     _(" Single | OneHalf | Double | Other "));
148     fl_addto_choice(class_->choice_doc_fontsize, "default|10|11|12");
149    for (n=0; tex_fonts[n][0]; ++n) {
150         fl_addto_choice(class_->choice_doc_fonts,tex_fonts[n]);
151     }
152     fl_addto_choice(class_->choice_doc_pagestyle,
153                     "default|empty|plain|headings|fancy");
154     fl_addto_choice(class_->choice_doc_skip,
155                     _(" Smallskip | Medskip | Bigskip | Length "));
156     fl_set_input_return(class_->input_doc_extra, FL_RETURN_CHANGED);
157     fl_set_input_return(class_->input_doc_skip, FL_RETURN_CHANGED);
158     fl_set_input_return(class_->input_doc_spacing, FL_RETURN_CHANGED);
159
160     bc().addReadOnly (class_->radio_doc_indent);
161     bc().addReadOnly (class_->radio_doc_skip);
162
163     bc().addReadOnly (class_->choice_doc_pagestyle);
164     bc().addReadOnly (class_->choice_doc_fonts);
165     bc().addReadOnly (class_->choice_doc_fontsize);
166     bc().addReadOnly (class_->radio_doc_sides_one);
167     bc().addReadOnly (class_->radio_doc_sides_two);
168     bc().addReadOnly (class_->radio_doc_columns_one);
169     bc().addReadOnly (class_->radio_doc_columns_two);
170     bc().addReadOnly (class_->input_doc_extra);
171     bc().addReadOnly (class_->input_doc_skip);
172     bc().addReadOnly (class_->choice_doc_skip);
173     bc().addReadOnly (class_->choice_doc_spacing);
174     bc().addReadOnly (class_->input_doc_spacing);
175
176     // the document language form
177     language_.reset(build_doc_language());
178     fl_addto_choice(language_->choice_inputenc,
179                     "default|auto|latin1|latin2|latin5|latin9"
180                     "|koi8-r|koi8-u|cp866|cp1251|iso88595");
181
182     // The language is a combo-box and has to be inserted manually
183     obj = language_->choice_language;
184     fl_deactivate_object(obj);
185     fl_addto_form(language_->form);
186     combo_language.reset(new Combox(FL_COMBOX_DROPLIST));
187     combo_language->add(obj->x, obj->y, obj->w, obj->h, 400,
188                         dialog_->tabbed_folder);
189     combo_language->shortcut("#L",1);
190     combo_language->setcallback(ComboInputCB, this);
191     fl_end_form();
192
193     for (Languages::const_iterator cit = languages.begin();
194         cit != languages.end(); ++cit) {
195         combo_language->addto(cit->second.lang());
196     }
197
198     fl_addto_choice(language_->choice_quotes_language,
199                     _(" ``text'' | ''text'' | ,,text`` | ,,text'' |"
200                       " «text» | »text« "));
201
202     bc().addReadOnly (language_->choice_inputenc);
203
204     // the document options form
205     options_.reset(build_doc_options());
206     fl_set_input_return(options_->input_float_placement, FL_RETURN_CHANGED);
207     fl_set_counter_bounds(options_->slider_secnumdepth,-2,5);
208     fl_set_counter_bounds(options_->slider_tocdepth,-1,5);
209     fl_set_counter_step(options_->slider_secnumdepth,1,1);
210     fl_set_counter_step(options_->slider_tocdepth,1,1);
211     fl_set_counter_precision(options_->slider_secnumdepth, 0);
212     fl_set_counter_precision(options_->slider_tocdepth, 0);
213     for (n=0; tex_graphics[n][0]; ++n) {
214         fl_addto_choice(options_->choice_postscript_driver, tex_graphics[n]);
215     }
216     fl_addto_choice(options_->choice_citation_format,
217                     _(" Author-year | Numerical "));
218
219     bc_.addReadOnly (options_->slider_secnumdepth);
220     bc_.addReadOnly (options_->slider_tocdepth);
221     bc_.addReadOnly (options_->check_use_amsmath);
222     bc_.addReadOnly (options_->check_use_natbib);
223     bc_.addReadOnly (options_->choice_citation_format);
224     bc_.addReadOnly (options_->input_float_placement);
225     bc_.addReadOnly (options_->choice_postscript_driver);
226
227     // the document bullets form
228     bullets_.reset(build_doc_bullet());
229     fl_addto_choice(bullets_->choice_bullet_size,
230                     _(" default | tiny | script | footnote | small |"
231                       " normal | large | Large | LARGE | huge | Huge"));
232     fl_set_choice(bullets_->choice_bullet_size, 1);
233     fl_set_input_return(bullets_->input_bullet_latex, FL_RETURN_CHANGED);
234     fl_set_input_maxchars(bullets_->input_bullet_latex, 80);
235
236     bc().addReadOnly (bullets_->bmtable_bullet_panel);
237     bc().addReadOnly (bullets_->choice_bullet_size);
238     bc().addReadOnly (bullets_->input_bullet_latex);
239
240     fl_addto_tabfolder(dialog_->tabbed_folder,_("Document"),
241                        class_->form);
242     fl_addto_tabfolder(dialog_->tabbed_folder,_("Paper"),
243                        paper_->form);
244     fl_addto_tabfolder(dialog_->tabbed_folder,_("Language"),
245                        language_->form);
246     fl_addto_tabfolder(dialog_->tabbed_folder,_("Extra"),
247                        options_->form);
248     fbullet = fl_addto_tabfolder(dialog_->tabbed_folder,_("Bullets"),
249                                  bullets_->form);
250     if ((XpmVersion < 4) || (XpmVersion == 4 && XpmRevision < 7)) {
251             lyxerr << _("Your version of libXpm is older than 4.7.\n"
252                         "The `bullet' tab of the document dialog "
253                         "has been disabled") << '\n';
254         fl_deactivate_object(fbullet);
255         fl_set_object_lcol(fbullet, FL_INACTIVE);
256     }
257 }
258
259
260 void FormDocument::apply()
261 {
262     if (!lv_->view()->available() || !dialog_.get())
263         return;
264
265     bool redo = class_apply();
266     paper_apply();
267     redo = language_apply() || redo;
268     redo = options_apply() || redo;
269     bullets_apply();
270
271     if (redo) {
272             lv_->view()->redoCurrentBuffer();
273     }
274     lv_->buffer()->markDirty();
275     setMinibuffer(lv_, _("Document layout set"));
276 }
277
278
279 void FormDocument::cancel()
280 {
281     // this avoids confusion when reopening
282     BufferParams & param = lv_->buffer()->params;
283     param.temp_bullets[0] = param.user_defined_bullets[0];
284     param.temp_bullets[1] = param.user_defined_bullets[1];
285     param.temp_bullets[2] = param.user_defined_bullets[2];
286     param.temp_bullets[3] = param.user_defined_bullets[3];
287     hide();
288 }
289
290
291 void FormDocument::update()
292 {
293     if (!dialog_.get())
294         return;
295
296     checkReadOnly();
297
298     BufferParams const & params = lv_->buffer()->params;
299
300     class_update(params);
301     paper_update(params);
302     language_update(params);
303     options_update(params);
304     bullets_update(params);
305 }
306
307
308 bool FormDocument::input( FL_OBJECT * ob, long data )
309 {
310         State cb = static_cast<State>( data );
311
312         switch (cb) {
313         case CHECKCHOICECLASS:
314                 CheckChoiceClass(ob, 0);
315                 break;
316         case CHOICEBULLETSIZE:
317                 ChoiceBulletSize(ob, 0);
318                 break;
319         case INPUTBULLETLATEX:
320                 InputBulletLaTeX(ob, 0);
321                 break;
322         case BULLETDEPTH1:
323         case BULLETDEPTH2:
324         case BULLETDEPTH3:
325         case BULLETDEPTH4:
326                 BulletDepth(ob, cb);
327                 break;
328         case BULLETPANEL1:
329         case BULLETPANEL2:
330         case BULLETPANEL3:
331         case BULLETPANEL4:
332         case BULLETPANEL5:
333         case BULLETPANEL6:
334                 BulletPanel(ob, cb);
335                 break;
336         case BULLETBMTABLE:
337                 BulletBMTable(ob, 0);
338                 break;
339         default:
340                 break;
341         }
342         
343         switch (data) {
344         case INPUT:
345         case CHECKCHOICECLASS:
346         case CHOICEBULLETSIZE:
347         case INPUTBULLETLATEX:
348         case BULLETBMTABLE:
349                 return CheckDocumentInput(ob, 0);
350         default:
351                 break;
352         }
353
354         return true;
355 }
356
357
358 void FormDocument::ComboInputCB(int, void * v, Combox * combox)
359 {
360     FormDocument * pre = static_cast<FormDocument*>(v);
361     if (combox == pre->combo_doc_class.get())
362         pre->CheckChoiceClass(0, 0);
363     pre->bc().valid(pre->CheckDocumentInput(0,0));
364 }
365
366
367 bool FormDocument::class_apply()
368 {
369         bool redo = false;
370         BufferParams &params = lv_->buffer()->params;
371
372         // If default skip is a "Length" but there's no text in the
373         // input field, reset the kind to "Medskip", which is the default.
374         if ((fl_get_choice (class_->choice_doc_skip) == 4) &&
375             !*(fl_get_input (class_->input_doc_skip))) {
376                 fl_set_choice (class_->choice_doc_skip, 2);
377         }
378         params.fonts = fl_get_choice_text(class_->choice_doc_fonts);
379         params.fontsize = fl_get_choice_text(class_->choice_doc_fontsize);
380         params.pagestyle = fl_get_choice_text(class_->choice_doc_pagestyle);
381
382         unsigned int const new_class = combo_doc_class->get() - 1;
383         
384         if (params.textclass != new_class) {
385                 // try to load new_class
386                 if (textclasslist.Load(new_class)) {
387                         // successfully loaded
388                         redo = true;
389                         setMinibuffer(lv_, _("Converting document to new document class..."));
390                         int ret = CutAndPaste::SwitchLayoutsBetweenClasses(
391                             params.textclass, new_class,
392                             lv_->buffer()->paragraph);
393                         if (ret) {
394                                 string s;
395                                 if (ret==1) {
396                                         s = _("One paragraph couldn't be converted");
397                                 } else {
398                                         s += tostr(ret);
399                                         s += _(" paragraphs couldn't be converted");
400                                 }
401                                 WriteAlert(_("Conversion Errors!"),s,
402                                            _("into chosen document class"));
403                         }
404                         
405                         params.textclass = new_class;
406                 } else {
407                         // problem changing class -- warn user and retain old style
408                         WriteAlert(_("Conversion Errors!"),
409                                    _("Errors loading new document class."),
410                                    _("Reverting to original document class."));
411                         combo_doc_class->select(int(params.textclass) + 1);
412                 }
413         }
414         BufferParams::PARSEP tmpsep = params.paragraph_separation;
415         if (fl_get_button(class_->radio_doc_indent))
416                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
417         else
418                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
419         if (tmpsep != params.paragraph_separation)
420                 redo = true;
421         
422         VSpace tmpdefskip = params.getDefSkip();
423         switch (fl_get_choice (class_->choice_doc_skip)) {
424         case 1:
425                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
426                 break;
427         case 2:
428                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
429                 break;
430     case 3:
431             params.setDefSkip(VSpace(VSpace::BIGSKIP));
432             break;
433         case 4:
434                 params.setDefSkip
435                         (VSpace(LyXGlueLength(fl_get_input(class_->input_doc_skip))));
436                 break;
437                 // DocumentDefskipCB assures that this never happens
438         default:
439                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
440                 break;
441         }
442         if (!(tmpdefskip == params.getDefSkip()))
443                 redo = true;
444         
445         if (fl_get_button(class_->radio_doc_columns_two))
446                 params.columns = 2;
447         else
448                 params.columns = 1;
449         if (fl_get_button(class_->radio_doc_sides_two))
450                 params.sides = LyXTextClass::TwoSides;
451         else
452                 params.sides = LyXTextClass::OneSide;
453         
454         Spacing tmpSpacing = params.spacing;
455         switch (fl_get_choice(class_->choice_doc_spacing)) {
456         case 1:
457                 lyxerr[Debug::INFO] << "Spacing: SINGLE\n";
458                 params.spacing.set(Spacing::Single);
459                 break;
460         case 2:
461                 lyxerr[Debug::INFO] << "Spacing: ONEHALF\n";
462                 params.spacing.set(Spacing::Onehalf);
463                 break;
464         case 3:
465                 lyxerr[Debug::INFO] << "Spacing: DOUBLE\n";
466                 params.spacing.set(Spacing::Double);
467                 break;
468         case 4:
469                 lyxerr[Debug::INFO] << "Spacing: OTHER\n";
470                 params.spacing.set(Spacing::Other, 
471                                    fl_get_input(class_->input_doc_spacing));
472                 break;
473         }
474         if (tmpSpacing != params.spacing)
475                 redo = true;
476         
477         params.options = fl_get_input(class_->input_doc_extra);
478         
479         return redo;
480 }
481
482
483 void FormDocument::paper_apply()
484 {
485     BufferParams & params = lv_->buffer()->params;
486     
487     params.papersize2 =
488             static_cast<char>(fl_get_choice(paper_->choice_papersize2)-1);
489     params.paperpackage =
490             static_cast<char>(fl_get_choice(paper_->choice_paperpackage)-1);
491     params.use_geometry = fl_get_button(paper_->push_use_geometry);
492     if (fl_get_button(paper_->radio_landscape))
493         params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
494     else
495         params.orientation = BufferParams::ORIENTATION_PORTRAIT;
496     params.paperwidth = fl_get_input(paper_->input_custom_width);
497     params.paperheight = fl_get_input(paper_->input_custom_height);
498     params.leftmargin = fl_get_input(paper_->input_left_margin);
499     params.topmargin = fl_get_input(paper_->input_top_margin);
500     params.rightmargin = fl_get_input(paper_->input_right_margin);
501     params.bottommargin = fl_get_input(paper_->input_bottom_margin);
502     params.headheight = fl_get_input(paper_->input_head_height);
503     params.headsep = fl_get_input(paper_->input_head_sep);
504     params.footskip = fl_get_input(paper_->input_foot_skip);
505     lv_->buffer()->setPaperStuff();
506 }
507
508
509 bool FormDocument::language_apply()
510 {
511     BufferParams & params = lv_->buffer()->params;
512     InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
513     bool redo = false;
514
515     switch (fl_get_choice(language_->choice_quotes_language) - 1) {
516     case 0:
517         lga = InsetQuotes::EnglishQ;
518         break;
519     case 1:
520         lga = InsetQuotes::SwedishQ;
521         break;
522     case 2:
523         lga = InsetQuotes::GermanQ;
524         break;
525     case 3:
526         lga = InsetQuotes::PolishQ;
527                 break;
528     case 4:
529         lga = InsetQuotes::FrenchQ;
530         break;
531     case 5:
532         lga = InsetQuotes::DanishQ;
533         break;
534     }
535     params.quotes_language = lga;
536     if (fl_get_button(language_->radio_single))   
537         params.quotes_times = InsetQuotes::SingleQ;
538     else
539         params.quotes_times = InsetQuotes::DoubleQ;
540
541     Language const * old_language = params.language;
542     Language const * new_language = 
543             languages.getLanguage(combo_language->getline());
544     if (!new_language)
545         new_language = default_language;
546
547     if (old_language != new_language
548         && old_language->RightToLeft() == new_language->RightToLeft()
549         && !lv_->buffer()->isMultiLingual())
550         lv_->buffer()->changeLanguage(old_language, new_language);
551     if (old_language != new_language) {
552         redo = true;
553     }
554     params.language = new_language;
555     params.inputenc = fl_get_choice_text(language_->choice_inputenc);
556
557     return redo;
558 }
559
560
561 bool FormDocument::options_apply()
562 {
563     BufferParams & params = lv_->buffer()->params;
564     bool redo = false;
565
566     params.graphicsDriver =
567         fl_get_choice_text(options_->choice_postscript_driver);
568     params.use_amsmath = fl_get_button(options_->check_use_amsmath);
569     params.use_natbib  = fl_get_button(options_->check_use_natbib);
570     params.use_numerical_citations  =
571             fl_get_choice(options_->choice_citation_format)-1;
572
573     int tmpchar = int(fl_get_counter_value(options_->slider_secnumdepth));
574     if (params.secnumdepth != tmpchar)
575         redo = true;
576     params.secnumdepth = tmpchar;
577    
578     params.tocdepth = int(fl_get_counter_value(options_->slider_tocdepth));
579
580     params.float_placement =
581         fl_get_input(options_->input_float_placement);
582
583     return redo;
584 }
585
586
587 void FormDocument::bullets_apply()
588 {
589     /* update the bullet settings */
590     BufferParams & param = lv_->buffer()->params;
591     
592     // a little bit of loop unrolling
593     param.user_defined_bullets[0] = param.temp_bullets[0];
594     param.user_defined_bullets[1] = param.temp_bullets[1];
595     param.user_defined_bullets[2] = param.temp_bullets[2];
596     param.user_defined_bullets[3] = param.temp_bullets[3];
597 }
598
599
600 void FormDocument::class_update(BufferParams const & params)
601 {
602     if (!class_.get())
603         return;
604
605     LyXTextClass const & tclass = textclasslist.TextClass(params.textclass);
606
607     combo_doc_class->select_text(
608         textclasslist.DescOfClass(params.textclass));
609     fl_set_choice_text(class_->choice_doc_fonts, params.fonts.c_str());
610     fl_clear_choice(class_->choice_doc_fontsize);
611     fl_addto_choice(class_->choice_doc_fontsize, "default");
612     fl_addto_choice(class_->choice_doc_fontsize,
613                     tclass.opt_fontsize().c_str());
614     fl_set_choice(class_->choice_doc_fontsize,
615                   tokenPos(tclass.opt_fontsize(), '|', params.fontsize)+2);
616     fl_clear_choice(class_->choice_doc_pagestyle);
617     fl_addto_choice(class_->choice_doc_pagestyle, "default");
618     fl_addto_choice(class_->choice_doc_pagestyle,
619                     tclass.opt_pagestyle().c_str());
620     fl_set_choice(class_->choice_doc_pagestyle,
621                   tokenPos(tclass.opt_pagestyle(), '|', params.pagestyle)+2);
622     fl_set_button(class_->radio_doc_indent, 0);
623     fl_set_button(class_->radio_doc_skip, 0);
624     if (params.paragraph_separation == BufferParams::PARSEP_INDENT)
625         fl_set_button(class_->radio_doc_indent, 1);
626     else
627         fl_set_button(class_->radio_doc_skip, 1);
628     switch (params.getDefSkip().kind()) {
629     case VSpace::SMALLSKIP: 
630         fl_set_choice (class_->choice_doc_skip, 1);
631         break;
632     case VSpace::MEDSKIP: 
633         fl_set_choice (class_->choice_doc_skip, 2);
634         break;
635     case VSpace::BIGSKIP: 
636         fl_set_choice (class_->choice_doc_skip, 3);
637         break;
638     case VSpace::LENGTH: 
639         fl_set_choice (class_->choice_doc_skip, 4);
640         fl_set_input (class_->input_doc_skip,
641                       params.getDefSkip().asLyXCommand().c_str());
642         break;
643     default:
644         fl_set_choice (class_->choice_doc_skip, 2);
645         break;
646     }
647     fl_set_button(class_->radio_doc_sides_one, 0);
648     fl_set_button(class_->radio_doc_sides_two, 0);
649     if (params.sides == LyXTextClass::TwoSides)
650         fl_set_button(class_->radio_doc_sides_two, 1);
651     else
652         fl_set_button(class_->radio_doc_sides_one, 1);
653     fl_set_button(class_->radio_doc_columns_one, 0);
654     fl_set_button(class_->radio_doc_columns_two, 0);
655     if (params.columns == 2)
656         fl_set_button(class_->radio_doc_columns_two, 1);
657     else
658         fl_set_button(class_->radio_doc_columns_one, 1);
659     fl_set_input(class_->input_doc_spacing, "");
660     switch (params.spacing.getSpace()) {
661     case Spacing::Default: // nothing bad should happen with this
662     case Spacing::Single:
663         // \singlespacing
664         fl_set_choice(class_->choice_doc_spacing, 1);
665         break;
666     case Spacing::Onehalf:
667         // \onehalfspacing
668         fl_set_choice(class_->choice_doc_spacing, 2);
669         break;
670     case Spacing::Double:
671         // \doublespacing
672         fl_set_choice(class_->choice_doc_spacing, 3);
673         break;
674     case Spacing::Other:
675         {
676             fl_set_choice(class_->choice_doc_spacing, 4);
677             char sval[20];
678             sprintf(sval,"%g",params.spacing.getValue()); 
679             fl_set_input(class_->input_doc_spacing, sval);
680             break;
681         }
682     }
683     if (!params.options.empty())
684         fl_set_input(class_->input_doc_extra, params.options.c_str());
685     else
686         fl_set_input(class_->input_doc_extra, "");
687 }
688
689
690 void FormDocument::language_update(BufferParams const & params)
691 {
692     if (!language_.get())
693         return;
694
695     combo_language->select_text(params.language->lang());
696     fl_set_choice_text(language_->choice_inputenc, params.inputenc.c_str());
697     fl_set_choice(language_->choice_quotes_language, params.quotes_language + 1);
698     fl_set_button(language_->radio_single, 0);
699     fl_set_button(language_->radio_double, 0);
700     if (params.quotes_times == InsetQuotes::SingleQ)
701         fl_set_button(language_->radio_single, 1);
702     else
703         fl_set_button(language_->radio_double, 1);
704 }
705
706
707 void FormDocument::options_update(BufferParams const & params)
708 {
709     if (!options_.get())
710         return;
711
712     fl_set_choice_text(options_->choice_postscript_driver,
713                        params.graphicsDriver.c_str());
714     fl_set_button(options_->check_use_amsmath, params.use_amsmath);
715     fl_set_button(options_->check_use_natbib,  params.use_natbib);
716     fl_set_choice(options_->choice_citation_format,
717                   int(params.use_numerical_citations)+1);
718     fl_set_counter_value(options_->slider_secnumdepth, params.secnumdepth);
719     fl_set_counter_value(options_->slider_tocdepth, params.tocdepth);
720     if (!params.float_placement.empty())
721         fl_set_input(options_->input_float_placement,
722                      params.float_placement.c_str());
723     else
724         fl_set_input(options_->input_float_placement, "");
725 }
726
727
728 void FormDocument::paper_update(BufferParams const & params)
729 {
730     if (!paper_.get())
731         return;
732
733     fl_set_choice(paper_->choice_papersize2, params.papersize2 + 1);
734     fl_set_choice(paper_->choice_paperpackage, params.paperpackage + 1);
735     fl_set_button(paper_->push_use_geometry, params.use_geometry);
736     fl_set_button(paper_->radio_portrait, 0);
737     fl_set_button(paper_->radio_landscape, 0);
738     if (params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
739         fl_set_button(paper_->radio_landscape, 1);
740     else
741         fl_set_button(paper_->radio_portrait, 1);
742     fl_set_input(paper_->input_custom_width, params.paperwidth.c_str());
743     fl_set_input(paper_->input_custom_height, params.paperheight.c_str());
744     fl_set_input(paper_->input_left_margin, params.leftmargin.c_str());
745     fl_set_input(paper_->input_top_margin, params.topmargin.c_str());
746     fl_set_input(paper_->input_right_margin, params.rightmargin.c_str());
747     fl_set_input(paper_->input_bottom_margin, params.bottommargin.c_str());
748     fl_set_input(paper_->input_head_height, params.headheight.c_str());
749     fl_set_input(paper_->input_head_sep, params.headsep.c_str());
750     fl_set_input(paper_->input_foot_skip, params.footskip.c_str());
751     fl_set_focus_object(paper_->form, paper_->choice_papersize2);
752 }
753
754
755 void FormDocument::bullets_update(BufferParams const & params)
756 {
757     if (!bullets_.get() || ((XpmVersion<4) || (XpmVersion==4 && XpmRevision<7)))
758         return;
759
760     bool const isLinuxDoc = lv_->buffer()->isLinuxDoc();
761     setEnabled(fbullet, !isLinuxDoc);
762
763     if (isLinuxDoc) return;
764
765     fl_set_button(bullets_->radio_bullet_depth_1, 1);
766     fl_set_input(bullets_->input_bullet_latex,
767                  params.user_defined_bullets[0].getText().c_str());
768     fl_set_choice(bullets_->choice_bullet_size,
769                   params.user_defined_bullets[0].getSize() + 2);
770 }
771
772
773 void FormDocument::checkReadOnly()
774 {
775     if (bc().readOnly(lv_->buffer()->isReadonly())) {
776         combo_doc_class->deactivate();
777         combo_language->deactivate();
778         fl_set_object_label(dialog_->text_warning,
779                             _("Document is read-only."
780                               " No changes to layout permitted."));
781         fl_show_object(dialog_->text_warning);
782     } else {
783         combo_doc_class->activate();
784         combo_language->activate();
785         fl_hide_object(dialog_->text_warning);
786     }   
787 }
788
789
790 void FormDocument::checkMarginValues()
791 {
792         bool const not_empty =
793                 strlen(fl_get_input(paper_->input_top_margin)) ||
794                 strlen(fl_get_input(paper_->input_bottom_margin)) ||
795                 strlen(fl_get_input(paper_->input_left_margin)) ||
796                 strlen(fl_get_input(paper_->input_right_margin)) ||
797                 strlen(fl_get_input(paper_->input_head_height)) ||
798                 strlen(fl_get_input(paper_->input_head_sep)) ||
799                 strlen(fl_get_input(paper_->input_foot_skip)) ||
800                 strlen(fl_get_input(paper_->input_custom_width)) ||
801                 strlen(fl_get_input(paper_->input_custom_height));
802         if (not_empty)
803                 fl_set_button(paper_->push_use_geometry, 1);
804 }
805
806
807 bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
808 {
809     string str;
810     int val;
811     bool ok = true;
812     char const * input;
813     
814     checkMarginValues();
815     if (ob == paper_->choice_papersize2) {
816         val = fl_get_choice(paper_->choice_papersize2)-1;
817         if (val == BufferParams::VM_PAPER_DEFAULT) {
818             fl_set_button(paper_->push_use_geometry, 0);
819             checkMarginValues();
820         } else {
821             if ((val != BufferParams::VM_PAPER_USLETTER) &&
822                 (val != BufferParams::VM_PAPER_USLEGAL) &&
823                 (val != BufferParams::VM_PAPER_USEXECUTIVE) &&
824                 (val != BufferParams::VM_PAPER_A4) &&
825                 (val != BufferParams::VM_PAPER_A5) &&
826                 (val != BufferParams::VM_PAPER_B5)) {
827                 fl_set_button(paper_->push_use_geometry, 1);
828             }
829             fl_set_choice(paper_->choice_paperpackage,
830                           BufferParams::PACKAGE_NONE + 1);
831         }
832     } else if (ob == paper_->choice_paperpackage) {
833         val = fl_get_choice(paper_->choice_paperpackage)-1;
834         if (val != BufferParams::PACKAGE_NONE) {
835             fl_set_choice(paper_->choice_papersize2,
836                           BufferParams::VM_PAPER_DEFAULT + 1);
837             fl_set_button(paper_->push_use_geometry, 0);
838         }
839     } else if (ob == class_->input_doc_spacing) {
840         input = fl_get_input(class_->input_doc_spacing);
841         if (!*input) {
842             fl_set_choice (class_->choice_doc_spacing, 1);
843         } else {
844             fl_set_choice(class_->choice_doc_spacing, 4);
845         }
846     }
847     // this has to be all out of if/elseif because it has to deactivate
848     // the document buttons and so the whole stuff has to be tested again.
849     str = fl_get_input(paper_->input_custom_width);
850     ok = ok && (str.empty() || isValidLength(str));
851     str = fl_get_input(paper_->input_custom_height);
852     ok = ok && (str.empty() || isValidLength(str));
853     str = fl_get_input(paper_->input_left_margin);
854     ok = ok && (str.empty() || isValidLength(str));
855     str = fl_get_input(paper_->input_right_margin);
856     ok = ok && (str.empty() || isValidLength(str));
857     str = fl_get_input(paper_->input_top_margin);
858     ok = ok && (str.empty() || isValidLength(str));
859     str = fl_get_input(paper_->input_bottom_margin);
860     ok = ok && (str.empty() || isValidLength(str));
861     str = fl_get_input(paper_->input_head_height);
862     ok = ok && (str.empty() || isValidLength(str));
863     str = fl_get_input(paper_->input_head_sep);
864     ok = ok && (str.empty() || isValidLength(str));
865     str = fl_get_input(paper_->input_foot_skip);
866     ok = ok && (str.empty() || isValidLength(str));
867     // "Synchronize" the choice and the input field, so that it
868     // is impossible to commit senseless data.
869     input = fl_get_input (class_->input_doc_skip);
870     if (ob == class_->input_doc_skip) {
871         if (!*input) {
872             fl_set_choice (class_->choice_doc_skip, 2);
873         } else if (isValidGlueLength (input)) {
874             fl_set_choice (class_->choice_doc_skip, 4);
875         } else {
876             fl_set_choice(class_->choice_doc_skip, 4);
877             ok = false;
878         }
879     } else {
880         if (*input && !isValidGlueLength(input))
881             ok = false;
882     }
883     if ((fl_get_choice(class_->choice_doc_skip) == 4) && !*input)
884         ok = false;
885     else if (fl_get_choice(class_->choice_doc_skip) != 4)
886         fl_set_input (class_->input_doc_skip, "");
887
888     input = fl_get_input(class_->input_doc_spacing);
889     if ((fl_get_choice(class_->choice_doc_spacing) == 4) && !*input)
890         ok = false;
891     else  if (fl_get_choice(class_->choice_doc_spacing) != 4)
892         fl_set_input (class_->input_doc_spacing, "");
893     return ok;
894 }
895
896
897 void FormDocument::ChoiceBulletSize(FL_OBJECT * ob, long /*data*/ )
898 {
899     BufferParams & param = lv_->buffer()->params;
900
901     // convert from 1-6 range to -1-4 
902     param.temp_bullets[current_bullet_depth].setSize(fl_get_choice(ob) - 2);
903     fl_set_input(bullets_->input_bullet_latex,
904                  param.temp_bullets[current_bullet_depth].getText().c_str());
905 }
906
907
908 void FormDocument::InputBulletLaTeX(FL_OBJECT *, long)
909 {
910     BufferParams & param = lv_->buffer()->params;
911
912     param.temp_bullets[current_bullet_depth].
913         setText(fl_get_input(bullets_->input_bullet_latex));
914 }
915
916
917 void FormDocument::BulletDepth(FL_OBJECT * ob, State cb)
918 {
919     /* Should I do the following:                                 */
920     /*  1. change to the panel that the current bullet belongs in */
921     /*  2. show that bullet as selected                           */
922     /*  3. change the size setting to the size of the bullet in Q.*/
923     /*  4. display the latex equivalent in the latex box          */
924     /*                                                            */
925     /* I'm inclined to just go with 3 and 4 at the moment and     */
926     /* maybe try to support the others later                      */
927     BufferParams & param = lv_->buffer()->params;
928
929     int data = 0;
930     if (cb == BULLETDEPTH1 )
931             data = 0;
932     else if (cb == BULLETDEPTH2 )
933             data = 1;
934     else if (cb == BULLETDEPTH3 )
935             data = 2;
936     else if (cb == BULLETDEPTH4 )
937             data = 3;
938
939     switch (fl_get_button_numb(ob)) {
940     case 3:
941             // right mouse button resets to default
942         param.temp_bullets[data] = ITEMIZE_DEFAULTS[data];
943     default:
944         current_bullet_depth = data;
945         fl_set_input(bullets_->input_bullet_latex,
946                      param.temp_bullets[data].getText().c_str());
947         fl_set_choice(bullets_->choice_bullet_size,
948                       param.temp_bullets[data].getSize() + 2);
949     }
950 }
951
952
953 void FormDocument::BulletPanel(FL_OBJECT * /*ob*/, State cb)
954 {
955     /* Here we have to change the background pixmap to that selected */
956     /* by the user. (eg. standard.xpm, psnfss1.xpm etc...)           */
957     
958     int data = 0;
959     if (cb == BULLETPANEL1 )
960             data = 0;
961     else if (cb == BULLETPANEL2 )
962             data = 1;
963     else if (cb == BULLETPANEL3 )
964             data = 2;
965     else if (cb == BULLETPANEL4 )
966             data = 3;
967     else if (cb == BULLETPANEL5 )
968             data = 4;
969     else if (cb == BULLETPANEL6 )
970             data = 5;
971
972     if (data != current_bullet_panel) {
973         fl_freeze_form(bullets_->form);
974         current_bullet_panel = data;
975
976         /* free the current pixmap */
977         fl_free_bmtable_pixmap(bullets_->bmtable_bullet_panel);
978         string new_panel;
979         switch (cb) {
980             /* display the new one */
981         case BULLETPANEL1 :
982             new_panel = "standard";
983             break;
984         case BULLETPANEL2 :
985             new_panel = "amssymb";
986             break;
987         case BULLETPANEL3 :
988             new_panel = "psnfss1";
989             break;
990         case BULLETPANEL4 :
991             new_panel = "psnfss2";
992             break;
993         case BULLETPANEL5 :
994             new_panel = "psnfss3";
995             break;
996         case BULLETPANEL6 :
997             new_panel = "psnfss4";
998             break;
999         default :
1000             /* something very wrong happened */
1001             // play it safe for now but should be an exception
1002             current_bullet_panel = 0;  // standard panel
1003             new_panel = "standard";
1004             break;
1005         }
1006         new_panel += ".xpm";
1007         fl_set_bmtable_pixmap_file(bullets_->bmtable_bullet_panel, 6, 6,
1008                                    LibFileSearch("images", new_panel).c_str());
1009         fl_redraw_object(bullets_->bmtable_bullet_panel);
1010         fl_unfreeze_form(bullets_->form);
1011     }
1012 }
1013
1014
1015 void FormDocument::BulletBMTable(FL_OBJECT * ob, long /*data*/ )
1016 {
1017     /* handle the user input by setting the current bullet depth's pixmap */
1018     /* to that extracted from the current chosen position of the BMTable  */
1019     /* Don't forget to free the button's old pixmap first.                */
1020
1021     BufferParams & param = lv_->buffer()->params;
1022     int bmtable_button = fl_get_bmtable(ob);
1023
1024     /* try to keep the button held down till another is pushed */
1025     /*  fl_set_bmtable(ob, 1, bmtable_button); */
1026     param.temp_bullets[current_bullet_depth].setFont(current_bullet_panel);
1027     param.temp_bullets[current_bullet_depth].setCharacter(bmtable_button);
1028     fl_set_input(bullets_->input_bullet_latex,
1029                  param.temp_bullets[current_bullet_depth].getText().c_str());
1030 }
1031
1032
1033 void FormDocument::CheckChoiceClass(FL_OBJECT * ob, long)
1034 {
1035     if (!ob)
1036         ob = class_->choice_doc_class;
1037
1038     lv_->prohibitInput();
1039
1040     unsigned int tc = combo_doc_class->get() - 1;
1041     if (textclasslist.Load(tc)) {
1042             // we use a copy of the bufferparams because we do not
1043             // want to modify them yet. 
1044             BufferParams params = lv_->buffer()->params;
1045
1046             if (params.textclass != tc
1047                 && AskQuestion(_("Should I set some parameters to"), 
1048                                _("the defaults of this document class?"))) {
1049             params.textclass = tc;
1050             params.useClassDefaults();
1051             UpdateLayoutDocument(params);
1052         }
1053     } else {
1054         // unable to load new style
1055         WriteAlert(_("Conversion Errors!"),
1056                    _("Unable to switch to new document class."),
1057                    _("Reverting to original document class."));
1058         combo_doc_class->select(int(lv_->buffer()->params.textclass) + 1);
1059     }
1060     lv_->allowInput();
1061 }
1062
1063
1064 void FormDocument::UpdateLayoutDocument(BufferParams const & params)
1065 {
1066     if (!dialog_.get())
1067         return;
1068
1069     checkReadOnly();
1070     class_update(params);
1071     paper_update(params);
1072     language_update(params);
1073     options_update(params);
1074     bullets_update(params);
1075 }