]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBox.C
Use boost::scoped_array to store the temporary wchar_t pointer/array
[lyx.git] / src / frontends / xforms / FormBox.C
1 /**
2  * \file FormBox.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 (Minipage stuff)
7  * \author Martin Vermeer
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "FormBox.h"
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"
21
22 #include "Tooltips.h"
23 #include "xforms_helpers.h"
24 #include "xformsBC.h"
25
26 #include "insets/insetbox.h"
27
28 #include "lyx_forms.h"
29 #include "debug.h"
30
31 #include <vector>
32
33 using std::string;
34
35 namespace lyx {
36
37 using support::getStringFromVector;
38 using support::isStrDbl;
39 using support::subst;
40
41 namespace frontend {
42
43
44 typedef FormController<ControlBox, FormView<FD_box> > base_class;
45
46 FormBox::FormBox(Dialog & parent)
47         : base_class(parent, _("Box"))
48 {}
49
50
51 void FormBox::build()
52 {
53         dialog_.reset(build_box(this));
54
55         box_gui_tokens(ids_, gui_names_);
56
57         for (unsigned int i = 0; i < gui_names_.size(); ++i) {
58                 fl_addto_choice(dialog_->choice_type, gui_names_[i].c_str());
59         }
60
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);
68
69         bcview().addReadOnly(dialog_->check_inner_box);
70
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);
74
75         bcview().addReadOnly(dialog_->radio_parbox);
76         bcview().addReadOnly(dialog_->radio_minipage);
77
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());
82
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());
88
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());
94
95         bcview().addReadOnly(dialog_->input_width);
96         bcview().addReadOnly(dialog_->choice_width_unit);
97         bcview().addReadOnly(dialog_->choice_special);
98
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());
102         }
103
104         string choice = getStringFromVector(getLatexUnits(), "|");
105         fl_addto_choice(dialog_->choice_width_unit,
106                 subst(choice, "%", "%%").c_str());
107
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());
114         }
115
116         choice = getStringFromVector(getLatexUnits(), "|");
117         fl_addto_choice(dialog_->choice_height_unit,
118                 subst(choice, "%", "%%").c_str());
119
120         bcview().setOK(dialog_->button_ok);
121         bcview().setApply(dialog_->button_apply);
122         bcview().setCancel(dialog_->button_cancel);
123 }
124
125
126 void FormBox::update()
127 {
128         string type(controller().params().type);
129         for (unsigned int i = 0; i < gui_names_.size(); ++i) {
130                 if (type == ids_[i])
131                         fl_set_choice_text(dialog_->choice_type, gui_names_[i].c_str());
132                 }
133
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);
137
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);
147
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);
152
153         LyXLength len(controller().params().width);
154         fl_set_input(dialog_->input_width, tostr(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());
161                 }
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);
166
167         LyXLength ht(controller().params().height);
168         fl_set_input(dialog_->input_height, tostr(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());
175                 }
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);
179         // Same here
180         if (height_special != "none")
181                 setEnabled(dialog_->choice_height_unit, false);
182 }
183
184
185 void FormBox::apply()
186 {
187         int i = fl_get_choice(dialog_->choice_type);
188         controller().params().type = ids_[i - 1];
189
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));
196
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];
203
204         i = fl_get_choice(dialog_->choice_special);
205         controller().params().special = ids_spec_[i - 1];
206
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];
212 }
213
214 ButtonPolicy::SMInput FormBox::input(FL_OBJECT * ob, long)
215 {
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));
236
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);
240                 else
241                         fl_set_choice(dialog_->choice_height_special, NONE);
242         }
243
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);
250                 else
251                     setEnabled(dialog_->choice_height_unit,
252                                 fl_get_button(dialog_->check_inner_box));
253
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);
260                 } else {
261                         setEnabled(dialog_->check_inner_box, true);
262                 }
263         }
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);
268                 if (invalid) {
269                         postWarning(_("Invalid length!"));
270                         return ButtonPolicy::SMI_INVALID;
271                 }
272         }
273         if (ob == dialog_->input_height) {
274                 string const input = getString(dialog_->input_height);
275                 bool const invalid = !isValidLength(input) && !isStrDbl(input);
276                 if (invalid) {
277                         postWarning(_("Invalid length!"));
278                         return ButtonPolicy::SMI_INVALID;
279                 }
280         }
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);
289         }
290
291         return ButtonPolicy::SMI_VALID;
292 }
293
294 } // namespace frontend
295 } // namespace lyx