]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormFloat.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / xforms / FormFloat.C
1 /**
2  * \file FormFloat.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Jürgen Spitzmüller
8  * \author Rob Lahaye
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "FormFloat.h"
16 #include "ControlFloat.h"
17 #include "forms/form_float.h"
18
19 #include "Tooltips.h"
20 #include "xforms_helpers.h"
21 #include "xformsBC.h"
22
23 #include "insets/insetfloat.h"
24
25 #include "support/lstrings.h"
26
27 #include "lyx_forms.h"
28
29 using std::string;
30
31 namespace lyx {
32
33 using support::contains;
34
35 namespace frontend {
36
37 namespace {
38
39 enum {
40         DOCUMENT_DEFAULTS,
41         HERE_DEFINITELY,
42         ALTERNATIVES
43 };
44
45 } // namespace anon
46
47
48 typedef FormController<ControlFloat, FormView<FD_float> > base_class;
49
50 FormFloat::FormFloat(Dialog & parent)
51         : base_class(parent, _("Float Settings"))
52 {}
53
54
55 void FormFloat::build()
56 {
57         dialog_.reset(build_float(this));
58
59         // Manage the ok, apply and cancel/close buttons
60         bcview().setOK(dialog_->button_ok);
61         bcview().setApply(dialog_->button_apply);
62         bcview().setCancel(dialog_->button_close);
63         bcview().setRestore(dialog_->button_restore);
64
65         // disable for read-only documents
66         bcview().addReadOnly(dialog_->radio_default);
67         bcview().addReadOnly(dialog_->radio_here_definitely);
68         bcview().addReadOnly(dialog_->radio_alternatives);
69         bcview().addReadOnly(dialog_->check_top);
70         bcview().addReadOnly(dialog_->check_bottom);
71         bcview().addReadOnly(dialog_->check_page);
72         bcview().addReadOnly(dialog_->check_here);
73         bcview().addReadOnly(dialog_->check_force);
74         bcview().addReadOnly(dialog_->check_wide);
75         bcview().addReadOnly(dialog_->check_sideways);
76
77         placement_.init(dialog_->radio_default,         DOCUMENT_DEFAULTS);
78         placement_.init(dialog_->radio_here_definitely, HERE_DEFINITELY);
79         placement_.init(dialog_->radio_alternatives,    ALTERNATIVES);
80
81         // set up the tooltips
82         string str = _("Use the document's default settings.");
83         tooltips().init(dialog_->radio_default, str);
84         str = _("Enforce placement of float here.");
85         tooltips().init(dialog_->radio_here_definitely, str);
86         str = _("Alternative suggestions for placement of float.");
87         tooltips().init(dialog_->radio_alternatives, str);
88         str = _("Try top of page.");
89         tooltips().init(dialog_->check_top, str);
90         str = _("Try bottom of page.");
91         tooltips().init(dialog_->check_bottom, str);
92         str = _("Put float on a separate page of floats.");
93         tooltips().init(dialog_->check_page, str);
94         str = _("Try float here.");
95         tooltips().init(dialog_->check_here, str);
96         str = _("Ignore internal settings. This is the \"!\" in LaTeX.");
97         tooltips().init(dialog_->check_force, str);
98         str = _("Span float over the columns.");
99         tooltips().init(dialog_->check_wide, str);
100         str = _("Rotate the float sideways by 90 degs.");
101         tooltips().init(dialog_->check_sideways, str);
102 }
103
104
105 void FormFloat::apply()
106 {
107         bool const wide = fl_get_button(dialog_->check_wide);
108         bool const sideways = fl_get_button(dialog_->check_sideways);
109
110         string placement;
111         switch (placement_.get()) {
112         case ALTERNATIVES:
113                 if (fl_get_button(dialog_->check_force)) {
114                         // Ignore internal LaTeX rules
115                         placement += '!';
116                 }
117                 if (fl_get_button(dialog_->check_top)) {
118                         // Top of page
119                         placement += 't';
120                 }
121                 if (fl_get_button(dialog_->check_bottom)) {
122                         // Bottom of page
123                         placement += 'b';
124                 }
125                 if (fl_get_button(dialog_->check_page)) {
126                         // Page of floats
127                         placement += 'p';
128                 }
129                 // ignore if wide is selected
130                 if (!wide && fl_get_button(dialog_->check_here)) {
131                         // Here, if possible
132                         placement += 'h';
133                 }
134                 if (placement == "!") {
135                         // ignore placement if only force is selected.
136                         placement.erase();
137                 }
138
139                 if (placement.length() == 0) {
140                         // none of Alternatives is selected; flip to default
141                         placement.erase();
142                         placement_.set(dialog_->radio_default);
143                         setEnabled(dialog_->check_force, false);
144                         setEnabled(dialog_->check_top, false);
145                         setEnabled(dialog_->check_bottom, false);
146                         setEnabled(dialog_->check_page, false);
147                         setEnabled(dialog_->check_here, false);
148                 }
149                 break;
150
151         case HERE_DEFINITELY:
152                 placement = "H";
153                 break;
154
155         case DOCUMENT_DEFAULTS:
156                 // default, do nothing.
157                 break;
158         }
159
160         controller().params().placement = placement;
161         controller().params().wide = wide;
162         controller().params().sideways = sideways;
163 }
164
165
166 void FormFloat::update()
167 {
168         string placement(controller().params().placement);
169         bool const wide = controller().params().wide;
170         bool const sideways = controller().params().sideways;
171         bool const sideways_possible = (controller().params().type == "figure"
172                 || controller().params().type == "table");
173
174         bool const here_definitely = contains(placement, 'H');
175
176         bool const top    = contains(placement, 't');
177         bool const bottom = contains(placement, 'b');
178         bool const page   = contains(placement, 'p');
179         bool const here   = contains(placement, 'h');
180         bool const force  = contains(placement, '!');
181         bool const alternatives = top || bottom || page || (here && !wide);
182
183         if (alternatives) {
184                 placement_.set(dialog_->radio_alternatives);
185         } else if (here_definitely) {
186                 placement_.set(dialog_->radio_here_definitely);
187         } else {
188                 placement_.set(dialog_->radio_default);
189         }
190         fl_set_button(dialog_->check_force, force);
191         fl_set_button(dialog_->check_top, top);
192         fl_set_button(dialog_->check_bottom, bottom);
193         fl_set_button(dialog_->check_page, page);
194         fl_set_button(dialog_->check_here, here);
195         fl_set_button(dialog_->check_wide, wide);
196         fl_set_button(dialog_->check_sideways, sideways);
197
198         setEnabled(dialog_->radio_here_definitely, !wide && !sideways);
199         setEnabled(dialog_->check_force,  alternatives && !sideways);
200         setEnabled(dialog_->check_top,    alternatives && !sideways);
201         setEnabled(dialog_->check_bottom, alternatives && !sideways);
202         setEnabled(dialog_->check_page,   alternatives && !sideways);
203         setEnabled(dialog_->check_here,   alternatives && !wide && !sideways);
204         setEnabled(dialog_->check_wide,   !sideways);
205         setEnabled(dialog_->radio_default,   !sideways);
206         setEnabled(dialog_->radio_alternatives,   !sideways);
207         setEnabled(dialog_->check_sideways, sideways_possible);
208 }
209
210
211 ButtonPolicy::SMInput FormFloat::input(FL_OBJECT * ob, long)
212 {
213         bool const alternatives = placement_.get() == ALTERNATIVES;
214         bool const wide = fl_get_button(dialog_->check_wide);
215         bool const sideways = fl_get_button(dialog_->check_sideways);
216
217         if (ob == dialog_->radio_default ||
218             ob == dialog_->radio_here_definitely ||
219             ob == dialog_->radio_alternatives) {
220                 // enable check buttons only for Alternatives
221                 setEnabled(dialog_->check_top, alternatives);
222                 setEnabled(dialog_->check_page, alternatives);
223                 // wide float doesn't allow 'here' or 'bottom' placement
224                 setEnabled(dialog_->check_here, alternatives && !wide);
225                 setEnabled(dialog_->check_bottom, alternatives && !wide);
226
227         } else if (ob == dialog_->check_wide) {
228                 if (wide && placement_.get() == HERE_DEFINITELY) {
229                         // wide float doesn't allow 'Here, definitely!'
230                         // placement
231                         placement_.set(dialog_->radio_default);
232                 }
233                 setEnabled(dialog_->check_here, alternatives && !wide);
234                 setEnabled(dialog_->radio_here_definitely, !wide);
235                 setEnabled(dialog_->check_bottom, alternatives && !wide);
236
237         } else if (ob == dialog_->check_sideways) {
238                 setEnabled(dialog_->radio_default,   !sideways);
239                 setEnabled(dialog_->radio_alternatives,   !sideways);
240                 setEnabled(dialog_->radio_here_definitely, !wide && !sideways);
241                 setEnabled(dialog_->check_top, alternatives && !sideways);
242                 setEnabled(dialog_->check_bottom,
243                         alternatives && !wide && !sideways);
244                 setEnabled(dialog_->check_page, alternatives && !sideways);
245                 setEnabled(dialog_->check_here, alternatives && !wide && !sideways);
246                 setEnabled(dialog_->check_wide,   !sideways);
247         }
248
249         // enable force button, if Alternatives is selected and at least
250         // one of its check buttons
251         bool const enable_force = alternatives && !sideways &&
252                 (fl_get_button(dialog_->check_top) ||
253                  fl_get_button(dialog_->check_bottom) ||
254                  fl_get_button(dialog_->check_page) ||
255                  (fl_get_button(dialog_->check_here) && !wide));
256         setEnabled(dialog_->check_force, enable_force);
257
258         return ButtonPolicy::SMI_VALID;
259 }
260
261 } // namespace frontend
262 } // namespace lyx