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