]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/FloatPlacement.cpp
Revert "Mark some intentional fall-throughs (in a way understandable to gcc)"
[lyx.git] / src / frontends / qt4 / FloatPlacement.cpp
1 /**
2  * \file FloatPlacement.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "FloatPlacement.h"
15 #include "qt_helpers.h"
16
17 #include "Buffer.h"
18 #include "BufferParams.h"
19 #include "FloatList.h"
20 #include "TextClass.h"
21
22 #include "insets/InsetFloat.h"
23 #include "support/lstrings.h"
24
25 #include <map>
26
27 using namespace std;
28 using namespace lyx::support;
29
30
31 namespace lyx {
32
33 namespace frontend {
34
35 FloatPlacement::FloatPlacement(bool show_options, QWidget * parent)
36         : InsetParamsWidget(parent), standardfloat_ (true),
37           allows_wide_(true), allows_sideways_(true), float_list_(0)
38 {
39         setupUi(this);
40
41         connect(floatTypeCO, SIGNAL(activated(int)), this, SLOT(changedSlot()));
42         connect(topCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
43         connect(bottomCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
44         connect(pageCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
45         connect(herepossiblyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
46         connect(heredefinitelyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
47         connect(ignoreCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
48         connect(spanCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
49         connect(sidewaysCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
50
51         floatTypeTitle->setVisible(show_options);
52         floatTypeCO->setVisible(show_options);
53         spanCB->setVisible(show_options);
54         sidewaysCB->setVisible(show_options);
55 }
56
57
58 docstring FloatPlacement::dialogToParams() const
59 {
60         InsetFloatParams params;
61         params.type = fromqstr(floatTypeCO->itemData(floatTypeCO->currentIndex()).toString());
62         params.placement = get(params.wide, params.sideways);
63         return from_ascii(InsetFloat::params2string(params));
64 }
65
66
67 void FloatPlacement::useWide()
68 {
69         spanCB->show();
70 }
71
72
73 void FloatPlacement::useSideways()
74 {
75         sidewaysCB->show();
76 }
77
78
79 bool FloatPlacement::possiblePlacement(char const & p) const
80 {
81         return !spanCB->isVisible() || contains(allowed_placement_, p);
82 }
83
84
85 void FloatPlacement::set(string const & placement)
86 {
87         bool def_placement = false;
88         bool top = false;
89         bool bottom = false;
90         bool page = false;
91         bool here = false;
92         bool force = false;
93         bool here_definitely = false;
94
95         if (placement.empty()) {
96                 def_placement = true;
97         } else if (contains(placement, 'H') && possiblePlacement('H')) {
98                 here_definitely = true;
99         } else {
100                 if (contains(placement, '!') && possiblePlacement('!')) {
101                         force = true;
102                 }
103                 if (contains(placement, 't') && possiblePlacement('t')) {
104                         top = true;
105                 }
106                 if (contains(placement, 'b') && possiblePlacement('b')) {
107                         bottom = true;
108                 }
109                 if (contains(placement, 'p') && possiblePlacement('p')) {
110                         page = true;
111                 }
112                 if (contains(placement, 'h') && possiblePlacement('h')) {
113                         here = true;
114                 }
115         }
116
117         defaultsCB->setChecked(def_placement);
118         topCB->setChecked(top);
119         bottomCB->setChecked(bottom);
120         pageCB->setChecked(page);
121         herepossiblyCB->setChecked(here);
122         ignoreCB->setChecked(force);
123         heredefinitelyCB->setChecked(here_definitely);
124         checkAllowed();
125 }
126
127
128 void FloatPlacement::initFloatTypeCO(FloatList const & floats)
129 {
130         if (float_list_ == &floats)
131                 return;
132
133         float_list_ = &floats;
134         floatTypeCO->clear();
135         FloatList::const_iterator it = floats.begin();
136         FloatList::const_iterator const end = floats.end();
137         for (; it != end; ++it) {
138                 floatTypeCO->addItem(qt_(it->second.name()),
139                                      toqstr(it->second.floattype()));
140         }
141 }
142
143
144 void FloatPlacement::paramsToDialog(Inset const * inset)
145 {
146         InsetFloat const * fl = static_cast<InsetFloat const *>(inset);
147         InsetFloatParams const & params = fl->params();
148
149         BufferParams const & bp = fl->buffer().params();
150         FloatList const & floats = bp.documentClass().floats();
151         initFloatTypeCO(floats);
152
153         int const item = floatTypeCO->findData(toqstr(params.type));
154         floatTypeCO->setCurrentIndex(item);
155
156         allowed_placement_ = floats.allowedPlacement(params.type);
157         allows_sideways_ = floats.allowsSideways(params.type);
158         allows_wide_ = floats.allowsWide(params.type);
159
160         set(params.placement);
161
162         standardfloat_ = (params.type == "figure"
163                 || params.type == "table");
164
165         if (params.wide) {
166                 herepossiblyCB->setChecked(false);
167                 heredefinitelyCB->setChecked(false);
168                 bottomCB->setChecked(false);
169         }
170
171         spanCB->setChecked(params.wide && allows_wide_);
172         sidewaysCB->setChecked(params.sideways && allows_sideways_);
173
174         checkAllowed();
175 }
176
177
178 string const FloatPlacement::get(bool & wide, bool & sideways) const
179 {
180         wide = spanCB->isChecked();
181         sideways = sidewaysCB->isChecked();
182
183         return get();
184 }
185
186
187 string const FloatPlacement::get() const
188 {
189         string placement;
190
191         if (defaultsCB->isChecked())
192                 return placement;
193
194         if (heredefinitelyCB->isChecked()) {
195                 placement += 'H';
196         } else {
197                 if (ignoreCB->isChecked()) {
198                         placement += '!';
199                 }
200                 if (topCB->isChecked()) {
201                         placement += 't';
202                 }
203                 if (bottomCB->isChecked()) {
204                         placement += 'b';
205                 }
206                 if (pageCB->isChecked()) {
207                         placement += 'p';
208                 }
209                 if (herepossiblyCB->isChecked()) {
210                         placement += 'h';
211                 }
212         }
213         return placement;
214 }
215
216
217 void FloatPlacement::on_defaultsCB_stateChanged(int state)
218 {
219         checkAllowed();
220         if (state == Qt::Checked)
221                 return;
222         if (topCB->isChecked() || bottomCB->isChecked()
223            || pageCB->isChecked() || herepossiblyCB->isChecked()
224            || heredefinitelyCB->isChecked() || ignoreCB->isChecked())
225                 changed();
226 }
227
228
229 void FloatPlacement::changedSlot()
230 {
231         checkAllowed();
232         changed();
233 }
234
235
236 void FloatPlacement::checkAllowed() const
237 {
238         bool const defaults = defaultsCB->isChecked();
239         bool const ignore = topCB->isChecked() || bottomCB->isChecked()
240                       || pageCB->isChecked() || herepossiblyCB->isChecked();
241         bool const heredefinitely = heredefinitelyCB->isChecked();
242
243         // float or document dialog?
244         if (spanCB->isVisible()) {
245                 bool const span = spanCB->isChecked();
246                 bool const sideways = sidewaysCB->isChecked();
247                 topCB->setEnabled(!sideways && !defaults && !heredefinitely
248                                   && contains(allowed_placement_, 't'));
249                 bottomCB->setEnabled(!sideways && !defaults && !span && !heredefinitely
250                                      && contains(allowed_placement_, 'b'));
251                 pageCB->setEnabled(!sideways && !defaults && !heredefinitely
252                                    && contains(allowed_placement_, 'p'));
253                 if (!pageCB->isChecked())
254                         pageCB->setChecked(sideways && contains(allowed_placement_, 'p'));
255                 herepossiblyCB->setEnabled(!defaults && !span && !heredefinitely
256                                            && contains(allowed_placement_, 'h'));
257                 heredefinitelyCB->setEnabled(!defaults && !span
258                                              && contains(allowed_placement_, 'H'));
259                 ignoreCB->setEnabled(!defaults && ignore && !heredefinitely
260                                      && contains(allowed_placement_, '!'));
261                 // handle special case with sideways
262                 if ((!herepossiblyCB->isChecked() && sideways) || (span && sideways))
263                         ignoreCB->setEnabled(false);
264                 // when disabled the options must be unchecked to avoid strange LaTeX export
265                 // don't do it for pageCB because this case is handled with sideways
266                 if (ignoreCB->isChecked() && !ignoreCB->isEnabled())
267                         ignoreCB->setChecked(false);
268                 if (herepossiblyCB->isChecked() && !herepossiblyCB->isEnabled())
269                         herepossiblyCB->setChecked(false);
270                 if (topCB->isChecked() && !topCB->isEnabled())
271                         topCB->setChecked(false);
272                 if (bottomCB->isChecked() && !bottomCB->isEnabled())
273                         bottomCB->setChecked(false);
274                 spanCB->setEnabled(allows_wide_ && (!sideways || standardfloat_));
275                 sidewaysCB->setEnabled(allows_sideways_);
276                 defaultsCB->setEnabled(!(sideways && span));
277         } else {
278                 topCB->setEnabled(!defaults && !heredefinitely);
279                 bottomCB->setEnabled(!defaults && !heredefinitely);
280                 pageCB->setEnabled(!defaults && !heredefinitely);
281                 herepossiblyCB->setEnabled(!defaults && !heredefinitely);
282                 heredefinitelyCB->setEnabled(!defaults);
283                 ignoreCB->setEnabled(!defaults && ignore && !heredefinitely);
284         }
285 }
286
287
288 bool FloatPlacement::checkWidgets(bool readonly) const
289 {
290         if (readonly) {
291                 floatTypeCO->setEnabled(false);
292                 defaultsCB->setEnabled(false);
293                 options->setEnabled(false);
294                 spanCB->setEnabled(false);
295                 sidewaysCB->setEnabled(false);
296         } else
297                 checkAllowed();
298
299         return InsetParamsWidget::checkWidgets();
300 }
301
302 } // namespace frontend
303 } // namespace lyx
304
305 #include "moc_FloatPlacement.cpp"