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