3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Jürgen Vigna (Minipage stuff)
7 * \author Martin Vermeer
9 * Full author contact details are available in file CREDITS.
15 #include "ControlBox.h"
16 #include "forms/form_box.h"
17 #include "controllers/ButtonPolicies.h"
18 #include "controllers/helper_funcs.h"
19 #include "support/lstrings.h"
20 #include "support/tostr.h"
23 #include "xforms_helpers.h"
26 #include "insets/insetbox.h"
28 #include "lyx_forms.h"
37 using support::getStringFromVector;
38 using support::isStrDbl;
44 typedef FormController<ControlBox, FormView<FD_box> > base_class;
46 FormBox::FormBox(Dialog & parent)
47 : base_class(parent, _("Box"))
53 dialog_.reset(build_box(this));
55 box_gui_tokens(ids_, gui_names_);
57 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
58 fl_addto_choice(dialog_->choice_type, gui_names_[i].c_str());
61 string str = _("Frameless: No border\n"
62 "Boxed: Rectangular\n"
63 "ovalbox: Oval, thin border\n"
64 "Ovalbox: Oval, thick border\n"
65 "Shadowbox: Box casting shadow\n"
66 "Doublebox: Double line border");
67 tooltips().init(dialog_->choice_type, str);
69 bcview().addReadOnly(dialog_->check_inner_box);
71 str = _("The inner box may be a parbox or a minipage,\n"
72 "with appropriate arguments from this dialog.");
73 tooltips().init(dialog_->check_inner_box, str);
75 bcview().addReadOnly(dialog_->radio_parbox);
76 bcview().addReadOnly(dialog_->radio_minipage);
78 bcview().addReadOnly(dialog_->choice_pos);
79 fl_addto_choice(dialog_->choice_pos, _("Top").c_str());
80 fl_addto_choice(dialog_->choice_pos, _("Middle").c_str());
81 fl_addto_choice(dialog_->choice_pos, _("Bottom").c_str());
83 bcview().addReadOnly(dialog_->choice_inner_pos);
84 fl_addto_choice(dialog_->choice_inner_pos, _("Top").c_str());
85 fl_addto_choice(dialog_->choice_inner_pos, _("Middle").c_str());
86 fl_addto_choice(dialog_->choice_inner_pos, _("Bottom").c_str());
87 fl_addto_choice(dialog_->choice_inner_pos, _("Stretch").c_str());
89 bcview().addReadOnly(dialog_->choice_hor_pos);
90 fl_addto_choice(dialog_->choice_hor_pos, _("Left").c_str());
91 fl_addto_choice(dialog_->choice_hor_pos, _("Center").c_str());
92 fl_addto_choice(dialog_->choice_hor_pos, _("Right").c_str());
93 fl_addto_choice(dialog_->choice_hor_pos, _("Stretch").c_str());
95 bcview().addReadOnly(dialog_->input_width);
96 bcview().addReadOnly(dialog_->choice_width_unit);
97 bcview().addReadOnly(dialog_->choice_special);
99 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
100 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
101 fl_addto_choice(dialog_->choice_special, gui_names_spec_[i].c_str());
104 string choice = getStringFromVector(getLatexUnits(), "|");
105 fl_addto_choice(dialog_->choice_width_unit,
106 subst(choice, "%", "%%").c_str());
108 bcview().addReadOnly(dialog_->input_height);
109 bcview().addReadOnly(dialog_->choice_height_unit);
110 bcview().addReadOnly(dialog_->choice_height_special);
111 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
112 fl_addto_choice(dialog_->choice_height_special,
113 gui_names_spec_[i].c_str());
116 choice = getStringFromVector(getLatexUnits(), "|");
117 fl_addto_choice(dialog_->choice_height_unit,
118 subst(choice, "%", "%%").c_str());
120 bcview().setOK(dialog_->button_ok);
121 bcview().setApply(dialog_->button_apply);
122 bcview().setCancel(dialog_->button_cancel);
126 void FormBox::update()
128 string type(controller().params().type);
129 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
131 fl_set_choice_text(dialog_->choice_type, gui_names_[i].c_str());
134 fl_set_button(dialog_->check_inner_box, controller().params().inner_box);
135 if (controller().params().type == "Frameless")
136 setEnabled(dialog_->check_inner_box, false);
138 char c = controller().params().pos;
139 fl_set_choice(dialog_->choice_pos, string("tcb").find(c, 0) + 1);
140 c = controller().params().inner_pos;
141 fl_set_choice(dialog_->choice_inner_pos, string("tcbs").find(c, 0) + 1);
142 c = controller().params().hor_pos;
143 fl_set_choice(dialog_->choice_hor_pos, string("lcrs").find(c, 0) + 1);
144 setEnabled(dialog_->choice_pos, controller().params().inner_box);
145 setEnabled(dialog_->choice_inner_pos, controller().params().inner_box);
146 setEnabled(dialog_->choice_hor_pos, !controller().params().inner_box);
148 fl_set_button(dialog_->radio_parbox, controller().params().use_parbox);
149 fl_set_button(dialog_->radio_minipage, !controller().params().use_parbox);
150 setEnabled(dialog_->radio_parbox, controller().params().inner_box);
151 setEnabled(dialog_->radio_minipage, controller().params().inner_box);
153 LyXLength len(controller().params().width);
154 fl_set_input(dialog_->input_width, convert<string>(len.value()).c_str());
155 fl_set_choice(dialog_->choice_width_unit, len.unit() + 1);
156 string special(controller().params().special);
157 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
158 if (special == ids_spec_[i])
159 fl_set_choice_text(dialog_->choice_special,
160 gui_names_spec_[i].c_str());
162 // Special width unit must be default for general units to be enabled
163 if (controller().params().special != "none")
164 setEnabled(dialog_->choice_width_unit, false);
165 setEnabled(dialog_->choice_special, !controller().params().inner_box);
167 LyXLength ht(controller().params().height);
168 fl_set_input(dialog_->input_height, convert<string>(ht.value()).c_str());
169 fl_set_choice(dialog_->choice_height_unit, ht.unit() + 1);
170 string const height_special(controller().params().height_special);
171 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
172 if (height_special == ids_spec_[i])
173 fl_set_choice_text(dialog_->choice_height_special,
174 gui_names_spec_[i].c_str());
176 setEnabled(dialog_->input_height, controller().params().inner_box);
177 setEnabled(dialog_->choice_height_unit, controller().params().inner_box);
178 setEnabled(dialog_->choice_height_special, controller().params().inner_box);
180 if (height_special != "none")
181 setEnabled(dialog_->choice_height_unit, false);
185 void FormBox::apply()
187 int i = fl_get_choice(dialog_->choice_type);
188 controller().params().type = ids_[i - 1];
190 controller().params().inner_box = fl_get_button(dialog_->check_inner_box);
191 controller().params().use_parbox =
192 fl_get_button(dialog_->radio_parbox);
193 controller().params().width =
194 LyXLength(getLengthFromWidgets(dialog_->input_width,
195 dialog_->choice_width_unit));
197 controller().params().pos =
198 "tcb"[fl_get_choice(dialog_->choice_pos) - 1];
199 controller().params().inner_pos =
200 "tcbs"[fl_get_choice(dialog_->choice_inner_pos) - 1];
201 controller().params().hor_pos =
202 "lcrs"[fl_get_choice(dialog_->choice_hor_pos) - 1];
204 i = fl_get_choice(dialog_->choice_special);
205 controller().params().special = ids_spec_[i - 1];
207 controller().params().height =
208 LyXLength(getLengthFromWidgets(dialog_->input_height,
209 dialog_->choice_height_unit));
210 i = fl_get_choice(dialog_->choice_height_special);
211 controller().params().height_special = ids_spec_[i - 1];
214 ButtonPolicy::SMInput FormBox::input(FL_OBJECT * ob, long)
216 if (ob == dialog_->check_inner_box) {
217 setEnabled(dialog_->choice_pos,
218 fl_get_button(dialog_->check_inner_box));
219 setEnabled(dialog_->radio_parbox,
220 fl_get_button(dialog_->check_inner_box));
221 setEnabled(dialog_->radio_minipage,
222 fl_get_button(dialog_->check_inner_box));
223 setEnabled(dialog_->choice_width_unit, true);
224 setEnabled(dialog_->choice_special,
225 !fl_get_button(dialog_->check_inner_box));
226 setEnabled(dialog_->input_height,
227 fl_get_button(dialog_->check_inner_box));
228 setEnabled(dialog_->choice_height_unit,
229 fl_get_button(dialog_->check_inner_box));
230 setEnabled(dialog_->choice_height_special,
231 fl_get_button(dialog_->check_inner_box));
232 setEnabled(dialog_->choice_hor_pos,
233 !fl_get_button(dialog_->check_inner_box));
234 setEnabled(dialog_->choice_inner_pos,
235 fl_get_button(dialog_->check_inner_box));
237 // Reset to defaults to not confuse users:
238 if (fl_get_button(dialog_->check_inner_box))
239 fl_set_choice(dialog_->choice_special, NONE);
241 fl_set_choice(dialog_->choice_height_special, NONE);
244 if (ob == dialog_->choice_special || ob == dialog_->check_inner_box)
245 setEnabled(dialog_->choice_width_unit,
246 fl_get_choice(dialog_->choice_special) == NONE);
247 if (ob == dialog_->choice_height_special || ob == dialog_->check_inner_box)
248 if (fl_get_choice(dialog_->choice_height_special) != NONE)
249 setEnabled(dialog_->choice_height_unit, false);
251 setEnabled(dialog_->choice_height_unit,
252 fl_get_button(dialog_->check_inner_box));
254 // An inner box (parbox, minipage) is mandatory if no outer box
255 if (ob == dialog_->choice_type) {
256 int i = fl_get_choice(dialog_->choice_type);
257 if (ids_[i - 1] == "Frameless") {
258 setEnabled(dialog_->check_inner_box, false);
259 fl_set_button(dialog_->check_inner_box, true);
261 setEnabled(dialog_->check_inner_box, true);
264 // disallow senseless data, warnings if input is senseless
265 if (ob == dialog_->input_width) {
266 string const input = getString(dialog_->input_width);
267 bool const invalid = !isValidLength(input) && !isStrDbl(input);
269 postWarning(_("Invalid length!"));
270 return ButtonPolicy::SMI_INVALID;
273 if (ob == dialog_->input_height) {
274 string const input = getString(dialog_->input_height);
275 bool const invalid = !isValidLength(input) && !isStrDbl(input);
277 postWarning(_("Invalid length!"));
278 return ButtonPolicy::SMI_INVALID;
281 if (ob == dialog_->button_defaults) {
282 fl_set_button(dialog_->check_inner_box, true);
283 fl_set_button(dialog_->radio_parbox, false);
284 fl_set_input(dialog_->input_width, "100");
285 fl_set_choice(dialog_->choice_width_unit, LyXLength::PCW + 1);
286 fl_set_choice(dialog_->choice_special, NONE);
287 fl_set_input(dialog_->input_height, "1");
288 fl_set_choice(dialog_->choice_height_special, TOTALHEIGHT);
291 return ButtonPolicy::SMI_VALID;
294 } // namespace frontend