]> git.lyx.org Git - features.git/blob - src/frontends/qt4/FloatPlacement.cpp
Attempt to simplify as much as possible Inset parameter dialog creation. We now just...
[features.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
21 #include "insets/InsetFloat.h"
22 #include "support/lstrings.h"
23
24 using namespace std;
25 using namespace lyx::support;
26
27
28 namespace lyx {
29
30 namespace frontend {
31
32 FloatPlacement::FloatPlacement(bool show_options, QWidget * parent)
33         : InsetParamsWidget(parent), float_list_(0)
34 {
35         setupUi(this);
36
37         connect(floatTypeCO, SIGNAL(activated(int)), this, SLOT(changedSlot()));
38         connect(topCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
39         connect(bottomCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
40         connect(pageCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
41         connect(herepossiblyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
42         connect(heredefinitelyCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
43         connect(ignoreCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
44         connect(spanCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
45         connect(sidewaysCB, SIGNAL(clicked()), this, SLOT(changedSlot()));
46
47         spanCB->setVisible(show_options);
48         sidewaysCB->setVisible(show_options);
49 }
50
51
52 docstring FloatPlacement::dialogToParams() const
53 {
54         InsetFloatParams params;
55         params.type = fromqstr(floatTypeCO->itemData(floatTypeCO->currentIndex()).toString());
56         params.placement = get(params.wide, params.sideways);
57         return from_ascii(InsetFloat::params2string(params));
58 }
59
60
61 void FloatPlacement::useWide()
62 {
63         spanCB->show();
64 }
65
66
67 void FloatPlacement::useSideways()
68 {
69         sidewaysCB->show();
70 }
71
72
73 void FloatPlacement::set(string const & placement)
74 {
75         bool def_placement = false;
76         bool top = false;
77         bool bottom = false;
78         bool page = false;
79         bool here = false;
80         bool force = false;
81         bool here_definitely = false;
82
83         if (placement.empty()) {
84                 def_placement = true;
85         } else if (contains(placement, 'H')) {
86                 here_definitely = true;
87         } else {
88                 if (contains(placement, '!')) {
89                         force = true;
90                 }
91                 if (contains(placement, 't')) {
92                         top = true;
93                 }
94                 if (contains(placement, 'b')) {
95                         bottom = true;
96                 }
97                 if (contains(placement, 'p')) {
98                         page = true;
99                 }
100                 if (contains(placement, 'h')) {
101                         here = true;
102                 }
103         }
104
105         defaultsCB->setChecked(def_placement);
106         topCB->setChecked(top);
107         bottomCB->setChecked(bottom);
108         pageCB->setChecked(page);
109         herepossiblyCB->setChecked(here);
110         ignoreCB->setChecked(force);
111         heredefinitelyCB->setChecked(here_definitely);
112         checkAllowed();
113 }
114
115
116 void FloatPlacement::initFloatTypeCO(FloatList const & floats)
117 {
118         if (float_list_ == &floats)
119                 return;
120
121         float_list_ = &floats;
122         floatTypeCO->clear();
123         FloatList::const_iterator it = floats.begin();
124         FloatList::const_iterator const end = floats.end();
125         for (; it != end; ++it) {
126                 floatTypeCO->addItem(qt_(it->second.name()),
127                                      toqstr(it->second.type()));
128         }
129 }
130
131
132 void FloatPlacement::paramsToDialog(Inset const * inset)
133 {
134         InsetFloat const * fl = static_cast<InsetFloat const *>(inset);
135         InsetFloatParams const & params = fl->params();
136
137         BufferParams const & bp = fl->buffer().params();
138         initFloatTypeCO(bp.documentClass().floats());
139
140         int const item = floatTypeCO->findData(toqstr(params.type));
141         floatTypeCO->setCurrentIndex(item);
142
143         set(params.placement);
144
145         standardfloat_ = (params.type == "figure"
146                 || params.type == "table");
147
148         if (params.wide) {
149                 herepossiblyCB->setChecked(false);
150                 heredefinitelyCB->setChecked(false);
151                 bottomCB->setChecked(false);
152         }
153
154         spanCB->setChecked(params.wide);
155         sidewaysCB->setChecked(params.sideways);
156         // the package rotfloat only has *-versions for figure and table
157         spanCB->setEnabled(!params.sideways || standardfloat_);
158         checkAllowed();
159 }
160
161
162 string const FloatPlacement::get(bool & wide, bool & sideways) const
163 {
164         wide = spanCB->isChecked();
165         sideways = sidewaysCB->isChecked();
166
167         return get();
168 }
169
170
171 string const FloatPlacement::get() const
172 {
173         string placement;
174
175         if (defaultsCB->isChecked())
176                 return placement;
177
178         if (heredefinitelyCB->isChecked()) {
179                 placement += 'H';
180         } else {
181                 if (ignoreCB->isChecked()) {
182                         placement += '!';
183                 }
184                 if (topCB->isChecked()) {
185                         placement += 't';
186                 }
187                 if (bottomCB->isChecked()) {
188                         placement += 'b';
189                 }
190                 if (pageCB->isChecked()) {
191                         placement += 'p';
192                 }
193                 if (herepossiblyCB->isChecked()) {
194                         placement += 'h';
195                 }
196         }
197         return placement;
198 }
199
200
201 void FloatPlacement::on_defaultsCB_stateChanged(int state)
202 {
203         checkAllowed();
204         if (state == Qt::Checked)
205                 return;
206         if (topCB->isChecked() || bottomCB->isChecked()
207            || pageCB->isChecked() || herepossiblyCB->isChecked()
208            || heredefinitelyCB->isChecked() || ignoreCB->isChecked())
209                 changed();
210 }
211
212
213 void FloatPlacement::changedSlot()
214 {
215         checkAllowed();
216         changed();
217 }
218
219
220 void FloatPlacement::checkAllowed()
221 {
222         bool const defaults = defaultsCB->isChecked();
223         bool const ignore = topCB->isChecked() || bottomCB->isChecked()
224                       || pageCB->isChecked() || herepossiblyCB->isChecked();
225         bool const heredefinitely = heredefinitelyCB->isChecked();
226
227         // float or document dialog?
228         if (spanCB->isVisible()) {
229                 bool const span = spanCB->isChecked();
230                 bool const sideways = sidewaysCB->isChecked();
231                 defaultsCB->setEnabled(!sideways);
232                 topCB->setEnabled(!sideways && !defaults && !heredefinitely);
233                 bottomCB->setEnabled(!sideways && !defaults && !span && !heredefinitely);
234                 pageCB->setEnabled(!sideways && !defaults && !heredefinitely);
235                 herepossiblyCB->setEnabled(!sideways && !defaults && !span && !heredefinitely);
236                 heredefinitelyCB->setEnabled(!sideways && !defaults && !span);
237                 ignoreCB->setEnabled(!sideways && !defaults && ignore && !heredefinitely);
238                 spanCB->setEnabled(!sideways || standardfloat_);
239         } else {
240                 topCB->setEnabled(!defaults && !heredefinitely);
241                 bottomCB->setEnabled(!defaults && !heredefinitely);
242                 pageCB->setEnabled(!defaults && !heredefinitely);
243                 herepossiblyCB->setEnabled(!defaults && !heredefinitely);
244                 heredefinitelyCB->setEnabled(!defaults);
245                 ignoreCB->setEnabled(!defaults && ignore && !heredefinitely);
246         }
247 }
248
249 } // namespace frontend
250 } // namespace lyx
251
252 #include "moc_FloatPlacement.cpp"