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