]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormParagraph.C
Fix xforms menus display problems
[lyx.git] / src / frontends / xforms / FormParagraph.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 #ifdef __GNUG_
15 #pragma implementation
16 #endif
17
18 #include "lyx_gui_misc.h"
19 #include "gettext.h"
20 #include FORMS_H_LOCATION
21 #include XPM_H_LOCATION
22
23 #include "FormParagraph.h"
24 #include "form_paragraph.h"
25 #include "xform_macros.h"
26 #include "Dialogs.h"
27 #include "ButtonController.h"
28 #include "Liason.h"
29 #include "LyXView.h"
30 #include "BufferView.h"
31 #include "buffer.h"
32 #include "lyxtext.h"
33
34 #ifdef SIGC_CXX_NAMESPACES
35 using SigC::slot;
36 #endif
37
38 #ifdef CXX_WORKING_NAMESPACES
39 using Liason::setMinibuffer;
40 #endif
41
42 C_RETURNCB(FormParagraph,  WMHideCB)
43 C_GENERICCB(FormParagraph, InputCB)
44 C_GENERICCB(FormParagraph, OKCB)
45 C_GENERICCB(FormParagraph, ApplyCB)
46 C_GENERICCB(FormParagraph, CancelCB)
47 C_GENERICCB(FormParagraph, RestoreCB)
48 C_GENERICCB(FormParagraph, VSpaceCB)
49         
50 FormParagraph::FormParagraph(LyXView * lv, Dialogs * d)
51         : dialog_(0), general_(0), extra_(0),
52           lv_(lv), d_(d), u_(0), h_(0),
53           status(POPUP_UNMODIFIED) ,
54           bc_(new ButtonController<NoRepeatedApplyReadOnlyPolicy>(_("Cancel"),
55                                                                   _("Close")))
56 {
57     // let the popup be shown
58     // This is a permanent connection so we won't bother
59     // storing a copy because we won't be disconnecting.
60     d->showLayoutParagraph.connect(slot(this, &FormParagraph::show));
61 }
62
63
64 FormParagraph::~FormParagraph()
65 {
66     free();
67     delete bc_;
68 }
69
70
71 void FormParagraph::build()
72 {
73     // the tabbed folder
74     dialog_ = build_tabbed_paragraph();
75
76     // manage the restore, ok, apply and cancel/close buttons
77     bc_->setOK(dialog_->button_ok);
78     bc_->setApply(dialog_->button_apply);
79     bc_->setCancel(dialog_->button_cancel);
80     bc_->setUndoAll(dialog_->button_restore);
81     bc_->refresh();
82
83     // the general paragraph data form
84     general_ = build_paragraph_general();
85
86     fl_addto_choice(general_->choice_space_above,
87                     _(" None | Defskip | Smallskip "
88                       "| Medskip | Bigskip | VFill | Length "));
89     fl_addto_choice(general_->choice_space_below,
90                     _(" None | Defskip | Smallskip "
91                       "| Medskip | Bigskip | VFill | Length ")); 
92
93     fl_set_input_return(general_->input_space_above, FL_RETURN_CHANGED);
94     fl_set_input_return(general_->input_space_below, FL_RETURN_CHANGED);
95     fl_set_input_return(general_->input_labelwidth, FL_RETURN_CHANGED);
96
97     bc_->addReadOnly (general_->radio_align_right);
98     bc_->addReadOnly (general_->radio_align_left);
99     bc_->addReadOnly (general_->radio_align_block);
100     bc_->addReadOnly (general_->radio_align_center);
101     bc_->addReadOnly (general_->check_lines_top);
102     bc_->addReadOnly (general_->check_lines_bottom);
103     bc_->addReadOnly (general_->check_pagebreaks_top);
104     bc_->addReadOnly (general_->check_pagebreaks_bottom);
105     bc_->addReadOnly (general_->choice_space_above);
106     bc_->addReadOnly (general_->input_space_above);
107     bc_->addReadOnly (general_->check_space_above);
108     bc_->addReadOnly (general_->choice_space_below);
109     bc_->addReadOnly (general_->input_space_below);
110     bc_->addReadOnly (general_->check_space_below);
111     bc_->addReadOnly (general_->check_noindent);
112     bc_->addReadOnly (general_->input_labelwidth);
113
114     // the document class form
115     extra_ = build_paragraph_extra();
116
117     fl_set_input_return(extra_->input_pextra_width, FL_RETURN_CHANGED);
118     fl_set_input_return(extra_->input_pextra_widthp, FL_RETURN_CHANGED);
119
120     bc_->addReadOnly (extra_->radio_pextra_indent);
121     bc_->addReadOnly (extra_->radio_pextra_minipage);
122     bc_->addReadOnly (extra_->radio_pextra_floatflt);
123
124     // now make them fit together
125     fl_set_form_atclose(dialog_->form, C_FormParagraphWMHideCB, 0);
126     fl_addto_tabfolder(dialog_->tabbed_folder,_("General"), general_->form);
127     fl_addto_tabfolder(dialog_->tabbed_folder,_("Extra"), extra_->form);
128 }
129
130
131 void FormParagraph::show()
132 {
133     if (!dialog_)
134         build();
135
136     update();  // make sure its up-to-date
137     if (dialog_->form->visible) {
138         fl_raise_form(dialog_->form);
139     } else {
140         fl_show_form(dialog_->form, FL_PLACE_MOUSE | FL_FREE_SIZE,
141                      FL_TRANSIENT, _("Paragraph Layout"));
142         u_ = d_->updateBufferDependent.connect(
143             slot(this, &FormParagraph::update));
144         h_ = d_->hideBufferDependent.connect(
145             slot(this, &FormParagraph::hide));
146     }
147 }
148
149
150 void FormParagraph::hide()
151 {
152     if (dialog_->form->visible) {
153         fl_hide_form(dialog_->form);
154         u_.disconnect();
155         h_.disconnect();
156     }
157 }
158
159
160 void FormParagraph::apply()
161 {
162     if (!lv_->view()->available() || !dialog_)
163         return;
164
165     general_apply();
166     extra_apply();
167
168     lv_->view()->update(BufferView::SELECT | BufferView::FITCUR |
169                         BufferView::CHANGE);
170     lv_->buffer()->markDirty();
171     setMinibuffer(lv_, _("Paragraph layout set"));
172 }
173
174
175 void FormParagraph::general_apply()
176 {
177     VSpace space_top, space_bottom;
178     LyXAlignment align;
179     string labelwidthstring;
180     bool noindent;
181
182     // If a vspace kind is "Length" but there's no text in
183     // the input field, reset the kind to "None". 
184     if ((fl_get_choice (general_->choice_space_above) == 7) &&
185         !*(fl_get_input (general_->input_space_above)))
186     {
187         fl_set_choice (general_->choice_space_above, 1);
188     }
189     if ((fl_get_choice (general_->choice_space_below) == 7) &&
190         !*(fl_get_input (general_->input_space_below)))
191     {
192         fl_set_choice (general_->choice_space_below, 1);
193     }
194    
195     bool line_top = fl_get_button(general_->check_lines_top);
196     bool line_bottom = fl_get_button(general_->check_lines_bottom);
197     bool pagebreak_top = fl_get_button(general_->check_pagebreaks_top);
198     bool pagebreak_bottom = fl_get_button(general_->check_pagebreaks_bottom);
199     
200     switch (fl_get_choice (general_->choice_space_above)) {
201     case 1:
202         space_top = VSpace(VSpace::NONE);
203         break;
204     case 2:
205         space_top = VSpace(VSpace::DEFSKIP);
206         break;
207     case 3:
208         space_top = VSpace(VSpace::SMALLSKIP);
209         break;
210     case 4:
211         space_top = VSpace(VSpace::MEDSKIP);
212         break;
213     case 5:
214         space_top = VSpace(VSpace::BIGSKIP);
215         break;
216     case 6:
217         space_top = VSpace(VSpace::VFILL);
218         break;
219     case 7:
220         space_top = VSpace(LyXGlueLength(fl_get_input(general_->input_space_above)));
221         break;
222     }
223     if (fl_get_button (general_->check_space_above))
224         space_top.setKeep (true);
225     switch (fl_get_choice (general_->choice_space_below)) {
226     case 1:
227         space_bottom = VSpace(VSpace::NONE);
228         break;
229     case 2:
230         space_bottom = VSpace(VSpace::DEFSKIP);
231         break;
232     case 3:
233         space_bottom = VSpace(VSpace::SMALLSKIP);
234         break;
235     case 4:
236         space_bottom = VSpace(VSpace::MEDSKIP);
237         break;
238     case 5:
239         space_bottom = VSpace(VSpace::BIGSKIP);
240         break;
241     case 6:
242         space_bottom = VSpace(VSpace::VFILL);
243         break;
244     case 7:
245         space_bottom = VSpace(LyXGlueLength(fl_get_input(general_->input_space_below)));
246         break;
247     }
248     if (fl_get_button (general_->check_space_below))
249         space_bottom.setKeep (true);
250
251     if (fl_get_button(general_->radio_align_left))
252         align = LYX_ALIGN_LEFT;
253     else if (fl_get_button(general_->radio_align_right))
254         align = LYX_ALIGN_RIGHT;
255     else if (fl_get_button(general_->radio_align_center))
256         align = LYX_ALIGN_CENTER;
257     else 
258         align = LYX_ALIGN_BLOCK;
259    
260     labelwidthstring = fl_get_input(general_->input_labelwidth);
261     noindent = fl_get_button(general_->check_noindent);
262
263     LyXText * text = 0;
264     if (lv_->view()->the_locking_inset)
265         text = lv_->view()->the_locking_inset->getLyXText(lv_->view());
266     if (!text)
267         text = lv_->view()->text;
268     text->SetParagraph(lv_->view(), line_top, line_bottom, pagebreak_top,
269                        pagebreak_bottom, space_top, space_bottom, align, 
270                        labelwidthstring, noindent);
271 }
272
273
274 void FormParagraph::extra_apply()
275 {
276     char const * width = fl_get_input(extra_->input_pextra_width);
277     char const * widthp = fl_get_input(extra_->input_pextra_widthp);
278     LyXText * text = lv_->view()->text;
279     int type = LyXParagraph::PEXTRA_NONE;
280     LyXParagraph::MINIPAGE_ALIGNMENT
281         alignment = LyXParagraph::MINIPAGE_ALIGN_TOP;
282     bool
283         hfill = false,
284         start_minipage = false;
285
286     if (fl_get_button(extra_->radio_pextra_indent)) {
287         type = LyXParagraph::PEXTRA_INDENT;
288     } else if (fl_get_button(extra_->radio_pextra_minipage)) {
289         type = LyXParagraph::PEXTRA_MINIPAGE;
290         hfill = fl_get_button(extra_->radio_pextra_hfill);
291         start_minipage = fl_get_button(extra_->radio_pextra_startmp);
292         if (fl_get_button(extra_->radio_pextra_top))
293             alignment = LyXParagraph::MINIPAGE_ALIGN_TOP;
294         else if (fl_get_button(extra_->radio_pextra_middle))
295             alignment = LyXParagraph::MINIPAGE_ALIGN_MIDDLE;
296         else if (fl_get_button(extra_->radio_pextra_bottom))
297             alignment = LyXParagraph::MINIPAGE_ALIGN_BOTTOM;
298     } else if (fl_get_button(extra_->radio_pextra_floatflt)) {
299         type = LyXParagraph::PEXTRA_FLOATFLT;
300     }
301     text->SetParagraphExtraOpt(lv_->view(), type, width, widthp, alignment,
302                                hfill, start_minipage);
303 }
304
305
306 void FormParagraph::cancel()
307 {
308 }
309
310
311 void FormParagraph::update()
312 {
313     if (!dialog_)
314         return;
315
316     general_update();
317     extra_update();
318 }
319
320
321 void FormParagraph::general_update()
322 {
323     if (!general_)
324         return;
325
326     Buffer * buf = lv_->view()->buffer();
327     LyXText * text = 0;
328
329     if (lv_->view()->the_locking_inset)
330         text = lv_->view()->the_locking_inset->getLyXText(lv_->view());
331     if (!text)
332         text = lv_->view()->text;
333
334     fl_set_input(general_->input_labelwidth,
335                  text->cursor.par()->GetLabelWidthString().c_str());
336     fl_set_button(general_->radio_align_right, 0);
337     fl_set_button(general_->radio_align_left, 0);
338     fl_set_button(general_->radio_align_center, 0);
339     fl_set_button(general_->radio_align_block, 0);
340
341     int align = text->cursor.par()->GetAlign();
342     if (align == LYX_ALIGN_LAYOUT)
343         align = textclasslist.Style(buf->params.textclass,
344                                     text->cursor.par()->GetLayout()).align;
345          
346     switch (align) {
347     case LYX_ALIGN_RIGHT:
348         fl_set_button(general_->radio_align_right, 1);
349         break;
350     case LYX_ALIGN_LEFT:
351         fl_set_button(general_->radio_align_left, 1);
352         break;
353     case LYX_ALIGN_CENTER:
354         fl_set_button(general_->radio_align_center, 1);
355         break;
356     default:
357         fl_set_button(general_->radio_align_block, 1);
358         break;
359     }
360
361 #ifndef NEW_INSETS
362     fl_set_button(general_->check_lines_top,
363                   text->cursor.par()->FirstPhysicalPar()->line_top);
364     
365     fl_set_button(general_->check_lines_bottom,
366                   text->cursor.par()->FirstPhysicalPar()->line_bottom);
367     
368     fl_set_button(general_->check_pagebreaks_top,
369                   text->cursor.par()->FirstPhysicalPar()->pagebreak_top);
370     
371     fl_set_button(general_->check_pagebreaks_bottom,
372                   text->cursor.par()->FirstPhysicalPar()->pagebreak_bottom);
373     fl_set_button(general_->check_noindent,
374                   text->cursor.par()->FirstPhysicalPar()->noindent);
375 #else
376     fl_set_button(general_->check_lines_top,
377                   text->cursor.par()->line_top);
378     fl_set_button(general_->check_lines_bottom,
379                   text->cursor.par()->line_bottom);
380     fl_set_button(general_->check_pagebreaks_top,
381                   text->cursor.par()->pagebreak_top);
382     fl_set_button(general_->check_pagebreaks_bottom,
383                   text->cursor.par()->pagebreak_bottom);
384     fl_set_button(general_->check_noindent,
385                   text->cursor.par()->noindent);
386 #endif
387     fl_set_input (general_->input_space_above, "");
388
389 #ifndef NEW_INSETS
390     switch (text->cursor.par()->FirstPhysicalPar()->added_space_top.kind()) {
391 #else
392     switch (text->cursor.par()->added_space_top.kind()) {
393 #endif
394
395     case VSpace::NONE:
396         fl_set_choice (general_->choice_space_above, 1);
397         break;
398     case VSpace::DEFSKIP:
399         fl_set_choice (general_->choice_space_above, 2);
400         break;
401     case VSpace::SMALLSKIP:
402         fl_set_choice (general_->choice_space_above, 3);
403         break;
404     case VSpace::MEDSKIP:
405         fl_set_choice (general_->choice_space_above, 4);
406         break;
407     case VSpace::BIGSKIP:
408         fl_set_choice (general_->choice_space_above, 5);
409         break;
410     case VSpace::VFILL:
411         fl_set_choice (general_->choice_space_above, 6);
412         break;
413     case VSpace::LENGTH:
414         fl_set_choice (general_->choice_space_above, 7);
415 #ifndef NEW_INSETS
416         fl_set_input  (general_->input_space_above, 
417                        text->cursor.par()->FirstPhysicalPar()->
418                        added_space_top.length().asString().c_str());
419 #else
420         fl_set_input  (general_->input_space_above, text->cursor.par()->
421                        added_space_top.length().asString().c_str());
422 #endif
423         break;
424     }
425 #ifndef NEW_INSETS
426     fl_set_button(general_->check_space_above,
427                    text->cursor.par()->FirstPhysicalPar()->
428                    added_space_top.keep());
429     fl_set_input(general_->input_space_below, "");
430     switch (text->cursor.par()->FirstPhysicalPar()->
431             added_space_bottom.kind()) {
432 #else
433     fl_set_button (general_->check_space_above,
434                    text->cursor.par()->added_space_top.keep());
435     fl_set_input (general_->input_space_below, "");
436     switch (text->cursor.par()->added_space_bottom.kind()) {
437 #endif
438     case VSpace::NONE:
439         fl_set_choice (general_->choice_space_below, 1);
440         break;
441     case VSpace::DEFSKIP:
442         fl_set_choice (general_->choice_space_below, 2);
443         break;
444     case VSpace::SMALLSKIP:
445         fl_set_choice (general_->choice_space_below, 3);
446         break;
447     case VSpace::MEDSKIP:
448         fl_set_choice (general_->choice_space_below, 4);
449         break;
450     case VSpace::BIGSKIP:
451         fl_set_choice (general_->choice_space_below, 5);
452         break;
453     case VSpace::VFILL:
454         fl_set_choice (general_->choice_space_below, 6);
455         break;
456     case VSpace::LENGTH:
457         fl_set_choice (general_->choice_space_below, 7);
458 #ifndef NEW_INSETS
459         fl_set_input  (general_->input_space_below, 
460                        text->cursor.par()->FirstPhysicalPar()->
461                        added_space_bottom.length().asString().c_str());
462         break;
463     }
464     fl_set_button(general_->check_space_below,
465                    text->cursor.par()->FirstPhysicalPar()->
466                    added_space_bottom.keep());
467     fl_set_button(general_->check_noindent,
468                   text->cursor.par()->FirstPhysicalPar()->noindent);
469 #else
470         fl_set_input(general_->input_space_below, text->cursor.par()->
471                      added_space_bottom.length().asString().c_str());
472         break;
473     }
474     fl_set_button(general_->check_space_below,
475                    text->cursor.par()->added_space_bottom.keep());
476     fl_set_button(general_->check_noindent,
477                   text->cursor.par()->noindent);
478 #endif
479 }
480
481
482 void FormParagraph::extra_update()
483 {
484     if (!lv_->view()->available() || !extra_)
485         return;
486
487     LyXParagraph * par = lv_->view()->text->cursor.par();
488
489     fl_activate_object(extra_->input_pextra_width);
490     fl_activate_object(extra_->input_pextra_widthp);
491     fl_set_input(extra_->input_pextra_width,
492                  par->pextra_width.c_str());
493     fl_set_input(extra_->input_pextra_widthp,
494                  par->pextra_widthp.c_str());
495     switch(par->pextra_alignment) {
496     case LyXParagraph::MINIPAGE_ALIGN_TOP:
497         fl_set_button(extra_->radio_pextra_top, 1);
498         break;
499     case LyXParagraph::MINIPAGE_ALIGN_MIDDLE:
500         fl_set_button(extra_->radio_pextra_middle, 1);
501         break;
502     case LyXParagraph::MINIPAGE_ALIGN_BOTTOM:
503         fl_set_button(extra_->radio_pextra_bottom, 1);
504         break;
505     }
506     fl_set_button(extra_->radio_pextra_hfill,
507                   par->pextra_hfill);
508     fl_set_button(extra_->radio_pextra_startmp,
509                   par->pextra_start_minipage);
510     if (par->pextra_type == LyXParagraph::PEXTRA_INDENT) {
511         fl_set_button(extra_->radio_pextra_indent, 1);
512         fl_set_button(extra_->radio_pextra_minipage, 0);
513         fl_set_button(extra_->radio_pextra_floatflt, 0);
514         fl_deactivate_object(extra_->radio_pextra_top);
515         fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
516         fl_deactivate_object(extra_->radio_pextra_middle);
517         fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
518         fl_deactivate_object(extra_->radio_pextra_bottom);
519         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
520         CheckParagraphInput(extra_->radio_pextra_indent, 0);
521     } else if (par->pextra_type == LyXParagraph::PEXTRA_MINIPAGE) {
522         fl_set_button(extra_->radio_pextra_indent, 0);
523         fl_set_button(extra_->radio_pextra_minipage, 1);
524         fl_set_button(extra_->radio_pextra_floatflt, 0);
525         fl_activate_object(extra_->radio_pextra_top);
526         fl_set_object_lcol(extra_->radio_pextra_top, FL_BLACK);
527         fl_activate_object(extra_->radio_pextra_middle);
528         fl_set_object_lcol(extra_->radio_pextra_middle, FL_BLACK);
529         fl_activate_object(extra_->radio_pextra_bottom);
530         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_BLACK);
531         CheckParagraphInput(extra_->radio_pextra_minipage, 0);
532     } else if (par->pextra_type == LyXParagraph::PEXTRA_FLOATFLT) {
533         fl_set_button(extra_->radio_pextra_indent, 0);
534         fl_set_button(extra_->radio_pextra_minipage, 0);
535         fl_set_button(extra_->radio_pextra_floatflt, 1);
536         fl_deactivate_object(extra_->radio_pextra_top);
537         fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
538         fl_deactivate_object(extra_->radio_pextra_middle);
539         fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
540         fl_deactivate_object(extra_->radio_pextra_bottom);
541         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
542         CheckParagraphInput(extra_->radio_pextra_floatflt, 0);
543     } else {
544         fl_set_button(extra_->radio_pextra_indent, 0);
545         fl_set_button(extra_->radio_pextra_minipage, 0);
546         fl_set_button(extra_->radio_pextra_floatflt, 0);
547         fl_deactivate_object(extra_->input_pextra_width);
548         fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
549         fl_deactivate_object(extra_->input_pextra_widthp);
550         fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
551         fl_deactivate_object(extra_->radio_pextra_top);
552         fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
553         fl_deactivate_object(extra_->radio_pextra_middle);
554         fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
555         fl_deactivate_object(extra_->radio_pextra_bottom);
556         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
557         CheckParagraphInput(0, 0);
558     }
559     fl_hide_object(dialog_->text_warning);
560 }
561
562
563 void FormParagraph::free()
564 {
565     if (dialog_) {
566         hide();
567         if (general_) {
568 //            fl_free_form(general_->form);
569             delete general_;
570             general_ = 0;
571         }
572         if (extra_) {
573 //            fl_free_form(extra_->form);
574             delete extra_;
575             extra_ = 0;
576         }
577 //        fl_free_form(dialog_->form);
578         delete dialog_;
579         dialog_ = 0;
580     }
581 }
582
583
584 int FormParagraph::WMHideCB(FL_FORM * form, void *)
585 {
586     // Ensure that the signals (u and h) are disconnected even if the
587     // window manager is used to close the popup.
588     FormParagraph * pre = static_cast<FormParagraph*>(form->u_vdata);
589     pre->hide();
590     pre->bc_->hide();
591     return FL_CANCEL;
592 }
593
594
595 void FormParagraph::OKCB(FL_OBJECT * ob, long)
596 {
597     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
598     pre->apply();
599     pre->hide();
600     pre->bc_->ok();
601 }
602
603
604 void FormParagraph::ApplyCB(FL_OBJECT * ob, long)
605 {
606     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
607     pre->apply();
608     pre->bc_->apply();
609 }
610
611
612 void FormParagraph::CancelCB(FL_OBJECT * ob, long)
613 {
614     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
615     pre->cancel();
616     pre->hide();
617     pre->bc_->cancel();
618 }
619
620
621 void FormParagraph::RestoreCB(FL_OBJECT * ob, long)
622 {
623     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
624     pre->update();
625     pre->bc_->undoAll();
626 }
627
628
629 void FormParagraph::InputCB(FL_OBJECT * ob, long)
630 {
631     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
632     pre->bc_->valid(pre->CheckParagraphInput(ob,0));
633 }
634
635
636 void FormParagraph::VSpaceCB(FL_OBJECT * ob, long)
637 {
638     FormParagraph * pre = static_cast<FormParagraph*>(ob->form->u_vdata);
639     pre->bc_->valid(pre->CheckParagraphInput(ob,0));
640 }
641
642
643 bool FormParagraph::CheckParagraphInput(FL_OBJECT * ob, long)
644 {
645     bool ret = true;
646
647     fl_hide_object(dialog_->text_warning);
648
649     // First check the buttons which are exclusive and you have to
650     // check only the actuall de/activated button.
651     //
652     // general form first
653     //
654     // "Synchronize" the choices and input fields, making it
655     // impossible to commit senseless data.
656     if (ob == general_->choice_space_above) {
657         if (fl_get_choice (general_->choice_space_above) != 7)
658             fl_set_input (general_->input_space_above, "");
659     } else if (ob == general_->choice_space_below) {
660         if (fl_get_choice (general_->choice_space_below) != 7)
661             fl_set_input (general_->input_space_below, "");
662     }
663     //
664     // then the extra form
665     //
666     else if (ob == extra_->radio_pextra_indent) {
667         int n = fl_get_button(extra_->radio_pextra_indent);
668         if (n) {
669             fl_set_button(extra_->radio_pextra_minipage, 0);
670             fl_set_button(extra_->radio_pextra_floatflt, 0);
671             fl_activate_object(extra_->input_pextra_width);
672             fl_set_object_lcol(extra_->input_pextra_width, FL_BLACK);
673             fl_activate_object(extra_->input_pextra_widthp);
674             fl_set_object_lcol(extra_->input_pextra_widthp, FL_BLACK);
675         } else {
676             fl_deactivate_object(extra_->input_pextra_width);
677             fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
678             fl_deactivate_object(extra_->input_pextra_widthp);
679             fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
680         }
681         fl_deactivate_object(extra_->radio_pextra_top);
682         fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
683         fl_deactivate_object(extra_->radio_pextra_middle);
684         fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
685         fl_deactivate_object(extra_->radio_pextra_bottom);
686         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
687         fl_activate_object(extra_->radio_pextra_hfill);
688         fl_set_object_lcol(extra_->radio_pextra_hfill, FL_INACTIVE);
689         fl_activate_object(extra_->radio_pextra_startmp);
690         fl_set_object_lcol(extra_->radio_pextra_startmp, FL_INACTIVE);
691     } else if (ob == extra_->radio_pextra_minipage) {
692         int n = fl_get_button(extra_->radio_pextra_minipage);
693         if (n) {
694             fl_set_button(extra_->radio_pextra_indent, 0);
695             fl_set_button(extra_->radio_pextra_floatflt, 0);
696             fl_activate_object(extra_->input_pextra_width);
697             fl_set_object_lcol(extra_->input_pextra_width, FL_BLACK);
698             fl_activate_object(extra_->input_pextra_widthp);
699             fl_set_object_lcol(extra_->input_pextra_widthp, FL_BLACK);
700             fl_activate_object(extra_->radio_pextra_top);
701             fl_set_object_lcol(extra_->radio_pextra_top, FL_BLACK);
702             fl_activate_object(extra_->radio_pextra_middle);
703             fl_set_object_lcol(extra_->radio_pextra_middle, FL_BLACK);
704             fl_activate_object(extra_->radio_pextra_bottom);
705             fl_set_object_lcol(extra_->radio_pextra_bottom, FL_BLACK);
706             fl_activate_object(extra_->radio_pextra_hfill);
707             fl_set_object_lcol(extra_->radio_pextra_hfill, FL_BLACK);
708             fl_activate_object(extra_->radio_pextra_startmp);
709             fl_set_object_lcol(extra_->radio_pextra_startmp, FL_BLACK);
710         } else {
711             fl_deactivate_object(extra_->input_pextra_width);
712             fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
713             fl_deactivate_object(extra_->input_pextra_widthp);
714             fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
715             fl_deactivate_object(extra_->radio_pextra_top);
716             fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
717             fl_deactivate_object(extra_->radio_pextra_middle);
718             fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
719             fl_deactivate_object(extra_->radio_pextra_bottom);
720             fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
721             fl_activate_object(extra_->radio_pextra_hfill);
722             fl_set_object_lcol(extra_->radio_pextra_hfill, FL_INACTIVE);
723             fl_activate_object(extra_->radio_pextra_startmp);
724             fl_set_object_lcol(extra_->radio_pextra_startmp, FL_INACTIVE);
725         }
726     } else if (ob == extra_->radio_pextra_floatflt) {
727         int n = fl_get_button(extra_->radio_pextra_floatflt);
728         if (n) {
729             fl_set_button(extra_->radio_pextra_indent, 0);
730             fl_set_button(extra_->radio_pextra_minipage, 0);
731             fl_activate_object(extra_->input_pextra_width);
732             fl_set_object_lcol(extra_->input_pextra_width, FL_BLACK);
733             fl_activate_object(extra_->input_pextra_widthp);
734             fl_set_object_lcol(extra_->input_pextra_widthp, FL_BLACK);
735         } else {
736             fl_deactivate_object(extra_->input_pextra_width);
737             fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
738             fl_deactivate_object(extra_->input_pextra_widthp);
739             fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
740         }
741         fl_deactivate_object(extra_->radio_pextra_top);
742         fl_set_object_lcol(extra_->radio_pextra_top, FL_INACTIVE);
743         fl_deactivate_object(extra_->radio_pextra_middle);
744         fl_set_object_lcol(extra_->radio_pextra_middle, FL_INACTIVE);
745         fl_deactivate_object(extra_->radio_pextra_bottom);
746         fl_set_object_lcol(extra_->radio_pextra_bottom, FL_INACTIVE);
747         fl_activate_object(extra_->radio_pextra_hfill);
748         fl_set_object_lcol(extra_->radio_pextra_hfill, FL_INACTIVE);
749         fl_activate_object(extra_->radio_pextra_startmp);
750         fl_set_object_lcol(extra_->radio_pextra_startmp, FL_INACTIVE);
751     }
752     
753     //
754     // first the general form
755     //
756     string input = fl_get_input (general_->input_space_above);
757         
758     if (input.empty()) {
759         fl_set_choice (general_->choice_space_above, 1);
760     } else if (isValidGlueLength (input)) {
761         fl_set_choice (general_->choice_space_above, 7);
762     } else {
763         fl_set_choice (general_->choice_space_above, 7);
764         fl_set_object_label(dialog_->text_warning,
765                     _("Warning: Invalid Length (valid example: 10mm)"));
766         fl_show_object(dialog_->text_warning);
767         ret = false;
768     }
769     
770     input = fl_get_input (general_->input_space_below);
771         
772     if (input.empty()) {
773         fl_set_choice (general_->choice_space_below, 1);
774     } else if (isValidGlueLength(input)) {
775         fl_set_choice (general_->choice_space_below, 7);
776     } else {
777         fl_set_choice (general_->choice_space_below, 7);
778         fl_set_object_label(dialog_->text_warning,
779                     _("Warning: Invalid Length (valid example: 10mm)"));
780         fl_show_object(dialog_->text_warning);
781         ret = false;
782     }
783     //
784     // then the extra form
785     //
786     int n = fl_get_button(extra_->radio_pextra_indent) +
787         fl_get_button(extra_->radio_pextra_minipage) +
788         fl_get_button(extra_->radio_pextra_floatflt);
789     string s1 = fl_get_input(extra_->input_pextra_width);
790     string s2 = fl_get_input(extra_->input_pextra_widthp);
791     if (!n) { // no button pressed both should be deactivated now
792         fl_deactivate_object(extra_->input_pextra_width);
793         fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
794         fl_deactivate_object(extra_->input_pextra_widthp);
795         fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
796         fl_hide_object(dialog_->text_warning);
797     } else if (s1.empty() && s2.empty()) {
798         fl_activate_object(extra_->input_pextra_width);
799         fl_set_object_lcol(extra_->input_pextra_width, FL_BLACK);
800         fl_activate_object(extra_->input_pextra_widthp);
801         fl_set_object_lcol(extra_->input_pextra_widthp, FL_BLACK);
802         fl_hide_object(dialog_->text_warning);
803         ret = false;
804     } else if (!s1.empty()) { // LyXLength parameter
805         fl_activate_object(extra_->input_pextra_width);
806         fl_set_object_lcol(extra_->input_pextra_width, FL_BLACK);
807         fl_deactivate_object(extra_->input_pextra_widthp);
808         fl_set_object_lcol(extra_->input_pextra_widthp, FL_INACTIVE);
809         if (!isValidLength(s1)) {
810             fl_set_object_label(dialog_->text_warning,
811                         _("Warning: Invalid Length (valid example: 10mm)"));
812             fl_show_object(dialog_->text_warning);
813             ret = false;
814         }
815     } else { // !s2.empty() % parameter
816         fl_deactivate_object(extra_->input_pextra_width);
817         fl_set_object_lcol(extra_->input_pextra_width, FL_INACTIVE);
818         fl_activate_object(extra_->input_pextra_widthp);
819         fl_set_object_lcol(extra_->input_pextra_widthp, FL_BLACK);
820         if ((atoi(s2.c_str()) < 0 ) || (atoi(s2.c_str()) > 100)) {
821             ret = false;
822             fl_set_object_label(dialog_->text_warning,
823                         _("Warning: Invalid percent value (0-100)"));
824             fl_show_object(dialog_->text_warning);
825         }
826     }
827     return ret;
828 }