3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Jürgen Vigna (Minipage stuff)
7 * \author Martin Vermeer
8 * \author Jürgen Spitzmüller
10 * Full author contact details are available in file CREDITS.
17 #include "FuncRequest.h"
20 #include "LengthCombo.h"
21 #include "qt_helpers.h"
22 #include "lengthcommon.h"
23 #include "LyXRC.h" // to set the default length values
24 #include "Validator.h"
26 #include "insets/InsetBox.h"
28 #include "support/lstrings.h"
30 #include <QPushButton>
32 #include <QCloseEvent>
42 void box_gui_tokens(vector<string> & ids, vector<docstring> & gui_names)
44 char const * const ids_[] = {
45 "Frameless", "Boxed", "ovalbox",
46 "Ovalbox", "Shadowbox", "Doublebox"};
47 size_t const ids_size = sizeof(ids_) / sizeof(char *);
48 ids = vector<string>(ids_, ids_ + ids_size);
50 gui_names.push_back(_("No frame drawn"));
51 gui_names.push_back(_("Rectangular box"));
52 gui_names.push_back(_("Oval box, thin"));
53 gui_names.push_back(_("Oval box, thick"));
54 gui_names.push_back(_("Shadow box"));
55 gui_names.push_back(_("Double box"));
59 void box_gui_tokens_special_length(vector<string> & ids,
60 vector<docstring> & gui_names)
62 char const * const ids_[] = {
63 "none", "height", "depth",
64 "totalheight", "width"};
65 size_t const ids_size = sizeof(ids_) / sizeof(char *);
66 ids = vector<string>(ids_, ids_ + ids_size);
68 gui_names.push_back(_("None"));
69 gui_names.push_back(_("Height"));
70 gui_names.push_back(_("Depth"));
71 gui_names.push_back(_("Total Height"));
72 gui_names.push_back(_("Width"));
76 GuiBox::GuiBox(LyXView & lv)
77 : GuiDialog(lv, "box"), params_("")
80 setViewTitle(_("Box Settings"));
82 // fill the box type choice
83 box_gui_tokens(ids_, gui_names_);
84 for (unsigned int i = 0; i < gui_names_.size(); ++i)
85 typeCO->addItem(toqstr(gui_names_[i]));
87 // add the special units to the height choice
88 // width needs different handling
89 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
90 for (unsigned int i = 1; i < gui_names_spec_.size(); ++i)
91 heightUnitsLC->addItem(toqstr(gui_names_spec_[i]));
93 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
94 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
95 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
96 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
98 connect(widthED, SIGNAL(textChanged(QString)),
99 this, SLOT(change_adaptor()));
100 connect(widthUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
101 this, SLOT(change_adaptor()));
102 connect(valignCO, SIGNAL(highlighted(QString)),
103 this, SLOT(change_adaptor()));
104 connect(heightCB, SIGNAL(stateChanged(int)),
105 this, SLOT(change_adaptor()));
106 connect(heightED, SIGNAL(textChanged(const QString &)),
107 this, SLOT(change_adaptor()));
108 connect(heightUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT) ),
109 this, SLOT(change_adaptor()));
110 connect(restorePB, SIGNAL(clicked()), this, SLOT(restoreClicked()));
111 connect(typeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
112 connect(typeCO, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
113 connect(halignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
114 connect(ialignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
115 connect(innerBoxCO, SIGNAL(activated(const QString&)),
116 this, SLOT(innerBoxChanged(const QString &)));
117 connect(innerBoxCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
119 heightED->setValidator(unsignedLengthValidator(heightED));
120 widthED->setValidator(unsignedLengthValidator(widthED));
122 bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
124 bc().addReadOnly(typeCO);
125 bc().addReadOnly(innerBoxCO);
126 bc().addReadOnly(valignCO);
127 bc().addReadOnly(ialignCO);
128 bc().addReadOnly(halignCO);
129 bc().addReadOnly(widthED);
130 bc().addReadOnly(widthUnitsLC);
131 bc().addReadOnly(heightCB);
132 bc().addReadOnly(heightED);
133 bc().addReadOnly(heightUnitsLC);
135 bc().setRestore(restorePB);
137 bc().setApply(applyPB);
138 bc().setCancel(closePB);
140 // initialize the length validator
141 bc().addCheckedLineEdit(widthED, widthLA);
142 bc().addCheckedLineEdit(heightED, heightCB);
146 void GuiBox::closeEvent(QCloseEvent * e)
153 void GuiBox::change_adaptor()
159 void GuiBox::innerBoxChanged(const QString & str)
161 bool const ibox = (str != qt_("None"));
162 valignCO->setEnabled(ibox);
163 ialignCO->setEnabled(ibox);
164 halignCO->setEnabled(!ibox);
165 heightCB->setEnabled(ibox);
166 if (heightCB->checkState() == Qt::Checked && ibox) {
167 heightED->setEnabled(true);
168 heightUnitsLC->setEnabled(true);
174 void GuiBox::typeChanged(int index)
176 bool const frameless = (index == 0);
178 valignCO->setEnabled(true);
179 ialignCO->setEnabled(true);
180 halignCO->setEnabled(false);
181 heightCB->setEnabled(true);
182 heightED->setEnabled(true);
183 heightUnitsLC->setEnabled(true);
186 int itype = innerBoxCO->currentIndex();
187 setInnerType(frameless, itype);
191 void GuiBox::restoreClicked()
193 setInnerType(true, 2);
194 widthED->setText("100");
195 widthUnitsLC->setCurrentItem(Length::PCW);
196 heightCB->setCheckState(Qt::Checked);
197 heightED->setText("1");
198 for (int j = 0; j < heightUnitsLC->count(); j++) {
199 if (heightUnitsLC->itemText(j) == qt_("Total Height"))
200 heightUnitsLC->setCurrentItem(j);
205 void GuiBox::updateContents()
207 string type = params_.type;
208 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
210 typeCO->setCurrentIndex(i);
214 unsigned int inner_type = 2;
215 if (!params_.inner_box)
218 if (params_.use_parbox)
221 bool frameless = (params_.type == "Frameless");
222 setInnerType(frameless, inner_type);
224 char c = params_.pos;
225 valignCO->setCurrentIndex(string("tcb").find(c, 0));
226 c = params_.inner_pos;
227 ialignCO->setCurrentIndex(string("tcbs").find(c, 0));
229 halignCO->setCurrentIndex(string("lcrs").find(c, 0));
231 bool ibox = params_.inner_box;
232 valignCO->setEnabled(ibox);
233 ialignCO->setEnabled(ibox);
234 halignCO->setEnabled(!ibox);
237 Length::UNIT default_unit =
238 (lyxrc.default_papersize > 3) ? Length::CM : Length::IN;
240 lengthToWidgets(widthED, widthUnitsLC,
241 (params_.width).asString(), default_unit);
243 string const special = params_.special;
244 if (!special.empty() && special != "none") {
246 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
247 if (special == ids_spec_[i])
248 spc = toqstr(gui_names_spec_[i].c_str());
250 for (int j = 0; j < widthUnitsLC->count(); j++) {
251 if (widthUnitsLC->itemText(j) == spc)
252 widthUnitsLC->setCurrentIndex(j);
256 lengthToWidgets(heightED, heightUnitsLC,
257 (params_.height).asString(), default_unit);
259 string const height_special = params_.height_special;
260 if (!height_special.empty() && height_special != "none") {
262 for (unsigned int i = 0; i != gui_names_spec_.size(); i++) {
263 if (height_special == ids_spec_[i])
264 hspc = toqstr(gui_names_spec_[i].c_str());
266 for (int j = 0; j != heightUnitsLC->count(); j++) {
267 if (heightUnitsLC->itemText(j) == hspc)
268 heightUnitsLC->setCurrentIndex(j);
271 // set no optional height when the value is the default "1\height"
272 // (special units like \height are handled as "in",
273 if (height_special == "totalheight" &&
274 params_.height == Length("1in"))
275 heightCB->setCheckState(Qt::Unchecked);
277 heightCB->setCheckState(Qt::Checked);
279 heightCB->setEnabled(ibox);
283 void GuiBox::applyView()
285 params_.type = ids_[typeCO->currentIndex()];
287 params_.inner_box = innerBoxCO->currentText() != qt_("None");
288 params_.use_parbox = innerBoxCO->currentText() == qt_("Parbox");
290 params_.pos = "tcb"[valignCO->currentIndex()];
291 params_.inner_pos = "tcbs"[ialignCO->currentIndex()];
292 params_.hor_pos = "lcrs"[halignCO->currentIndex()];
296 QString special = widthUnitsLC->currentText();
297 QString value = widthED->text();
298 if (special == qt_("Height")) {
301 } else if (special == qt_("Depth")) {
304 } else if (special == qt_("Total Height")) {
307 } else if (special == qt_("Width")) {
311 // the user might insert a non-special value in the line edit
312 if (isValidLength(fromqstr(value))) {
316 params_.special = ids_spec_[i];
320 width = fromqstr(value);
321 // beware: bogosity! the unit is simply ignored in this case
324 width = widgetsToLength(widthED, widthUnitsLC);
327 params_.width = Length(width);
331 special = heightUnitsLC->currentText();
332 value = heightED->text();
333 if (special == qt_("Height")) {
336 } else if (special == qt_("Depth")) {
339 } else if (special == qt_("Total Height")) {
342 } else if (special == qt_("Width")) {
346 // the user might insert a non-special value in the line edit
347 if (isValidLength(fromqstr(value))) {
351 params_.height_special = ids_spec_[i];
354 if (spec && !isValidLength(fromqstr(heightED->text()))) {
355 height = fromqstr(value);
356 // beware: bogosity! the unit is simply ignored in this case
359 height = widgetsToLength(heightED, heightUnitsLC);
361 // the height parameter is omitted in InsetBox.cpp when the value
362 // is "1in" and "Total Height" is used as unit.
363 // 1in + "Total Height" means "1\height" which is the LaTeX default when
364 // no height is given
365 if (heightCB->checkState() == Qt::Checked)
366 params_.height = Length(height);
368 params_.height = Length("1in");
369 params_.height_special = ids_spec_[3];
374 void GuiBox::setSpecial(bool ibox)
376 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
377 // check if the widget contains the special units
378 int count = widthUnitsLC->count();
379 bool has_special = false;
380 for (int i = 0; i < count; i++)
381 if (widthUnitsLC->itemText(i).contains(qt_("Total Height")) > 0)
383 // insert 'em if needed...
384 if (!ibox && !has_special) {
385 for (unsigned int i = 1; i < gui_names_spec_.size(); i++)
386 widthUnitsLC->addItem(toqstr(gui_names_spec_[i]));
387 // ... or remove 'em if needed
388 } else if (ibox && has_special) {
389 widthUnitsLC->clear();
390 for (int i = 0; i < num_units; i++)
391 widthUnitsLC->addItem(qt_(unit_name_gui[i]));
396 void GuiBox::setInnerType(bool frameless, int i)
398 // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
399 // we have to remove "none" then and adjust the combo
402 innerBoxCO->addItem(qt_("Parbox"));
403 innerBoxCO->addItem(qt_("Minipage"));
405 innerBoxCO->setCurrentIndex(i - 1);
407 innerBoxCO->setCurrentIndex(i);
409 if (innerBoxCO->count() == 2)
412 innerBoxCO->addItem(qt_("None"));
413 innerBoxCO->addItem(qt_("Parbox"));
414 innerBoxCO->addItem(qt_("Minipage"));
415 innerBoxCO->setCurrentIndex(i);
419 bool GuiBox::initialiseParams(string const & data)
421 InsetBoxMailer::string2params(data, params_);
427 void GuiBox::clearParams()
429 params_ = InsetBoxParams("");
433 void GuiBox::dispatchParams()
435 dispatch(FuncRequest(getLfun(), InsetBoxMailer::params2string(params_)));
439 Dialog * createGuiBox(LyXView & lv) { return new GuiBox(lv); }
442 } // namespace frontend
446 #include "GuiBox_moc.cpp"