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