]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormParagraph.C
move space above/below from Paragraph into a separate vspace inset.
[lyx.git] / src / frontends / xforms / FormParagraph.C
1 /**
2  * \file FormParagraph.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna
7  * \author Rob Lahaye
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "FormParagraph.h"
15 #include "ControlParagraph.h"
16 #include "forms/form_paragraph.h"
17
18 #include "checkedwidgets.h"
19 #include "input_validators.h"
20 #include "Tooltips.h"
21 #include "xforms_helpers.h"
22 #include "xformsBC.h"
23
24 #include "controllers/helper_funcs.h"
25
26 #include "lyxrc.h" // to set the deafult length values
27 #include "ParagraphParameters.h"
28 #include "Spacing.h"
29
30 #include "support/lstrings.h"
31 #include "support/tostr.h"
32
33 #include "lyx_forms.h"
34
35 using lyx::support::contains_functor;
36 using lyx::support::getStringFromVector;
37 using lyx::support::rtrim;
38
39 using std::bind2nd;
40 using std::remove_if;
41
42 using std::vector;
43 using std::string;
44
45
46 namespace {
47
48 string defaultUnit("cm");
49
50 } // namespace anon
51
52
53 typedef FormController<ControlParagraph, FormView<FD_paragraph> > base_class;
54
55 FormParagraph::FormParagraph(Dialog & parent)
56         : base_class(parent, _("Paragraph Settings"))
57 {}
58
59
60 void FormParagraph::build()
61 {
62         // the tabbed folder
63         dialog_.reset(build_paragraph(this));
64
65         // Manage the ok, apply, restore and cancel/close buttons
66         bcview().setOK(dialog_->button_ok);
67         bcview().setApply(dialog_->button_apply);
68         bcview().setCancel(dialog_->button_close);
69         bcview().setRestore(dialog_->button_restore);
70
71         // disable for read-only documents
72         bcview().addReadOnly(dialog_->check_noindent);
73         bcview().addReadOnly(dialog_->choice_linespacing);
74         bcview().addReadOnly(dialog_->input_linespacing);
75
76         bcview().addReadOnly(dialog_->input_labelwidth);
77
78         // trigger an input event for cut&paste with middle mouse button.
79         setPrehandler(dialog_->input_linespacing);
80         setPrehandler(dialog_->input_labelwidth);
81
82         fl_set_input_return(dialog_->input_labelwidth,  FL_RETURN_CHANGED);
83         fl_set_input_return(dialog_->input_linespacing, FL_RETURN_CHANGED);
84
85         // limit these inputs to unsigned floats
86         fl_set_input_filter(dialog_->input_linespacing, fl_unsigned_float_filter);
87
88         // add alignment radio buttons
89         alignment_.init(dialog_->radio_align_left,   LYX_ALIGN_LEFT);
90         alignment_.init(dialog_->radio_align_right,  LYX_ALIGN_RIGHT);
91         alignment_.init(dialog_->radio_align_block,  LYX_ALIGN_BLOCK);
92         alignment_.init(dialog_->radio_align_center, LYX_ALIGN_CENTER);
93
94         string const linespacing = _("Default|Single|OneHalf|Double|Custom");
95         fl_addto_choice(dialog_->choice_linespacing, linespacing.c_str());
96
97         // Create the contents of the unit choices; don't include the "%" terms.
98         vector<string> units_vec = getLatexUnits();
99         vector<string>::iterator del =
100                 remove_if(units_vec.begin(), units_vec.end(),
101                           bind2nd(contains_functor(), "%"));
102         units_vec.erase(del, units_vec.end());
103
104         // set default unit for custom length
105         switch (lyxrc.default_papersize) {
106                 case PAPER_DEFAULT:
107                 case PAPER_USLETTER:
108                 case PAPER_LEGALPAPER:
109                 case PAPER_EXECUTIVEPAPER:
110                         defaultUnit = "in";
111                         break;
112                 case PAPER_A3PAPER:
113                 case PAPER_A4PAPER:
114                 case PAPER_A5PAPER:
115                 case PAPER_B5PAPER:
116                         defaultUnit = "cm";
117                         break;
118         }
119 }
120
121
122 void FormParagraph::apply()
123 {
124         if (!form())
125                 return;
126
127         // alignment
128         LyXAlignment const alignment =
129                 static_cast<LyXAlignment>(alignment_.get());
130         controller().params().align(alignment);
131
132         // label width
133         string const labelwidthstring =
134                 getString(dialog_->input_labelwidth);
135         controller().params().labelWidthString(labelwidthstring);
136
137         // indendation
138         bool const noindent = fl_get_button(dialog_->check_noindent);
139         controller().params().noindent(noindent);
140
141         // get spacing
142         Spacing::Space linespacing = Spacing::Default;
143         string other;
144         switch (fl_get_choice(dialog_->choice_linespacing)) {
145         case 1:
146                 linespacing = Spacing::Default;
147                 break;
148         case 2:
149                 linespacing = Spacing::Single;
150                 break;
151         case 3:
152                 linespacing = Spacing::Onehalf;
153                 break;
154         case 4:
155                 linespacing = Spacing::Double;
156                 break;
157         case 5:
158                 // reset to default if input is empty
159                 other = getString(dialog_->input_linespacing);
160                 if (!other.empty()) {
161                         linespacing = Spacing::Other;
162                 } else {
163                         linespacing = Spacing::Default;
164                         fl_set_choice(dialog_->choice_linespacing, 1);
165                 }
166                 break;
167         }
168         Spacing const spacing(linespacing, other);
169         controller().params().spacing(spacing);
170 }
171
172
173 void FormParagraph::update()
174 {
175         if (!dialog_.get())
176                 return;
177
178         // label width
179         string const labelwidth = controller().params().labelWidthString();
180         fl_set_input(dialog_->input_labelwidth, labelwidth.c_str());
181         setEnabled(dialog_->input_labelwidth,
182                    labelwidth != _("Senseless with this layout!"));
183
184         // alignment
185         alignment_.set(controller().params().align());
186
187         // mark default alignment
188         LyXAlignment const default_alignment = controller().alignDefault();
189
190         string label = _("Block");
191         if (default_alignment == LYX_ALIGN_BLOCK) {
192                 label += _(" (default)");
193         }
194         fl_set_object_label(dialog_->radio_align_block, label.c_str());
195         fl_set_button_shortcut(dialog_->radio_align_block, "#B", 1);
196
197         label = _("Center");
198         if (default_alignment == LYX_ALIGN_CENTER) {
199                 label += _(" (default)");
200         }
201         fl_set_object_label(dialog_->radio_align_center, label.c_str());
202         fl_set_button_shortcut(dialog_->radio_align_center, "#C", 1);
203
204         label = _("Left");
205         if (default_alignment == LYX_ALIGN_LEFT) {
206                 label += _(" (default)");
207         }
208         fl_set_object_label(dialog_->radio_align_left, label.c_str());
209         fl_set_button_shortcut(dialog_->radio_align_left, "#L", 1);
210
211         label = _("Right");
212         if (default_alignment == LYX_ALIGN_RIGHT) {
213                 label = _(" (default)");
214         }
215         fl_set_object_label(dialog_->radio_align_right, label.c_str());
216         fl_set_button_shortcut(dialog_->radio_align_right, "#R", 1);
217
218         // Ensure that there's no crud left on the screen from this change
219         // of labels.
220         fl_redraw_form(form());
221
222         LyXAlignment alignpos = controller().alignPossible();
223         setEnabled(dialog_->radio_align_block,
224                    bool(alignpos & LYX_ALIGN_BLOCK));
225         setEnabled(dialog_->radio_align_center,
226                    bool(alignpos & LYX_ALIGN_CENTER));
227         setEnabled(dialog_->radio_align_left,
228                    bool(alignpos & LYX_ALIGN_LEFT));
229         setEnabled(dialog_->radio_align_right,
230                    bool(alignpos & LYX_ALIGN_RIGHT));
231
232         // lines, pagebreaks and indent
233         fl_set_button(dialog_->check_noindent,
234                       controller().params().noindent());
235
236         // linespacing
237         Spacing const space = controller().params().spacing();
238
239         int pos;
240         switch (space.getSpace()) {
241         case Spacing::Other:
242                 pos = 5;
243                 break;
244         case Spacing::Double:
245                 pos = 4;
246                 break;
247         case Spacing::Onehalf:
248                 pos = 3;
249                 break;
250         case Spacing::Single:
251                 pos = 2;
252                 break;
253         case Spacing::Default:
254         default:
255                 pos = 1;
256                 break;
257         }
258         fl_set_choice(dialog_->choice_linespacing, pos);
259
260         bool const spacing_other = space.getSpace() == Spacing::Other;
261         setEnabled(dialog_->input_linespacing, spacing_other);
262         if (spacing_other) {
263                 string const sp = tostr(space.getValue());
264                 fl_set_input(dialog_->input_linespacing, sp.c_str());
265         } else {
266                 fl_set_input(dialog_->input_linespacing, "");
267         }
268
269         // no indent
270         fl_set_button(dialog_->check_noindent,
271                       controller().params().noindent());
272 }
273
274
275 ButtonPolicy::SMInput FormParagraph::input(FL_OBJECT * ob, long)
276 {
277         // Enable input when custum length is choosen,
278         // disable 'keep' when no space is choosen
279         if (ob == dialog_->choice_linespacing) {
280                 bool const custom_spacing =
281                         fl_get_choice(dialog_->choice_linespacing) == 5;
282                 setEnabled(dialog_->input_linespacing, custom_spacing);
283         }
284
285         return ButtonPolicy::SMI_VALID;
286 }