]> git.lyx.org Git - features.git/blob - src/frontends/qt4/QBox.cpp
Whitespace cleanup
[features.git] / src / frontends / qt4 / QBox.cpp
1 /**
2  * \file QBox.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna (Minipage stuff)
7  * \author Martin Vermeer
8  * \author Jürgen Spitzmüller
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "QBox.h"
16
17 #include "CheckedLineEdit.h"
18 #include "LengthCombo.h"
19 #include "qt_helpers.h"
20 #include "Qt2BC.h"
21 #include "lengthcommon.h"
22 #include "LyXRC.h" // to set the default length values
23 #include "Validator.h"
24
25 #include "controllers/ControlBox.h"
26 #include "controllers/frontend_helpers.h"
27
28 #include "insets/InsetBox.h"
29
30 #include "support/lstrings.h"
31
32 #include <QPushButton>
33 #include <QLineEdit>
34 #include <QCloseEvent>
35
36
37 using lyx::support::getStringFromVector;
38 using lyx::support::isStrDbl;
39 using lyx::support::subst;
40 using std::string;
41
42
43 namespace lyx {
44 namespace frontend {
45
46 //////////////////////////////////////////////////////////////////
47 //
48 // QBoxDialog
49 //
50 //////////////////////////////////////////////////////////////////
51
52 QBoxDialog::QBoxDialog(QBox * form)
53         : form_(form)
54 {
55         setupUi(this);
56         connect(restorePB, SIGNAL(clicked()), form, SLOT(slotRestore()));
57         connect(okPB, SIGNAL(clicked()), form, SLOT(slotOK()));
58         connect(applyPB, SIGNAL(clicked()), form, SLOT(slotApply()));
59         connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose()));
60
61         connect(widthED, SIGNAL(textChanged(const QString &)),
62                 this, SLOT(change_adaptor()));
63         connect(widthUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
64                 this, SLOT(change_adaptor()));
65         connect(valignCO, SIGNAL(highlighted(const QString &)),
66                 this, SLOT(change_adaptor()));
67         connect(heightED, SIGNAL(textChanged(const QString &)),
68                 this, SLOT(change_adaptor()));
69         connect(heightUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT) ),
70                 this, SLOT(change_adaptor()));
71         connect(restorePB, SIGNAL(clicked()), this, SLOT(restoreClicked()));
72         connect(typeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
73         connect(typeCO, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
74         connect(halignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
75         connect(ialignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
76         connect(innerBoxCO, SIGNAL(activated(const QString&)),
77                 this, SLOT(innerBoxChanged(const QString &)));
78         connect(innerBoxCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
79
80         heightED->setValidator(unsignedLengthValidator(heightED));
81         widthED->setValidator(unsignedLengthValidator(widthED));
82 }
83
84
85 void QBoxDialog::closeEvent(QCloseEvent * e)
86 {
87         form_->slotWMHide();
88         e->accept();
89 }
90
91
92 void QBoxDialog::change_adaptor()
93 {
94         form_->changed();
95 }
96
97
98 void QBoxDialog::innerBoxChanged(const QString & str)
99 {
100         bool const ibox = (str != qt_("None"));
101         valignCO->setEnabled(ibox);
102         ialignCO->setEnabled(ibox);
103         halignCO->setEnabled(!ibox);
104         heightED->setEnabled(ibox);
105         heightUnitsLC->setEnabled(ibox);
106         form_->setSpecial(ibox);
107 }
108
109
110 void QBoxDialog::typeChanged(int index)
111 {
112         bool const frameless = (index == 0);
113         if (frameless) {
114                 valignCO->setEnabled(true);
115                 ialignCO->setEnabled(true);
116                 halignCO->setEnabled(false);
117                 heightED->setEnabled(true);
118                 heightUnitsLC->setEnabled(true);
119                 form_->setSpecial(true);
120         }
121         int itype = innerBoxCO->currentIndex();
122         form_->setInnerType(frameless, itype);
123 }
124
125
126 void QBoxDialog::restoreClicked()
127 {
128         form_->setInnerType(true, 2);
129         widthED->setText("100");
130         widthUnitsLC->setCurrentItem(Length::PCW);
131         heightED->setText("1");
132         for (int j = 0; j < heightUnitsLC->count(); j++) {
133                 if (heightUnitsLC->itemText(j) == qt_("Total Height"))
134                         heightUnitsLC->setCurrentItem(j);
135         }
136 }
137
138
139 //////////////////////////////////////////////////////////////////
140 //
141 // QBox
142 //
143 //////////////////////////////////////////////////////////////////
144
145 typedef QController<ControlBox, QView<QBoxDialog> > box_base_class;
146
147 QBox::QBox(Dialog & parent)
148         : box_base_class(parent, _("Box Settings"))
149 {}
150
151
152 void QBox::build_dialog()
153 {
154         dialog_.reset(new QBoxDialog(this));
155
156         // fill the box type choice
157         box_gui_tokens(ids_, gui_names_);
158         for (unsigned int i = 0; i < gui_names_.size(); ++i)
159                 dialog_->typeCO->addItem(toqstr(gui_names_[i]));
160
161         // add the special units to the height choice
162         // width needs different handling
163         box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
164         for (unsigned int i = 1; i < gui_names_spec_.size(); ++i)
165                 dialog_->heightUnitsLC->addItem(toqstr(gui_names_spec_[i]));
166
167         bcview().addReadOnly(dialog_->typeCO);
168         bcview().addReadOnly(dialog_->innerBoxCO);
169         bcview().addReadOnly(dialog_->valignCO);
170         bcview().addReadOnly(dialog_->ialignCO);
171         bcview().addReadOnly(dialog_->halignCO);
172         bcview().addReadOnly(dialog_->widthED);
173         bcview().addReadOnly(dialog_->heightED);
174         bcview().addReadOnly(dialog_->widthUnitsLC);
175         bcview().addReadOnly(dialog_->heightUnitsLC);
176
177         bcview().setRestore(dialog_->restorePB);
178         bcview().setOK(dialog_->okPB);
179         bcview().setApply(dialog_->applyPB);
180         bcview().setCancel(dialog_->closePB);
181
182         // initialize the length validator
183         addCheckedLineEdit(bcview(), dialog_->widthED, dialog_->widthLA);
184         addCheckedLineEdit(bcview(), dialog_->heightED, dialog_->heightLA);
185 }
186
187
188 void QBox::update_contents()
189 {
190         string type(controller().params().type);
191         for (unsigned int i = 0; i < gui_names_.size(); ++i) {
192                 if (type == ids_[i])
193                         dialog_->typeCO->setCurrentIndex(i);
194         }
195
196         // default: minipage
197         unsigned int inner_type = 2;
198         if (!controller().params().inner_box)
199                 // none
200                 inner_type = 0;
201         if (controller().params().use_parbox)
202                 // parbox
203                 inner_type = 1;
204         bool frameless = (controller().params().type == "Frameless");
205         setInnerType(frameless, inner_type);
206
207         char c = controller().params().pos;
208         dialog_->valignCO->setCurrentIndex(string("tcb").find(c, 0));
209         c = controller().params().inner_pos;
210         dialog_->ialignCO->setCurrentIndex(string("tcbs").find(c, 0));
211         c = controller().params().hor_pos;
212         dialog_->halignCO->setCurrentIndex(string("lcrs").find(c, 0));
213
214         bool ibox = controller().params().inner_box;
215         dialog_->valignCO->setEnabled(ibox);
216         dialog_->ialignCO->setEnabled(ibox);
217         dialog_->halignCO->setEnabled(!ibox);
218         setSpecial(ibox);
219
220         Length::UNIT default_unit =
221                 (lyxrc.default_papersize > 3) ? Length::CM : Length::IN;
222
223         lengthToWidgets(dialog_->widthED, dialog_->widthUnitsLC,
224                 (controller().params().width).asString(), default_unit);
225
226         string const special(controller().params().special);
227         if (!special.empty() && special != "none") {
228                 QString spc;
229                 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
230                         if (special == ids_spec_[i])
231                                 spc = toqstr(gui_names_spec_[i].c_str());
232                 }
233                 for (int j = 0; j < dialog_->widthUnitsLC->count(); j++) {
234                         if (dialog_->widthUnitsLC->itemText(j) == spc)
235                                 dialog_->widthUnitsLC->setCurrentIndex(j);
236                 }
237         }
238
239         lengthToWidgets(dialog_->heightED, dialog_->heightUnitsLC,
240                 (controller().params().height).asString(), default_unit);
241
242         string const height_special(controller().params().height_special);
243         if (!height_special.empty() && height_special != "none") {
244                 QString hspc;
245                 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
246                         if (height_special == ids_spec_[i]) {
247                                 hspc = toqstr(gui_names_spec_[i].c_str());
248                         }
249                 }
250                 for (int j = 0; j < dialog_->heightUnitsLC->count(); j++) {
251                         if (dialog_->heightUnitsLC->itemText(j) == hspc) {
252                                 dialog_->heightUnitsLC->setCurrentIndex(j);
253                         }
254                 }
255         }
256
257         dialog_->heightED->setEnabled(ibox);
258         dialog_->heightUnitsLC->setEnabled(ibox);
259 }
260
261
262 void QBox::apply()
263 {
264         controller().params().type =
265                 ids_[dialog_->typeCO->currentIndex()];
266
267         controller().params().inner_box =
268                 dialog_->innerBoxCO->currentText() != qt_("None");
269         controller().params().use_parbox =
270                 dialog_->innerBoxCO->currentText() ==  qt_("Parbox");
271
272         controller().params().pos =
273                 "tcb"[dialog_->valignCO->currentIndex()];
274         controller().params().inner_pos =
275                 "tcbs"[dialog_->ialignCO->currentIndex()];
276         controller().params().hor_pos =
277                 "lcrs"[dialog_->halignCO->currentIndex()];
278
279         int i = 0;
280         bool spec = false;
281         QString special = dialog_->widthUnitsLC->currentText();
282         QString value = dialog_->widthED->text();
283         if (special == qt_("Height")) {
284                 i = 1;
285                 spec = true;
286         } else if (special == qt_("Depth")) {
287                 i = 2;
288                 spec = true;
289         } else if (special == qt_("Total Height")) {
290                 i = 3;
291                 spec = true;
292         } else if (special == qt_("Width")) {
293                 i = 4;
294                 spec = true;
295         }
296         // the user might insert a non-special value in the line edit
297         if (isValidLength(fromqstr(value))) {
298                 i = 0;
299                 spec = false;
300         }
301         controller().params().special = ids_spec_[i];
302
303         string width;
304         if (spec) {
305                 width = fromqstr(value);
306                 // beware: bogosity! the unit is simply ignored in this case
307                 width += "in";
308         } else
309                 width = widgetsToLength(dialog_->widthED, dialog_->widthUnitsLC);
310
311         controller().params().width = Length(width);
312
313         i = 0;
314         spec = false;
315         special = dialog_->heightUnitsLC->currentText();
316         value = dialog_->heightED->text();
317         if (special == qt_("Height")) {
318                 i = 1;
319                 spec = true;
320         } else if (special == qt_("Depth")) {
321                 i = 2;
322                 spec = true;
323         } else if (special == qt_("Total Height")) {
324                 i = 3;
325                 spec = true;
326         } else if (special == qt_("Width")) {
327                 i = 4;
328                 spec = true;
329         }
330         // the user might insert a non-special value in the line edit
331         if (isValidLength(fromqstr(value))) {
332                 i = 0;
333                 spec = false;
334         }
335         controller().params().height_special = ids_spec_[i];
336
337         string height;
338         if (spec  && !isValidLength(fromqstr(dialog_->heightED->text()))) {
339                 height = fromqstr(value);
340                 // beware: bogosity! the unit is simply ignored in this case
341                 height += "in";
342         } else
343                 height = widgetsToLength(dialog_->heightED, dialog_->heightUnitsLC);
344
345         controller().params().height = Length(height);
346 }
347
348
349 void QBox::setSpecial(bool ibox)
350 {
351         box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
352         // check if the widget contains the special units
353         int count = dialog_->widthUnitsLC->count();
354         bool has_special = false;
355         for (int i = 0; i < count; i++)
356                 if (dialog_->widthUnitsLC->itemText(i).contains(qt_("Total Height")) > 0)
357                         has_special = true;
358         // insert 'em if needed...
359         if (!ibox && !has_special) {
360                 for (unsigned int i = 1; i < gui_names_spec_.size(); i++)
361                         dialog_->widthUnitsLC->addItem(toqstr(gui_names_spec_[i]));
362         // ... or remove 'em if needed
363         } else if (ibox && has_special) {
364                 dialog_->widthUnitsLC->clear();
365                 for (int i = 0; i < num_units; i++)
366                         dialog_->widthUnitsLC->addItem(qt_(unit_name_gui[i]));
367         }
368 }
369
370
371 void QBox::setInnerType(bool frameless, int i)
372 {
373         // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
374         // we have to remove "none" then and adjust the combo
375         if (frameless) {
376                 dialog_->innerBoxCO->clear();
377                 dialog_->innerBoxCO->addItem(qt_("Parbox"));
378                 dialog_->innerBoxCO->addItem(qt_("Minipage"));
379                 dialog_->innerBoxCO->setCurrentIndex(i - 1);
380         } else {
381                 if (dialog_->innerBoxCO->count() == 2)
382                         i += 1;
383                 dialog_->innerBoxCO->clear();
384                 dialog_->innerBoxCO->addItem(qt_("None"));
385                 dialog_->innerBoxCO->addItem(qt_("Parbox"));
386                 dialog_->innerBoxCO->addItem(qt_("Minipage"));
387                 dialog_->innerBoxCO->setCurrentIndex(i);
388         }
389 }
390
391 } // namespace frontend
392 } // namespace lyx
393
394
395 #include "QBox_moc.cpp"