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"
33 using lyx::support::getStringFromVector;
34 using lyx::support::isStrDbl;
35 using lyx::support::subst;
39 typedef FormController<ControlBox, FormView<FD_box> > base_class;
41 FormBox::FormBox(Dialog & parent)
42 : base_class(parent, _("Box"))
48 dialog_.reset(build_box(this));
50 box_gui_tokens(ids_, gui_names_);
52 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
53 fl_addto_choice(dialog_->choice_type, gui_names_[i].c_str());
56 string str = _("Frameless: No border\n"
57 "Boxed: Rectangular\n"
58 "ovalbox: Oval, thin border\n"
59 "Ovalbox: Oval, thick border\n"
60 "Shadowbox: Box casting shadow\n"
61 "Doublebox: Double line border");
62 tooltips().init(dialog_->choice_type, str);
64 bcview().addReadOnly(dialog_->check_inner_box);
66 str = _("The inner box may be a parbox or a minipage,\n"
67 "with appropriate arguments from this dialog.");
68 tooltips().init(dialog_->check_inner_box, str);
70 bcview().addReadOnly(dialog_->radio_parbox);
71 bcview().addReadOnly(dialog_->radio_minipage);
73 bcview().addReadOnly(dialog_->choice_pos);
74 fl_addto_choice(dialog_->choice_pos, _("top").c_str());
75 fl_addto_choice(dialog_->choice_pos, _("middle").c_str());
76 fl_addto_choice(dialog_->choice_pos, _("bottom").c_str());
78 bcview().addReadOnly(dialog_->choice_inner_pos);
79 fl_addto_choice(dialog_->choice_inner_pos, _("top").c_str());
80 fl_addto_choice(dialog_->choice_inner_pos, _("middle").c_str());
81 fl_addto_choice(dialog_->choice_inner_pos, _("bottom").c_str());
82 fl_addto_choice(dialog_->choice_inner_pos, _("stretch").c_str());
84 bcview().addReadOnly(dialog_->choice_hor_pos);
85 fl_addto_choice(dialog_->choice_hor_pos, _("left").c_str());
86 fl_addto_choice(dialog_->choice_hor_pos, _("center").c_str());
87 fl_addto_choice(dialog_->choice_hor_pos, _("right").c_str());
88 fl_addto_choice(dialog_->choice_hor_pos, _("stretch").c_str());
90 bcview().addReadOnly(dialog_->input_width);
91 bcview().addReadOnly(dialog_->choice_width_unit);
92 bcview().addReadOnly(dialog_->choice_special);
94 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
95 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
96 fl_addto_choice(dialog_->choice_special, gui_names_spec_[i].c_str());
99 string choice = getStringFromVector(getLatexUnits(), "|");
100 fl_addto_choice(dialog_->choice_width_unit,
101 subst(choice, "%", "%%").c_str());
103 bcview().addReadOnly(dialog_->input_height);
104 bcview().addReadOnly(dialog_->choice_height_unit);
105 bcview().addReadOnly(dialog_->choice_height_special);
106 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
107 fl_addto_choice(dialog_->choice_height_special,
108 gui_names_spec_[i].c_str());
111 choice = getStringFromVector(getLatexUnits(), "|");
112 fl_addto_choice(dialog_->choice_height_unit,
113 subst(choice, "%", "%%").c_str());
115 bcview().setOK(dialog_->button_ok);
116 bcview().setApply(dialog_->button_apply);
117 bcview().setCancel(dialog_->button_cancel);
121 void FormBox::update()
123 string type(controller().params().type);
124 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
126 fl_set_choice_text(dialog_->choice_type, gui_names_[i].c_str());
129 fl_set_button(dialog_->check_inner_box, controller().params().inner_box);
130 if (controller().params().type == "Frameless")
131 setEnabled(dialog_->check_inner_box, false);
133 char c = controller().params().pos;
134 fl_set_choice(dialog_->choice_pos, string("tcb").find(c, 0) + 1);
135 c = controller().params().inner_pos;
136 fl_set_choice(dialog_->choice_inner_pos, string("tcbs").find(c, 0) + 1);
137 c = controller().params().hor_pos;
138 fl_set_choice(dialog_->choice_hor_pos, string("lcrs").find(c, 0) + 1);
139 setEnabled(dialog_->choice_pos, controller().params().inner_box);
140 setEnabled(dialog_->choice_inner_pos, controller().params().inner_box);
141 setEnabled(dialog_->choice_hor_pos, !controller().params().inner_box);
143 fl_set_button(dialog_->radio_parbox, controller().params().use_parbox);
144 fl_set_button(dialog_->radio_minipage, !controller().params().use_parbox);
145 setEnabled(dialog_->radio_parbox, controller().params().inner_box);
146 setEnabled(dialog_->radio_minipage, controller().params().inner_box);
148 LyXLength len(controller().params().width);
149 fl_set_input(dialog_->input_width, tostr(len.value()).c_str());
150 fl_set_choice(dialog_->choice_width_unit, len.unit() + 1);
151 string special(controller().params().special);
152 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
153 if (special == ids_spec_[i])
154 fl_set_choice_text(dialog_->choice_special,
155 gui_names_spec_[i].c_str());
157 // Special width unit must be default for general units to be enabled
158 if(controller().params().special != "none")
159 setEnabled(dialog_->choice_width_unit, false);
160 setEnabled(dialog_->choice_special, !controller().params().inner_box);
162 LyXLength ht(controller().params().height);
163 fl_set_input(dialog_->input_height, tostr(ht.value()).c_str());
164 fl_set_choice(dialog_->choice_height_unit, ht.unit() + 1);
165 string const height_special(controller().params().height_special);
166 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
167 if (height_special == ids_spec_[i])
168 fl_set_choice_text(dialog_->choice_height_special,
169 gui_names_spec_[i].c_str());
171 setEnabled(dialog_->input_height, controller().params().inner_box);
172 setEnabled(dialog_->choice_height_unit, controller().params().inner_box);
173 setEnabled(dialog_->choice_height_special, controller().params().inner_box);
175 if(height_special != "none")
176 setEnabled(dialog_->choice_height_unit, false);
180 void FormBox::apply()
182 int i = fl_get_choice(dialog_->choice_type);
183 controller().params().type = ids_[i - 1];
185 controller().params().inner_box = fl_get_button(dialog_->check_inner_box);
186 controller().params().use_parbox =
187 fl_get_button(dialog_->radio_parbox);
188 controller().params().width =
189 LyXLength(getLengthFromWidgets(dialog_->input_width,
190 dialog_->choice_width_unit));
192 controller().params().pos =
193 "tcb"[fl_get_choice(dialog_->choice_pos) - 1];
194 controller().params().inner_pos =
195 "tcbs"[fl_get_choice(dialog_->choice_inner_pos) - 1];
196 controller().params().hor_pos =
197 "lcrs"[fl_get_choice(dialog_->choice_hor_pos) - 1];
199 i = fl_get_choice(dialog_->choice_special);
200 controller().params().special = ids_spec_[i - 1];
202 controller().params().height =
203 LyXLength(getLengthFromWidgets(dialog_->input_height,
204 dialog_->choice_height_unit));
205 i = fl_get_choice(dialog_->choice_height_special);
206 controller().params().height_special = ids_spec_[i - 1];
209 ButtonPolicy::SMInput FormBox::input(FL_OBJECT * ob, long)
211 if (ob == dialog_->check_inner_box) {
212 setEnabled(dialog_->choice_pos,
213 fl_get_button(dialog_->check_inner_box));
214 setEnabled(dialog_->radio_parbox,
215 fl_get_button(dialog_->check_inner_box));
216 setEnabled(dialog_->radio_minipage,
217 fl_get_button(dialog_->check_inner_box));
218 setEnabled(dialog_->choice_width_unit, true);
219 setEnabled(dialog_->choice_special,
220 !fl_get_button(dialog_->check_inner_box));
221 setEnabled(dialog_->input_height,
222 fl_get_button(dialog_->check_inner_box));
223 setEnabled(dialog_->choice_height_unit,
224 fl_get_button(dialog_->check_inner_box));
225 setEnabled(dialog_->choice_height_special,
226 fl_get_button(dialog_->check_inner_box));
227 setEnabled(dialog_->choice_hor_pos,
228 !fl_get_button(dialog_->check_inner_box));
229 setEnabled(dialog_->choice_inner_pos,
230 fl_get_button(dialog_->check_inner_box));
232 // Reset to defaults to not confuse users:
233 if (fl_get_button(dialog_->check_inner_box))
234 fl_set_choice(dialog_->choice_special, NONE);
236 fl_set_choice(dialog_->choice_height_special, NONE);
239 if (ob == dialog_->choice_special || ob == dialog_->check_inner_box)
240 setEnabled(dialog_->choice_width_unit,
241 fl_get_choice(dialog_->choice_special) == NONE);
242 if (ob == dialog_->choice_height_special || ob == dialog_->check_inner_box)
243 if (fl_get_choice(dialog_->choice_height_special) != NONE)
244 setEnabled(dialog_->choice_height_unit, false);
246 setEnabled(dialog_->choice_height_unit,
247 fl_get_button(dialog_->check_inner_box));
249 // An inner box (parbox, minipage) is mandatory if no outer box
250 if (ob == dialog_->choice_type) {
251 int i = fl_get_choice(dialog_->choice_type);
252 if (ids_[i - 1] == "Frameless") {
253 setEnabled(dialog_->check_inner_box, false);
254 fl_set_button(dialog_->check_inner_box, true);
256 setEnabled(dialog_->check_inner_box, true);
259 // disallow senseless data, warnings if input is senseless
260 if (ob == dialog_->input_width) {
261 string const input = getString(dialog_->input_width);
262 bool const invalid = !isValidLength(input) && !isStrDbl(input);
264 postWarning(_("Invalid Length!"));
265 return ButtonPolicy::SMI_INVALID;
268 if (ob == dialog_->input_height) {
269 string const input = getString(dialog_->input_height);
270 bool const invalid = !isValidLength(input) && !isStrDbl(input);
272 postWarning(_("Invalid Length!"));
273 return ButtonPolicy::SMI_INVALID;
276 if (ob == dialog_->button_defaults) {
277 fl_set_button(dialog_->check_inner_box, true);
278 fl_set_button(dialog_->radio_parbox, false);
279 fl_set_input(dialog_->input_width, "100");
280 fl_set_choice(dialog_->choice_width_unit, LyXLength::PCW + 1);
281 fl_set_choice(dialog_->choice_special, NONE);
282 fl_set_input(dialog_->input_height, "1");
283 fl_set_choice(dialog_->choice_height_special, TOTALHEIGHT);
286 return ButtonPolicy::SMI_VALID;