]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/FloatPlacement.cpp
Amend f441590c
[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), float_list_(0)
37 {
38         setupUi(this);
39
40         connect(floatTypeCO, SIGNAL(activated(int)), this, SLOT(changedSlot()));
41         connect(topCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
42         connect(bottomCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
43         connect(pageCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
44         connect(herepossiblyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
45         connect(heredefinitelyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
46         connect(ignoreCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
47         connect(spanCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
48         connect(sidewaysCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
49
50         floatTypeTitle->setVisible(show_options);
51         floatTypeCO->setVisible(show_options);
52         spanCB->setVisible(show_options);
53         sidewaysCB->setVisible(show_options);
54 }
55
56
57 docstring FloatPlacement::dialogToParams() const
58 {
59         InsetFloatParams params;
60         params.type = fromqstr(floatTypeCO->itemData(floatTypeCO->currentIndex()).toString());
61         params.placement = get(params.wide, params.sideways);
62         return from_ascii(InsetFloat::params2string(params));
63 }
64
65
66 void FloatPlacement::useWide()
67 {
68         spanCB->show();
69 }
70
71
72 void FloatPlacement::useSideways()
73 {
74         sidewaysCB->show();
75 }
76
77
78 bool FloatPlacement::possiblePlacement(char const & p) const
79 {
80         return !spanCB->isVisible() || contains(allowed_placement_, p);
81 }
82
83
84 void FloatPlacement::set(string const & placement)
85 {
86         bool def_placement = false;
87         bool top = false;
88         bool bottom = false;
89         bool page = false;
90         bool here = false;
91         bool force = false;
92         bool here_definitely = false;
93
94         if (placement.empty()) {
95                 def_placement = true;
96         } else if (contains(placement, 'H') && possiblePlacement('H')) {
97                 here_definitely = true;
98         } else {
99                 if (contains(placement, '!') && possiblePlacement('!')) {
100                         force = true;
101                 }
102                 if (contains(placement, 't') && possiblePlacement('t')) {
103                         top = true;
104                 }
105                 if (contains(placement, 'b') && possiblePlacement('b')) {
106                         bottom = true;
107                 }
108                 if (contains(placement, 'p') && possiblePlacement('p')) {
109                         page = true;
110                 }
111                 if (contains(placement, 'h') && possiblePlacement('h')) {
112                         here = true;
113                 }
114         }
115
116         defaultsCB->setChecked(def_placement);
117         topCB->setChecked(top);
118         bottomCB->setChecked(bottom);
119         pageCB->setChecked(page);
120         herepossiblyCB->setChecked(here);
121         ignoreCB->setChecked(force);
122         heredefinitelyCB->setChecked(here_definitely);
123         checkAllowed();
124 }
125
126
127 void FloatPlacement::initFloatTypeCO(FloatList const & floats)
128 {
129         if (float_list_ == &floats)
130                 return;
131
132         float_list_ = &floats;
133         floatTypeCO->clear();
134         FloatList::const_iterator it = floats.begin();
135         FloatList::const_iterator const end = floats.end();
136         for (; it != end; ++it) {
137                 floatTypeCO->addItem(qt_(it->second.name()),
138                                      toqstr(it->second.floattype()));
139         }
140 }
141
142
143 void FloatPlacement::paramsToDialog(Inset const * inset)
144 {
145         InsetFloat const * fl = static_cast<InsetFloat const *>(inset);
146         InsetFloatParams const & params = fl->params();
147
148         BufferParams const & bp = fl->buffer().params();
149         FloatList const & floats = bp.documentClass().floats();
150         initFloatTypeCO(floats);
151
152         int const item = floatTypeCO->findData(toqstr(params.type));
153         floatTypeCO->setCurrentIndex(item);
154
155         allowed_placement_ = floats.allowedPlacement(params.type);
156         allows_sideways_ = floats.allowsSideways(params.type);
157         allows_wide_ = floats.allowsWide(params.type);
158
159         set(params.placement);
160
161         standardfloat_ = (params.type == "figure"
162                 || params.type == "table");
163
164         if (params.wide) {
165                 herepossiblyCB->setChecked(false);
166                 heredefinitelyCB->setChecked(false);
167                 bottomCB->setChecked(false);
168         }
169
170         spanCB->setChecked(params.wide && allows_wide_);
171         sidewaysCB->setChecked(params.sideways && allows_sideways_);
172
173         checkAllowed();
174 }
175
176
177 string const FloatPlacement::get(bool & wide, bool & sideways) const
178 {
179         wide = spanCB->isChecked();
180         sideways = sidewaysCB->isChecked();
181
182         return get();
183 }
184
185
186 string const FloatPlacement::get() const
187 {
188         string placement;
189
190         if (defaultsCB->isChecked())
191                 return placement;
192
193         if (heredefinitelyCB->isChecked()) {
194                 placement += 'H';
195         } else {
196                 if (ignoreCB->isChecked()) {
197                         placement += '!';
198                 }
199                 if (topCB->isChecked()) {
200                         placement += 't';
201                 }
202                 if (bottomCB->isChecked()) {
203                         placement += 'b';
204                 }
205                 if (pageCB->isChecked()) {
206                         placement += 'p';
207                 }
208                 if (herepossiblyCB->isChecked()) {
209                         placement += 'h';
210                 }
211         }
212         return placement;
213 }
214
215
216 void FloatPlacement::on_defaultsCB_stateChanged(int state)
217 {
218         checkAllowed();
219         if (state == Qt::Checked)
220                 return;
221         if (topCB->isChecked() || bottomCB->isChecked()
222            || pageCB->isChecked() || herepossiblyCB->isChecked()
223            || heredefinitelyCB->isChecked() || ignoreCB->isChecked())
224                 changed();
225 }
226
227
228 void FloatPlacement::changedSlot()
229 {
230         checkAllowed();
231         changed();
232 }
233
234
235 void FloatPlacement::checkAllowed() const
236 {
237         bool const defaults = defaultsCB->isChecked();
238         bool const ignore = topCB->isChecked() || bottomCB->isChecked()
239                       || pageCB->isChecked() || herepossiblyCB->isChecked();
240         bool const heredefinitely = heredefinitelyCB->isChecked();
241
242         // float or document dialog?
243         if (spanCB->isVisible()) {
244                 bool const span = spanCB->isChecked();
245                 bool const sideways = sidewaysCB->isChecked();
246                 defaultsCB->setEnabled(!sideways);
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                 herepossiblyCB->setEnabled(!sideways && !defaults && !span && !heredefinitely
254                                            && contains(allowed_placement_, 'h'));
255                 heredefinitelyCB->setEnabled(!sideways && !defaults && !span
256                                              && contains(allowed_placement_, 'H'));
257                 ignoreCB->setEnabled(!sideways && !defaults && ignore && !heredefinitely
258                                      && contains(allowed_placement_, '!'));
259                 spanCB->setEnabled(allows_wide_ && (!sideways || standardfloat_));
260                 sidewaysCB->setEnabled(allows_sideways_);
261         } else {
262                 topCB->setEnabled(!defaults && !heredefinitely);
263                 bottomCB->setEnabled(!defaults && !heredefinitely);
264                 pageCB->setEnabled(!defaults && !heredefinitely);
265                 herepossiblyCB->setEnabled(!defaults && !heredefinitely);
266                 heredefinitelyCB->setEnabled(!defaults);
267                 ignoreCB->setEnabled(!defaults && ignore && !heredefinitely);
268         }
269 }
270
271
272 bool FloatPlacement::checkWidgets(bool readonly) const
273 {
274         if (readonly) {
275                 floatTypeCO->setEnabled(false);
276                 defaultsCB->setEnabled(false);
277                 options->setEnabled(false);
278                 spanCB->setEnabled(false);
279                 sidewaysCB->setEnabled(false);
280         } else
281                 checkAllowed();
282
283         return InsetParamsWidget::checkWidgets();
284 }
285
286 } // namespace frontend
287 } // namespace lyx
288
289 #include "moc_FloatPlacement.cpp"