]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormVSpace.C
The VSpace fixes (removal of VSPACE::NONE) from Michael and myself
[lyx.git] / src / frontends / xforms / FormVSpace.C
1 /**
2  * \file FormVSpace.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  * \author Jürgen Vigna
8  * \author Rob Lahaye
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "FormVSpace.h"
16 #include "ControlVSpace.h"
17 #include "forms/form_vspace.h"
18
19 #include "checkedwidgets.h"
20 #include "input_validators.h"
21 #include "Tooltips.h"
22 #include "xforms_helpers.h"
23 #include "xformsBC.h"
24
25 #include "controllers/helper_funcs.h"
26
27 #include "lyxrc.h" // to set the deafult length values
28 #include "Spacing.h"
29 #include "vspace.h"
30
31 #include "support/lstrings.h"
32 #include "support/tostr.h"
33
34 #include "lyx_forms.h"
35
36 using lyx::support::contains_functor;
37 using lyx::support::getStringFromVector;
38 using lyx::support::rtrim;
39
40 using std::bind2nd;
41 using std::remove_if;
42
43 using std::vector;
44 using std::string;
45
46
47 namespace {
48
49 string defaultUnit("cm");
50
51 void validateVSpaceWidgets(FL_OBJECT * choice_type, FL_OBJECT * input_length)
52 {
53         // Paranoia check!
54         BOOST_ASSERT(choice_type  && choice_type->objclass  == FL_CHOICE &&
55                      input_length && input_length->objclass == FL_INPUT);
56
57         if (fl_get_choice(choice_type) != 6)
58                 return;
59
60         // If a vspace kind is "Length" but there's no text in
61         // the input field, insert nothing.
62         string const input = rtrim(getString(input_length));
63         if (input.empty())
64                 return;
65 }
66
67
68 VSpace const setVSpaceFromWidgets(FL_OBJECT * choice_type,
69                                   FL_OBJECT * input_length,
70                                   FL_OBJECT * choice_length,
71                                   bool keep)
72 {
73         // Paranoia check!
74         BOOST_ASSERT(choice_type   && choice_type->objclass   == FL_CHOICE &&
75                      input_length  && input_length->objclass  == FL_INPUT &&
76                      choice_length && choice_length->objclass == FL_CHOICE);
77
78         VSpace space = VSpace(VSpace::DEFSKIP);
79
80         switch (fl_get_choice(choice_type)) {
81         case 1:
82                 space = VSpace(VSpace::DEFSKIP);
83                 break;
84         case 2:
85                 space = VSpace(VSpace::SMALLSKIP);
86                 break;
87         case 3:
88                 space = VSpace(VSpace::MEDSKIP);
89                 break;
90         case 4:
91                 space = VSpace(VSpace::BIGSKIP);
92                 break;
93         case 5:
94                 space = VSpace(VSpace::VFILL);
95                 break;
96         case 6:
97                 space = VSpace(LyXGlueLength(
98                         getLengthFromWidgets(input_length, choice_length)));
99                 break;
100         }
101
102         space.setKeep(keep);
103         return space;
104 }
105
106
107 void setWidgetsFromVSpace(VSpace const & space,
108                           FL_OBJECT * choice_type,
109                           FL_OBJECT * input_length,
110                           FL_OBJECT * choice_length,
111                           FL_OBJECT * check_keep)
112 {
113         // Paranoia check!
114         BOOST_ASSERT(choice_type   && choice_type->objclass   == FL_CHOICE &&
115                      input_length  && input_length->objclass  == FL_INPUT &&
116                      choice_length && choice_length->objclass == FL_CHOICE &&
117                      check_keep    && check_keep->objclass   == FL_CHECKBUTTON);
118
119         int pos = 1;
120         switch (space.kind()) {
121         case VSpace::DEFSKIP:
122                 pos = 1;
123                 break;
124         case VSpace::SMALLSKIP:
125                 pos = 2;
126                 break;
127         case VSpace::MEDSKIP:
128                 pos = 3;
129                 break;
130         case VSpace::BIGSKIP:
131                 pos = 4;
132                 break;
133         case VSpace::VFILL:
134                 pos = 5;
135                 break;
136         case VSpace::LENGTH:
137                 pos = 6;
138                 break;
139         }
140         fl_set_choice(choice_type, pos);
141         fl_set_button(check_keep, space.keep());
142
143         bool const custom_vspace = space.kind() == VSpace::LENGTH;
144         if (custom_vspace) {
145                 string const length = space.length().asString();
146                 updateWidgetsFromLengthString(input_length, choice_length,
147                                               length, defaultUnit);
148         } else {
149                 fl_set_input(input_length, "");
150                 fl_set_choice_text(choice_length, defaultUnit.c_str());
151         }
152 }
153
154 } // namespace anon
155
156
157 typedef FormController<ControlVSpace, FormView<FD_vspace> > base_class;
158
159 FormVSpace::FormVSpace(Dialog & parent)
160         : base_class(parent, _("VSpace Settings"))
161 {}
162
163
164 void FormVSpace::build()
165 {
166         // the tabbed folder
167         dialog_.reset(build_vspace(this));
168
169         // Manage the ok, apply, restore and cancel/close buttons
170         bcview().setOK(dialog_->button_ok);
171         bcview().setApply(dialog_->button_apply);
172         bcview().setCancel(dialog_->button_close);
173         bcview().setRestore(dialog_->button_restore);
174
175         // disable for read-only documents
176         bcview().addReadOnly(dialog_->choice_space);
177         bcview().addReadOnly(dialog_->input_space);
178         bcview().addReadOnly(dialog_->choice_unit_space);
179
180         // check validity of "length + unit" input.
181         // If invalid, the label of input_space is displayed in red.
182         addCheckedGlueLength(bcview(),
183                              dialog_->input_space,
184                              dialog_->input_space);
185
186         // trigger an input event for cut&paste with middle mouse button.
187         setPrehandler(dialog_->input_space);
188
189         fl_set_input_return(dialog_->input_space, FL_RETURN_CHANGED);
190
191         string const spacing =
192                 _("DefSkip|SmallSkip|MedSkip|BigSkip|VFill|Length");
193         fl_addto_choice(dialog_->choice_space, spacing.c_str());
194
195         // Create the contents of the unit choices; don't include the "%" terms.
196         vector<string> units_vec = getLatexUnits();
197         vector<string>::iterator del =
198                 remove_if(units_vec.begin(), units_vec.end(),
199                           bind2nd(contains_functor(), "%"));
200         units_vec.erase(del, units_vec.end());
201
202         string const units = getStringFromVector(units_vec, "|");
203         fl_addto_choice(dialog_->choice_unit_space, units.c_str());
204
205         // set up the tooltips
206         string str = _("Additional vertical space.");
207         tooltips().init(dialog_->choice_space, str);
208
209         // set default unit for custom length
210         switch (lyxrc.default_papersize) {
211         case PAPER_DEFAULT:
212         case PAPER_USLETTER:
213         case PAPER_LEGALPAPER:
214         case PAPER_EXECUTIVEPAPER:
215                 defaultUnit = "in";
216                 break;
217         case PAPER_A3PAPER:
218         case PAPER_A4PAPER:
219         case PAPER_A5PAPER:
220         case PAPER_B5PAPER:
221                 defaultUnit = "cm";
222                 break;
223         }
224 }
225
226
227 void FormVSpace::apply()
228 {
229         if (!form())
230                 return;
231
232         // spacing
233         // If a vspace choice is "Length" but there's no text in
234         // the input field, insert nothing.
235         validateVSpaceWidgets(dialog_->choice_space, dialog_->input_space);
236
237         VSpace const space =
238                 setVSpaceFromWidgets(dialog_->choice_space,
239                                      dialog_->input_space,
240                                      dialog_->choice_unit_space,
241                                      fl_get_button(dialog_->check_keep));
242
243         controller().params() = space;
244 }
245
246
247 void FormVSpace::update()
248 {
249         setWidgetsFromVSpace(controller().params(),
250                              dialog_->choice_space,
251                              dialog_->input_space,
252                              dialog_->choice_unit_space,
253                              dialog_->check_keep);
254
255         bool const custom_length =
256                 fl_get_choice(dialog_->choice_space) == 6;
257         setEnabled(dialog_->input_space, custom_length);
258         setEnabled(dialog_->choice_unit_space, custom_length);
259 }
260
261
262 ButtonPolicy::SMInput FormVSpace::input(FL_OBJECT * ob, long)
263 {
264         // Enable input when custum length is choosen,
265         // disable 'keep' when no space is choosen
266         if (ob == dialog_->choice_space) {
267                 bool const custom_length =
268                         fl_get_choice(dialog_->choice_space) == 6;
269                 setEnabled(dialog_->input_space, custom_length);
270                 setEnabled(dialog_->choice_unit_space, custom_length);
271         }
272         return ButtonPolicy::SMI_VALID;
273 }