]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormVSpace.C
move space above/below from Paragraph into a separate vspace inset.
[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) != 7)
58                 return;
59
60         // If a vspace kind is "Length" but there's no text in
61         // the input field, reset the kind to "None".
62         string const input = rtrim(getString(input_length));
63         if (input.empty())
64                 fl_set_choice(choice_type, 1);
65 }
66
67
68 VSpace const setVSpaceFromWidgets(FL_OBJECT * choice_type,
69                                   FL_OBJECT * input_length,
70                                   FL_OBJECT * choice_length)
71 {
72         // Paranoia check!
73         BOOST_ASSERT(choice_type   && choice_type->objclass   == FL_CHOICE &&
74                      input_length  && input_length->objclass  == FL_INPUT &&
75                      choice_length && choice_length->objclass == FL_CHOICE);
76
77         switch (fl_get_choice(choice_type)) {
78         case 1:
79                 return VSpace(VSpace::NONE);
80         case 2:
81                 return VSpace(VSpace::DEFSKIP);
82         case 3:
83                 return VSpace(VSpace::SMALLSKIP);
84         case 4:
85                 return VSpace(VSpace::MEDSKIP);
86         case 5:
87                 return VSpace(VSpace::BIGSKIP);
88         case 6:
89                 return VSpace(VSpace::VFILL);
90         case 7:
91                 return VSpace(LyXGlueLength(
92                                       getLengthFromWidgets(input_length, choice_length)));
93         }
94
95         return VSpace(VSpace::NONE);
96 }
97
98
99 void setWidgetsFromVSpace(VSpace const & space,
100                           FL_OBJECT * choice_type,
101                           FL_OBJECT * input_length,
102                           FL_OBJECT * choice_length)
103 {
104         // Paranoia check!
105         BOOST_ASSERT(choice_type   && choice_type->objclass   == FL_CHOICE &&
106                      input_length  && input_length->objclass  == FL_INPUT &&
107                      choice_length && choice_length->objclass == FL_CHOICE);
108
109         int pos = 1;
110         switch (space.kind()) {
111         case VSpace::NONE:
112                 pos = 1;
113                 break;
114         case VSpace::DEFSKIP:
115                 pos = 2;
116                 break;
117         case VSpace::SMALLSKIP:
118                 pos = 3;
119                 break;
120         case VSpace::MEDSKIP:
121                 pos = 4;
122                 break;
123         case VSpace::BIGSKIP:
124                 pos = 5;
125                 break;
126         case VSpace::VFILL:
127                 pos = 6;
128                 break;
129         case VSpace::LENGTH:
130                 pos = 7;
131                 break;
132         }
133         fl_set_choice(choice_type, pos);
134
135         bool const custom_vspace = space.kind() == VSpace::LENGTH;
136         if (custom_vspace) {
137                 string const length = space.length().asString();
138                 updateWidgetsFromLengthString(input_length, choice_length,
139                                               length, defaultUnit);
140         } else {
141                 fl_set_input(input_length, "");
142                 fl_set_choice_text(choice_length, defaultUnit.c_str());
143         }
144 }
145
146 } // namespace anon
147
148
149 typedef FormController<ControlVSpace, FormView<FD_vspace> > base_class;
150
151 FormVSpace::FormVSpace(Dialog & parent)
152         : base_class(parent, _("VSpace Settings"))
153 {}
154
155
156 void FormVSpace::build()
157 {
158         // the tabbed folder
159         dialog_.reset(build_vspace(this));
160
161         // Manage the ok, apply, restore and cancel/close buttons
162         bcview().setOK(dialog_->button_ok);
163         bcview().setApply(dialog_->button_apply);
164         bcview().setCancel(dialog_->button_close);
165         bcview().setRestore(dialog_->button_restore);
166
167         // disable for read-only documents
168         bcview().addReadOnly(dialog_->choice_space);
169         bcview().addReadOnly(dialog_->input_space);
170
171         // check validity of "length + unit" input
172         addCheckedGlueLength(bcview(),
173                              dialog_->input_space,
174                              dialog_->choice_space);
175
176         // trigger an input event for cut&paste with middle mouse button.
177         setPrehandler(dialog_->input_space);
178
179         fl_set_input_return(dialog_->input_space, FL_RETURN_CHANGED);
180
181         // Create the contents of the unit choices; don't include the "%" terms.
182         vector<string> units_vec = getLatexUnits();
183         vector<string>::iterator del =
184                 remove_if(units_vec.begin(), units_vec.end(),
185                           bind2nd(contains_functor(), "%"));
186         units_vec.erase(del, units_vec.end());
187
188         string const units = getStringFromVector(units_vec, "|");
189         fl_addto_choice(dialog_->choice_unit_space, units.c_str());
190
191         // set up the tooltips
192         string str = _("Additional vertical space.");
193         tooltips().init(dialog_->choice_space, str);
194
195         // set default unit for custom length
196         switch (lyxrc.default_papersize) {
197         case PAPER_DEFAULT:
198         case PAPER_USLETTER:
199         case PAPER_LEGALPAPER:
200         case PAPER_EXECUTIVEPAPER:
201                 defaultUnit = "in";
202                 break;
203         case PAPER_A3PAPER:
204         case PAPER_A4PAPER:
205         case PAPER_A5PAPER:
206         case PAPER_B5PAPER:
207                 defaultUnit = "cm";
208                 break;
209         }
210 }
211
212
213 void FormVSpace::apply()
214 {
215         if (!form())
216                 return;
217
218         // spacing
219         // If a vspace choice is "Length" but there's no text in
220         // the input field, reset the choice to "None".
221         validateVSpaceWidgets(dialog_->choice_space, dialog_->input_space);
222
223         VSpace const space =
224                 setVSpaceFromWidgets(dialog_->choice_space,
225                                      dialog_->input_space,
226                                      dialog_->choice_unit_space);
227
228         controller().params() = space;
229 }
230
231
232 void FormVSpace::update()
233 {
234         setWidgetsFromVSpace(controller().params(),
235                              dialog_->choice_space,
236                              dialog_->input_space,
237                              dialog_->choice_unit_space);
238
239 }
240
241
242 ButtonPolicy::SMInput FormVSpace::input(FL_OBJECT * ob, long)
243 {
244         // Enable input when custum length is choosen,
245         // disable 'keep' when no space is choosen
246         if (ob == dialog_->choice_space) {
247                 bool const custom_length =
248                         fl_get_choice(dialog_->choice_space) == 7;
249         }
250         return ButtonPolicy::SMI_VALID;
251 }