]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormParagraph.C
ef51c02e2761b00cf17314aac01ddcb1f89ad0c8
[lyx.git] / src / frontends / xforms / FormParagraph.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 #ifdef __GNUG_
15 #pragma implementation
16 #endif
17
18 #include FORMS_H_LOCATION
19
20 #include "FormParagraph.h"
21 #include "form_paragraph.h"
22 #include "Dialogs.h"
23 #include "Liason.h"
24 #include "LyXView.h"
25 #include "buffer.h"
26 #include "lyxtext.h"
27 #include "xforms_helpers.h"
28
29 using Liason::setMinibuffer;
30 using SigC::slot;
31
32
33 FormParagraph::FormParagraph(LyXView * lv, Dialogs * d)
34         : FormBaseBD(lv, d, _("Paragraph Layout"))
35 {
36     // let the dialog be shown
37     // This is a permanent connection so we won't bother
38     // storing a copy because we won't be disconnecting.
39     d->showLayoutParagraph.connect(slot(this, &FormParagraph::show));
40 }
41
42
43 void FormParagraph::redraw()
44 {
45         if( form() && form()->visible )
46                 fl_redraw_form( form() );
47         else
48                 return;
49
50         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabbed_folder);
51         if (outer_form && outer_form->visible)
52                 fl_redraw_form( outer_form );
53 }
54
55
56 FL_FORM * FormParagraph::form() const
57 {
58     if (dialog_.get()) return dialog_->form;
59     return 0;
60 }
61
62
63 void FormParagraph::build()
64 {
65     // the tabbed folder
66     dialog_.reset(build_tabbed_paragraph());
67
68     // Manage the ok, apply, restore and cancel/close buttons
69     bc_.setOK(dialog_->button_ok);
70     bc_.setApply(dialog_->button_apply);
71     bc_.setCancel(dialog_->button_cancel);
72     bc_.setRestore(dialog_->button_restore);
73
74     // the general paragraph data form
75     general_.reset(build_paragraph_general());
76
77     fl_addto_choice(general_->choice_space_above,
78                     _(" None | Defskip | Smallskip "
79                       "| Medskip | Bigskip | VFill | Length "));
80     fl_addto_choice(general_->choice_space_below,
81                     _(" None | Defskip | Smallskip "
82                       "| Medskip | Bigskip | VFill | Length ")); 
83
84     fl_set_input_return(general_->input_space_above, FL_RETURN_CHANGED);
85     fl_set_input_return(general_->input_space_below, FL_RETURN_CHANGED);
86     fl_set_input_return(general_->input_labelwidth, FL_RETURN_CHANGED);
87
88     bc_.addReadOnly (general_->radio_align_right);
89     bc_.addReadOnly (general_->radio_align_left);
90     bc_.addReadOnly (general_->radio_align_block);
91     bc_.addReadOnly (general_->radio_align_center);
92     bc_.addReadOnly (general_->check_lines_top);
93     bc_.addReadOnly (general_->check_lines_bottom);
94     bc_.addReadOnly (general_->check_pagebreaks_top);
95     bc_.addReadOnly (general_->check_pagebreaks_bottom);
96     bc_.addReadOnly (general_->choice_space_above);
97     bc_.addReadOnly (general_->input_space_above);
98     bc_.addReadOnly (general_->check_space_above);
99     bc_.addReadOnly (general_->choice_space_below);
100     bc_.addReadOnly (general_->input_space_below);
101     bc_.addReadOnly (general_->check_space_below);
102     bc_.addReadOnly (general_->check_noindent);
103     bc_.addReadOnly (general_->input_labelwidth);
104
105     // now make them fit together
106     fl_addto_tabfolder(dialog_->tabbed_folder,_("General"), general_->form);
107 }
108
109
110 void FormParagraph::apply()
111 {
112     if (!lv_->view()->available() || !dialog_.get())
113         return;
114
115     general_apply();
116
117     lv_->view()->update(lv_->view()->text, 
118                         BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
119     lv_->buffer()->markDirty();
120     setMinibuffer(lv_, _("Paragraph layout set"));
121 }
122
123
124 void FormParagraph::update()
125 {
126     if (!dialog_.get())
127         return;
128
129     // Do this first; some objects may be de/activated subsequently.
130     bc_.readOnly(lv_->buffer()->isReadonly());
131
132     general_update();
133 }
134
135
136 void FormParagraph::general_apply()
137 {
138     VSpace space_top, space_bottom;
139     LyXAlignment align;
140     string labelwidthstring;
141     bool noindent;
142
143     // If a vspace kind is "Length" but there's no text in
144     // the input field, reset the kind to "None". 
145     if ((fl_get_choice (general_->choice_space_above) == 7) &&
146         !*(fl_get_input (general_->input_space_above)))
147     {
148         fl_set_choice (general_->choice_space_above, 1);
149     }
150     if ((fl_get_choice (general_->choice_space_below) == 7) &&
151         !*(fl_get_input (general_->input_space_below)))
152     {
153         fl_set_choice (general_->choice_space_below, 1);
154     }
155    
156     bool line_top = fl_get_button(general_->check_lines_top);
157     bool line_bottom = fl_get_button(general_->check_lines_bottom);
158     bool pagebreak_top = fl_get_button(general_->check_pagebreaks_top);
159     bool pagebreak_bottom = fl_get_button(general_->check_pagebreaks_bottom);
160     
161     switch (fl_get_choice (general_->choice_space_above)) {
162     case 1:
163         space_top = VSpace(VSpace::NONE);
164         break;
165     case 2:
166         space_top = VSpace(VSpace::DEFSKIP);
167         break;
168     case 3:
169         space_top = VSpace(VSpace::SMALLSKIP);
170         break;
171     case 4:
172         space_top = VSpace(VSpace::MEDSKIP);
173         break;
174     case 5:
175         space_top = VSpace(VSpace::BIGSKIP);
176         break;
177     case 6:
178         space_top = VSpace(VSpace::VFILL);
179         break;
180     case 7:
181         space_top =
182                 VSpace(LyXGlueLength(fl_get_input(general_->input_space_above)));
183         break;
184     }
185     if (fl_get_button (general_->check_space_above))
186         space_top.setKeep (true);
187     switch (fl_get_choice (general_->choice_space_below)) {
188     case 1:
189         space_bottom = VSpace(VSpace::NONE);
190         break;
191     case 2:
192         space_bottom = VSpace(VSpace::DEFSKIP);
193         break;
194     case 3:
195         space_bottom = VSpace(VSpace::SMALLSKIP);
196         break;
197     case 4:
198         space_bottom = VSpace(VSpace::MEDSKIP);
199         break;
200     case 5:
201         space_bottom = VSpace(VSpace::BIGSKIP);
202         break;
203     case 6:
204         space_bottom = VSpace(VSpace::VFILL);
205         break;
206     case 7:
207         space_bottom =
208                 VSpace(LyXGlueLength(fl_get_input(general_->input_space_below)));
209         break;
210     }
211     if (fl_get_button (general_->check_space_below))
212         space_bottom.setKeep (true);
213
214     if (fl_get_button(general_->radio_align_left))
215         align = LYX_ALIGN_LEFT;
216     else if (fl_get_button(general_->radio_align_right))
217         align = LYX_ALIGN_RIGHT;
218     else if (fl_get_button(general_->radio_align_center))
219         align = LYX_ALIGN_CENTER;
220     else 
221         align = LYX_ALIGN_BLOCK;
222    
223     labelwidthstring = fl_get_input(general_->input_labelwidth);
224     noindent = fl_get_button(general_->check_noindent);
225
226     LyXText * text = 0;
227     if (lv_->view()->theLockingInset())
228         text = lv_->view()->theLockingInset()->getLyXText(lv_->view());
229     if (!text)
230         text = lv_->view()->text;
231     text->SetParagraph(lv_->view(), line_top, line_bottom, pagebreak_top,
232                        pagebreak_bottom, space_top, space_bottom, align, 
233                        labelwidthstring, noindent);
234 }
235
236
237 void FormParagraph::general_update()
238 {
239     if (!general_.get())
240         return;
241
242     Buffer * buf = lv_->view()->buffer();
243     LyXText * text = 0;
244
245     if (lv_->view()->theLockingInset())
246         text = lv_->view()->theLockingInset()->getLyXText(lv_->view());
247     if (!text)
248         text = lv_->view()->text;
249
250     fl_set_input(general_->input_labelwidth,
251                  text->cursor.par()->GetLabelWidthString().c_str());
252     fl_set_button(general_->radio_align_right, 0);
253     fl_set_button(general_->radio_align_left, 0);
254     fl_set_button(general_->radio_align_center, 0);
255     fl_set_button(general_->radio_align_block, 0);
256
257     int align = text->cursor.par()->GetAlign();
258     if (align == LYX_ALIGN_LAYOUT)
259         align = textclasslist.Style(buf->params.textclass,
260                                     text->cursor.par()->GetLayout()).align;
261
262     switch (align) {
263     case LYX_ALIGN_RIGHT:
264         fl_set_button(general_->radio_align_right, 1);
265         break;
266     case LYX_ALIGN_LEFT:
267         fl_set_button(general_->radio_align_left, 1);
268         break;
269     case LYX_ALIGN_CENTER:
270         fl_set_button(general_->radio_align_center, 1);
271         break;
272     default:
273         fl_set_button(general_->radio_align_block, 1);
274         break;
275     }
276
277     LyXAlignment alignpos =
278             textclasslist.Style(buf->params.textclass,
279                                 text->cursor.par()->GetLayout()).alignpossible;
280
281     setEnabled(general_->radio_align_block,  bool(alignpos & LYX_ALIGN_BLOCK));
282     setEnabled(general_->radio_align_center, bool(alignpos & LYX_ALIGN_CENTER));
283     setEnabled(general_->radio_align_left,   bool(alignpos & LYX_ALIGN_LEFT));
284     setEnabled(general_->radio_align_right,  bool(alignpos & LYX_ALIGN_RIGHT));
285     
286     fl_set_button(general_->check_lines_top,
287                   text->cursor.par()->params.lineTop());
288     fl_set_button(general_->check_lines_bottom,
289                   text->cursor.par()->params.lineBottom());
290     fl_set_button(general_->check_pagebreaks_top,
291                   text->cursor.par()->params.pagebreakTop());
292     fl_set_button(general_->check_pagebreaks_bottom,
293                   text->cursor.par()->params.pagebreakBottom());
294     fl_set_button(general_->check_noindent,
295                   text->cursor.par()->params.noindent());
296
297     fl_set_input (general_->input_space_above, "");
298
299     switch (text->cursor.par()->params.spaceTop().kind()) {
300     case VSpace::NONE:
301         fl_set_choice (general_->choice_space_above, 1);
302         break;
303     case VSpace::DEFSKIP:
304         fl_set_choice (general_->choice_space_above, 2);
305         break;
306     case VSpace::SMALLSKIP:
307         fl_set_choice (general_->choice_space_above, 3);
308         break;
309     case VSpace::MEDSKIP:
310         fl_set_choice (general_->choice_space_above, 4);
311         break;
312     case VSpace::BIGSKIP:
313         fl_set_choice (general_->choice_space_above, 5);
314         break;
315     case VSpace::VFILL:
316         fl_set_choice (general_->choice_space_above, 6);
317         break;
318     case VSpace::LENGTH:
319         fl_set_choice (general_->choice_space_above, 7);
320         fl_set_input(general_->input_space_above, text->cursor.par()->
321                      params.spaceTop().length().asString().c_str());
322         break;
323     }
324     
325     fl_set_button (general_->check_space_above,
326                    text->cursor.par()->params.spaceTop().keep());
327     fl_set_input (general_->input_space_below, "");
328
329     switch (text->cursor.par()->params.spaceBottom().kind()) {
330     case VSpace::NONE:
331         fl_set_choice (general_->choice_space_below, 1);
332         break;
333     case VSpace::DEFSKIP:
334         fl_set_choice (general_->choice_space_below, 2);
335         break;
336     case VSpace::SMALLSKIP:
337         fl_set_choice (general_->choice_space_below, 3);
338         break;
339     case VSpace::MEDSKIP:
340         fl_set_choice (general_->choice_space_below, 4);
341         break;
342     case VSpace::BIGSKIP:
343         fl_set_choice (general_->choice_space_below, 5);
344         break;
345     case VSpace::VFILL:
346         fl_set_choice (general_->choice_space_below, 6);
347         break;
348     case VSpace::LENGTH:
349         fl_set_choice (general_->choice_space_below, 7);
350         fl_set_input(general_->input_space_below, text->cursor.par()->
351                      params.spaceBottom().length().asString().c_str());
352         break;
353     }
354     fl_set_button(general_->check_space_below,
355                    text->cursor.par()->params.spaceBottom().keep());
356     fl_set_button(general_->check_noindent,
357                   text->cursor.par()->params.noindent());
358 }
359
360
361 bool FormParagraph::input(FL_OBJECT * ob, long)
362 {
363     bool ret = true;
364
365     fl_hide_object(dialog_->text_warning);
366
367     // First check the buttons which are exclusive and you have to
368     // check only the actuall de/activated button.
369     //
370     // general form first
371     //
372     // "Synchronize" the choices and input fields, making it
373     // impossible to commit senseless data.
374
375     if (fl_get_choice (general_->choice_space_above) != 7)
376         fl_set_input (general_->input_space_above, "");
377
378     if (fl_get_choice (general_->choice_space_below) != 7)
379         fl_set_input (general_->input_space_below, "");
380
381     //
382     // first the general form
383     //
384     string input = fl_get_input (general_->input_space_above);
385     bool invalid = false;
386         
387     if (fl_get_choice(general_->choice_space_above)==7)
388         invalid = !input.empty() && !isValidGlueLength(input);
389
390     input = fl_get_input (general_->input_space_below);
391
392     if (fl_get_choice(general_->choice_space_below)==7)
393         invalid = invalid || (!input.empty() && !isValidGlueLength(input));
394     
395     if (ob == general_->input_space_above || ob == general_->input_space_below) {
396         if (invalid) {
397             fl_set_object_label(dialog_->text_warning,
398                 _("Warning: Invalid Length (valid example: 10mm)"));
399             fl_show_object(dialog_->text_warning);
400             return false;
401         } else {
402             fl_hide_object(dialog_->text_warning);
403             return true;
404         }
405     }
406
407     return ret;
408 }
409