]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormParagraph.C
2c299281d53905def469b23a43a0f2d46968afa7
[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     general_update();
130
131     bc_.readOnly(lv_->buffer()->isReadonly());
132 }
133
134
135 void FormParagraph::general_apply()
136 {
137     VSpace space_top, space_bottom;
138     LyXAlignment align;
139     string labelwidthstring;
140     bool noindent;
141
142     // If a vspace kind is "Length" but there's no text in
143     // the input field, reset the kind to "None". 
144     if ((fl_get_choice (general_->choice_space_above) == 7) &&
145         !*(fl_get_input (general_->input_space_above)))
146     {
147         fl_set_choice (general_->choice_space_above, 1);
148     }
149     if ((fl_get_choice (general_->choice_space_below) == 7) &&
150         !*(fl_get_input (general_->input_space_below)))
151     {
152         fl_set_choice (general_->choice_space_below, 1);
153     }
154    
155     bool line_top = fl_get_button(general_->check_lines_top);
156     bool line_bottom = fl_get_button(general_->check_lines_bottom);
157     bool pagebreak_top = fl_get_button(general_->check_pagebreaks_top);
158     bool pagebreak_bottom = fl_get_button(general_->check_pagebreaks_bottom);
159     
160     switch (fl_get_choice (general_->choice_space_above)) {
161     case 1:
162         space_top = VSpace(VSpace::NONE);
163         break;
164     case 2:
165         space_top = VSpace(VSpace::DEFSKIP);
166         break;
167     case 3:
168         space_top = VSpace(VSpace::SMALLSKIP);
169         break;
170     case 4:
171         space_top = VSpace(VSpace::MEDSKIP);
172         break;
173     case 5:
174         space_top = VSpace(VSpace::BIGSKIP);
175         break;
176     case 6:
177         space_top = VSpace(VSpace::VFILL);
178         break;
179     case 7:
180         space_top =
181                 VSpace(LyXGlueLength(fl_get_input(general_->input_space_above)));
182         break;
183     }
184     if (fl_get_button (general_->check_space_above))
185         space_top.setKeep (true);
186     switch (fl_get_choice (general_->choice_space_below)) {
187     case 1:
188         space_bottom = VSpace(VSpace::NONE);
189         break;
190     case 2:
191         space_bottom = VSpace(VSpace::DEFSKIP);
192         break;
193     case 3:
194         space_bottom = VSpace(VSpace::SMALLSKIP);
195         break;
196     case 4:
197         space_bottom = VSpace(VSpace::MEDSKIP);
198         break;
199     case 5:
200         space_bottom = VSpace(VSpace::BIGSKIP);
201         break;
202     case 6:
203         space_bottom = VSpace(VSpace::VFILL);
204         break;
205     case 7:
206         space_bottom =
207                 VSpace(LyXGlueLength(fl_get_input(general_->input_space_below)));
208         break;
209     }
210     if (fl_get_button (general_->check_space_below))
211         space_bottom.setKeep (true);
212
213     if (fl_get_button(general_->radio_align_left))
214         align = LYX_ALIGN_LEFT;
215     else if (fl_get_button(general_->radio_align_right))
216         align = LYX_ALIGN_RIGHT;
217     else if (fl_get_button(general_->radio_align_center))
218         align = LYX_ALIGN_CENTER;
219     else 
220         align = LYX_ALIGN_BLOCK;
221    
222     labelwidthstring = fl_get_input(general_->input_labelwidth);
223     noindent = fl_get_button(general_->check_noindent);
224
225     LyXText * text = 0;
226     if (lv_->view()->theLockingInset())
227         text = lv_->view()->theLockingInset()->getLyXText(lv_->view());
228     if (!text)
229         text = lv_->view()->text;
230     text->SetParagraph(lv_->view(), line_top, line_bottom, pagebreak_top,
231                        pagebreak_bottom, space_top, space_bottom, align, 
232                        labelwidthstring, noindent);
233 }
234
235
236 void FormParagraph::general_update()
237 {
238     if (!general_.get())
239         return;
240
241     Buffer * buf = lv_->view()->buffer();
242     LyXText * text = 0;
243
244     if (lv_->view()->theLockingInset())
245         text = lv_->view()->theLockingInset()->getLyXText(lv_->view());
246     if (!text)
247         text = lv_->view()->text;
248
249     fl_set_input(general_->input_labelwidth,
250                  text->cursor.par()->GetLabelWidthString().c_str());
251     fl_set_button(general_->radio_align_right, 0);
252     fl_set_button(general_->radio_align_left, 0);
253     fl_set_button(general_->radio_align_center, 0);
254     fl_set_button(general_->radio_align_block, 0);
255
256     int align = text->cursor.par()->GetAlign();
257     if (align == LYX_ALIGN_LAYOUT)
258         align = textclasslist.Style(buf->params.textclass,
259                                     text->cursor.par()->GetLayout()).align;
260          
261     switch (align) {
262     case LYX_ALIGN_RIGHT:
263         fl_set_button(general_->radio_align_right, 1);
264         break;
265     case LYX_ALIGN_LEFT:
266         fl_set_button(general_->radio_align_left, 1);
267         break;
268     case LYX_ALIGN_CENTER:
269         fl_set_button(general_->radio_align_center, 1);
270         break;
271     default:
272         fl_set_button(general_->radio_align_block, 1);
273         break;
274     }
275
276     fl_set_button(general_->check_lines_top,
277                   text->cursor.par()->params.lineTop());
278     fl_set_button(general_->check_lines_bottom,
279                   text->cursor.par()->params.lineBottom());
280     fl_set_button(general_->check_pagebreaks_top,
281                   text->cursor.par()->params.pagebreakTop());
282     fl_set_button(general_->check_pagebreaks_bottom,
283                   text->cursor.par()->params.pagebreakBottom());
284     fl_set_button(general_->check_noindent,
285                   text->cursor.par()->params.noindent());
286
287     fl_set_input (general_->input_space_above, "");
288
289     switch (text->cursor.par()->params.spaceTop().kind()) {
290     case VSpace::NONE:
291         fl_set_choice (general_->choice_space_above, 1);
292         break;
293     case VSpace::DEFSKIP:
294         fl_set_choice (general_->choice_space_above, 2);
295         break;
296     case VSpace::SMALLSKIP:
297         fl_set_choice (general_->choice_space_above, 3);
298         break;
299     case VSpace::MEDSKIP:
300         fl_set_choice (general_->choice_space_above, 4);
301         break;
302     case VSpace::BIGSKIP:
303         fl_set_choice (general_->choice_space_above, 5);
304         break;
305     case VSpace::VFILL:
306         fl_set_choice (general_->choice_space_above, 6);
307         break;
308     case VSpace::LENGTH:
309         fl_set_choice (general_->choice_space_above, 7);
310         fl_set_input(general_->input_space_above, text->cursor.par()->
311                      params.spaceTop().length().asString().c_str());
312         break;
313     }
314     
315     fl_set_button (general_->check_space_above,
316                    text->cursor.par()->params.spaceTop().keep());
317     fl_set_input (general_->input_space_below, "");
318
319     switch (text->cursor.par()->params.spaceBottom().kind()) {
320     case VSpace::NONE:
321         fl_set_choice (general_->choice_space_below, 1);
322         break;
323     case VSpace::DEFSKIP:
324         fl_set_choice (general_->choice_space_below, 2);
325         break;
326     case VSpace::SMALLSKIP:
327         fl_set_choice (general_->choice_space_below, 3);
328         break;
329     case VSpace::MEDSKIP:
330         fl_set_choice (general_->choice_space_below, 4);
331         break;
332     case VSpace::BIGSKIP:
333         fl_set_choice (general_->choice_space_below, 5);
334         break;
335     case VSpace::VFILL:
336         fl_set_choice (general_->choice_space_below, 6);
337         break;
338     case VSpace::LENGTH:
339         fl_set_choice (general_->choice_space_below, 7);
340         fl_set_input(general_->input_space_below, text->cursor.par()->
341                      params.spaceBottom().length().asString().c_str());
342         break;
343     }
344     fl_set_button(general_->check_space_below,
345                    text->cursor.par()->params.spaceBottom().keep());
346     fl_set_button(general_->check_noindent,
347                   text->cursor.par()->params.noindent());
348 }
349
350
351 bool FormParagraph::input(FL_OBJECT * ob, long)
352 {
353     bool ret = true;
354
355     fl_hide_object(dialog_->text_warning);
356
357     // First check the buttons which are exclusive and you have to
358     // check only the actuall de/activated button.
359     //
360     // general form first
361     //
362     // "Synchronize" the choices and input fields, making it
363     // impossible to commit senseless data.
364
365     if (fl_get_choice (general_->choice_space_above) != 7)
366         fl_set_input (general_->input_space_above, "");
367
368     if (fl_get_choice (general_->choice_space_below) != 7)
369         fl_set_input (general_->input_space_below, "");
370
371     //
372     // first the general form
373     //
374     string input = fl_get_input (general_->input_space_above);
375     bool invalid = false;
376         
377     if (fl_get_choice(general_->choice_space_above)==7)
378         invalid = !input.empty() && !isValidGlueLength(input);
379
380     input = fl_get_input (general_->input_space_below);
381
382     if (fl_get_choice(general_->choice_space_below)==7)
383         invalid = invalid || (!input.empty() && !isValidGlueLength(input));
384     
385     if (ob == general_->input_space_above || ob == general_->input_space_below) {
386         if (invalid) {
387             fl_set_object_label(dialog_->text_warning,
388                 _("Warning: Invalid Length (valid example: 10mm)"));
389             fl_show_object(dialog_->text_warning);
390             return false;
391         } else {
392             fl_hide_object(dialog_->text_warning);
393             return true;
394         }
395     }
396
397     return ret;
398 }
399