]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormFloat.C
If I ever see another licence blurb again, it'll be too soon...
[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
16 #include "xformsBC.h"
17 #include "ControlFloat.h"
18 #include "FormFloat.h"
19 #include "forms/form_float.h"
20 #include "Tooltips.h"
21 #include "xforms_helpers.h"
22 #include "insets/insetfloat.h"
23 #include "support/lstrings.h"
24 #include "lyx_forms.h"
25
26 using namespace lyx::support;
27
28 namespace {
29
30 enum {
31         DOCUMENT_DEFAULTS,
32         HERE_DEFINITELY,
33         ALTERNATIVES
34 };
35
36 } // namespace anon
37
38
39 typedef FormController<ControlFloat, FormView<FD_float> > base_class;
40
41 FormFloat::FormFloat(Dialog & parent)
42         : base_class(parent, _("Float Settings"))
43 {}
44
45
46 void FormFloat::build()
47 {
48         dialog_.reset(build_float(this));
49
50         // Manage the ok, apply and cancel/close buttons
51         bcview().setOK(dialog_->button_ok);
52         bcview().setApply(dialog_->button_apply);
53         bcview().setCancel(dialog_->button_close);
54         bcview().setRestore(dialog_->button_restore);
55
56         // disable for read-only documents
57         bcview().addReadOnly(dialog_->radio_default);
58         bcview().addReadOnly(dialog_->radio_here_definitely);
59         bcview().addReadOnly(dialog_->radio_alternatives);
60         bcview().addReadOnly(dialog_->check_top);
61         bcview().addReadOnly(dialog_->check_bottom);
62         bcview().addReadOnly(dialog_->check_page);
63         bcview().addReadOnly(dialog_->check_here);
64         bcview().addReadOnly(dialog_->check_force);
65         bcview().addReadOnly(dialog_->check_wide);
66
67         placement_.init(dialog_->radio_default,         DOCUMENT_DEFAULTS);
68         placement_.init(dialog_->radio_here_definitely, HERE_DEFINITELY);
69         placement_.init(dialog_->radio_alternatives,    ALTERNATIVES);
70
71         // set up the tooltips
72         string str = _("Use the document's default settings.");
73         tooltips().init(dialog_->radio_default, str);
74         str = _("Enforce placement of float here.");
75         tooltips().init(dialog_->radio_here_definitely, str);
76         str = _("Alternative suggestions for placement of float.");
77         tooltips().init(dialog_->radio_alternatives, str);
78         str = _("Try top of page.");
79         tooltips().init(dialog_->check_top, str);
80         str = _("Try bottom of page.");
81         tooltips().init(dialog_->check_bottom, str);
82         str = _("Put float on a separate page of floats.");
83         tooltips().init(dialog_->check_page, str);
84         str = _("Try float here.");
85         tooltips().init(dialog_->check_here, str);
86         str = _("Ignore internal settings. This is the \"!\" in LaTeX.");
87         tooltips().init(dialog_->check_force, str);
88         str = _("Span float over the columns.");
89         tooltips().init(dialog_->check_wide, str);
90 }
91
92
93 void FormFloat::apply()
94 {
95         bool const wide = fl_get_button(dialog_->check_wide);
96
97         string placement;
98         switch (placement_.get()) {
99         case ALTERNATIVES:
100                 if (fl_get_button(dialog_->check_force)) {
101                         // Ignore internal LaTeX rules
102                         placement += '!';
103                 }
104                 if (fl_get_button(dialog_->check_top)) {
105                         // Top of page
106                         placement += 't';
107                 }
108                 if (fl_get_button(dialog_->check_bottom)) {
109                         // Bottom of page
110                         placement += 'b';
111                 }
112                 if (fl_get_button(dialog_->check_page)) {
113                         // Page of floats
114                         placement += 'p';
115                 }
116                 // ignore if wide is selected
117                 if (!wide && fl_get_button(dialog_->check_here)) {
118                         // Here, if possible
119                         placement += 'h';
120                 }
121                 if (placement == "!") {
122                         // ignore placement if only force is selected.
123                         placement.erase();
124                 }
125
126                 if (placement.length() == 0) {
127                         // none of Alternatives is selected; flip to default
128                         placement.erase();
129                         placement_.set(dialog_->radio_default);
130                         setEnabled(dialog_->check_force, false);
131                         setEnabled(dialog_->check_top, false);
132                         setEnabled(dialog_->check_bottom, false);
133                         setEnabled(dialog_->check_page, false);
134                         setEnabled(dialog_->check_here, false);
135                 }
136                 break;
137
138         case HERE_DEFINITELY:
139                 placement = "H";
140                 break;
141
142         case DOCUMENT_DEFAULTS:
143                 // default, do nothing.
144                 break;
145         }
146
147         controller().params().placement = placement;
148         controller().params().wide = wide;
149 }
150
151
152 void FormFloat::update()
153 {
154         string placement(controller().params().placement);
155         bool const wide = controller().params().wide;
156
157         bool const here_definitely = contains(placement, "H");
158
159         bool const top    = contains(placement, "t");
160         bool const bottom = contains(placement, "b");
161         bool const page   = contains(placement, "p");
162         bool const here   = contains(placement, "h");
163         bool const force  = contains(placement, "!");
164         bool const alternatives = top || bottom || page || (here && !wide);
165
166         if (alternatives) {
167                 placement_.set(dialog_->radio_alternatives);
168         } else if (here_definitely) {
169                 placement_.set(dialog_->radio_here_definitely);
170         } else {
171                 placement_.set(dialog_->radio_default);
172         }
173         fl_set_button(dialog_->check_force, force);
174         fl_set_button(dialog_->check_top, top);
175         fl_set_button(dialog_->check_bottom, bottom);
176         fl_set_button(dialog_->check_page, page);
177         fl_set_button(dialog_->check_here, here);
178         fl_set_button(dialog_->check_wide, wide);
179
180         setEnabled(dialog_->radio_here_definitely, !wide);
181         setEnabled(dialog_->check_force,  alternatives);
182         setEnabled(dialog_->check_top,    alternatives);
183         setEnabled(dialog_->check_bottom, alternatives);
184         setEnabled(dialog_->check_page,   alternatives);
185         setEnabled(dialog_->check_here,   alternatives && !wide);
186 }
187
188
189 ButtonPolicy::SMInput FormFloat::input(FL_OBJECT * ob, long)
190 {
191         bool const alternatives = placement_.get() == ALTERNATIVES;
192         bool const wide = fl_get_button(dialog_->check_wide);
193
194         if (ob == dialog_->radio_default ||
195             ob == dialog_->radio_here_definitely ||
196             ob == dialog_->radio_alternatives) {
197                 // enable check buttons only for Alternatives
198                 setEnabled(dialog_->check_top, alternatives);
199                 setEnabled(dialog_->check_bottom, alternatives);
200                 setEnabled(dialog_->check_page, alternatives);
201                 // wide float doesn't allow 'here' placement
202                 setEnabled(dialog_->check_here, alternatives && !wide);
203
204         } else if (ob == dialog_->check_wide) {
205                 if (wide && placement_.get() == HERE_DEFINITELY) {
206                         // wide float doesn't allow 'Here, definitely!'
207                         // placement
208                         placement_.set(dialog_->radio_default);
209                 }
210                 setEnabled(dialog_->check_here, alternatives && !wide);
211                 setEnabled(dialog_->radio_here_definitely, !wide);
212         }
213
214         // enable force button, if Alternatives is selected and at least
215         // one of its check buttons
216         bool const enable_force = alternatives &&
217                 (fl_get_button(dialog_->check_top) ||
218                  fl_get_button(dialog_->check_bottom) ||
219                  fl_get_button(dialog_->check_page) ||
220                  (fl_get_button(dialog_->check_here) && !wide));
221         setEnabled(dialog_->check_force, enable_force);
222
223         return ButtonPolicy::SMI_VALID;
224 }