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