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"), Controller(this), params_("")
80 setViewTitle(_("Box Settings"));
81 setController(this, false);
83 // fill the box type choice
84 box_gui_tokens(ids_, gui_names_);
85 for (unsigned int i = 0; i < gui_names_.size(); ++i)
86 typeCO->addItem(toqstr(gui_names_[i]));
88 // add the special units to the height choice
89 // width needs different handling
90 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
91 for (unsigned int i = 1; i < gui_names_spec_.size(); ++i)
92 heightUnitsLC->addItem(toqstr(gui_names_spec_[i]));
94 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
95 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
96 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
97 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
99 connect(widthED, SIGNAL(textChanged(QString)),
100 this, SLOT(change_adaptor()));
101 connect(widthUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
102 this, SLOT(change_adaptor()));
103 connect(valignCO, SIGNAL(highlighted(QString)),
104 this, SLOT(change_adaptor()));
105 connect(heightCB, SIGNAL(stateChanged(int)),
106 this, SLOT(change_adaptor()));
107 connect(heightED, SIGNAL(textChanged(const QString &)),
108 this, SLOT(change_adaptor()));
109 connect(heightUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT) ),
110 this, SLOT(change_adaptor()));
111 connect(restorePB, SIGNAL(clicked()), this, SLOT(restoreClicked()));
112 connect(typeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
113 connect(typeCO, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
114 connect(halignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
115 connect(ialignCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
116 connect(innerBoxCO, SIGNAL(activated(const QString&)),
117 this, SLOT(innerBoxChanged(const QString &)));
118 connect(innerBoxCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
120 heightED->setValidator(unsignedLengthValidator(heightED));
121 widthED->setValidator(unsignedLengthValidator(widthED));
123 bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
125 bc().addReadOnly(typeCO);
126 bc().addReadOnly(innerBoxCO);
127 bc().addReadOnly(valignCO);
128 bc().addReadOnly(ialignCO);
129 bc().addReadOnly(halignCO);
130 bc().addReadOnly(widthED);
131 bc().addReadOnly(widthUnitsLC);
132 bc().addReadOnly(heightCB);
133 bc().addReadOnly(heightED);
134 bc().addReadOnly(heightUnitsLC);
136 bc().setRestore(restorePB);
138 bc().setApply(applyPB);
139 bc().setCancel(closePB);
141 // initialize the length validator
142 bc().addCheckedLineEdit(widthED, widthLA);
143 bc().addCheckedLineEdit(heightED, heightCB);
147 void GuiBox::closeEvent(QCloseEvent * e)
154 void GuiBox::change_adaptor()
160 void GuiBox::innerBoxChanged(const QString & str)
162 bool const ibox = (str != qt_("None"));
163 valignCO->setEnabled(ibox);
164 ialignCO->setEnabled(ibox);
165 halignCO->setEnabled(!ibox);
166 heightCB->setEnabled(ibox);
167 if (heightCB->checkState() == Qt::Checked && ibox) {
168 heightED->setEnabled(true);
169 heightUnitsLC->setEnabled(true);
175 void GuiBox::typeChanged(int index)
177 bool const frameless = (index == 0);
179 valignCO->setEnabled(true);
180 ialignCO->setEnabled(true);
181 halignCO->setEnabled(false);
182 heightCB->setEnabled(true);
183 heightED->setEnabled(true);
184 heightUnitsLC->setEnabled(true);
187 int itype = innerBoxCO->currentIndex();
188 setInnerType(frameless, itype);
192 void GuiBox::restoreClicked()
194 setInnerType(true, 2);
195 widthED->setText("100");
196 widthUnitsLC->setCurrentItem(Length::PCW);
197 heightCB->setCheckState(Qt::Checked);
198 heightED->setText("1");
199 for (int j = 0; j < heightUnitsLC->count(); j++) {
200 if (heightUnitsLC->itemText(j) == qt_("Total Height"))
201 heightUnitsLC->setCurrentItem(j);
206 void GuiBox::updateContents()
208 string type = params_.type;
209 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
211 typeCO->setCurrentIndex(i);
215 unsigned int inner_type = 2;
216 if (!params_.inner_box)
219 if (params_.use_parbox)
222 bool frameless = (params_.type == "Frameless");
223 setInnerType(frameless, inner_type);
225 char c = params_.pos;
226 valignCO->setCurrentIndex(string("tcb").find(c, 0));
227 c = params_.inner_pos;
228 ialignCO->setCurrentIndex(string("tcbs").find(c, 0));
230 halignCO->setCurrentIndex(string("lcrs").find(c, 0));
232 bool ibox = params_.inner_box;
233 valignCO->setEnabled(ibox);
234 ialignCO->setEnabled(ibox);
235 halignCO->setEnabled(!ibox);
238 Length::UNIT default_unit =
239 (lyxrc.default_papersize > 3) ? Length::CM : Length::IN;
241 lengthToWidgets(widthED, widthUnitsLC,
242 (params_.width).asString(), default_unit);
244 string const special = params_.special;
245 if (!special.empty() && special != "none") {
247 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
248 if (special == ids_spec_[i])
249 spc = toqstr(gui_names_spec_[i].c_str());
251 for (int j = 0; j < widthUnitsLC->count(); j++) {
252 if (widthUnitsLC->itemText(j) == spc)
253 widthUnitsLC->setCurrentIndex(j);
257 lengthToWidgets(heightED, heightUnitsLC,
258 (params_.height).asString(), default_unit);
260 string const height_special = params_.height_special;
261 if (!height_special.empty() && height_special != "none") {
263 for (unsigned int i = 0; i != gui_names_spec_.size(); i++) {
264 if (height_special == ids_spec_[i])
265 hspc = toqstr(gui_names_spec_[i].c_str());
267 for (int j = 0; j != heightUnitsLC->count(); j++) {
268 if (heightUnitsLC->itemText(j) == hspc)
269 heightUnitsLC->setCurrentIndex(j);
272 // set no optional height when the value is the default "1\height"
273 // (special units like \height are handled as "in",
274 if (height_special == "totalheight" &&
275 params_.height == Length("1in"))
276 heightCB->setCheckState(Qt::Unchecked);
278 heightCB->setCheckState(Qt::Checked);
280 heightCB->setEnabled(ibox);
284 void GuiBox::applyView()
286 params_.type = ids_[typeCO->currentIndex()];
288 params_.inner_box = innerBoxCO->currentText() != qt_("None");
289 params_.use_parbox = innerBoxCO->currentText() == qt_("Parbox");
291 params_.pos = "tcb"[valignCO->currentIndex()];
292 params_.inner_pos = "tcbs"[ialignCO->currentIndex()];
293 params_.hor_pos = "lcrs"[halignCO->currentIndex()];
297 QString special = widthUnitsLC->currentText();
298 QString value = widthED->text();
299 if (special == qt_("Height")) {
302 } else if (special == qt_("Depth")) {
305 } else if (special == qt_("Total Height")) {
308 } else if (special == qt_("Width")) {
312 // the user might insert a non-special value in the line edit
313 if (isValidLength(fromqstr(value))) {
317 params_.special = ids_spec_[i];
321 width = fromqstr(value);
322 // beware: bogosity! the unit is simply ignored in this case
325 width = widgetsToLength(widthED, widthUnitsLC);
328 params_.width = Length(width);
332 special = heightUnitsLC->currentText();
333 value = heightED->text();
334 if (special == qt_("Height")) {
337 } else if (special == qt_("Depth")) {
340 } else if (special == qt_("Total Height")) {
343 } else if (special == qt_("Width")) {
347 // the user might insert a non-special value in the line edit
348 if (isValidLength(fromqstr(value))) {
352 params_.height_special = ids_spec_[i];
355 if (spec && !isValidLength(fromqstr(heightED->text()))) {
356 height = fromqstr(value);
357 // beware: bogosity! the unit is simply ignored in this case
360 height = widgetsToLength(heightED, heightUnitsLC);
362 // the height parameter is omitted in InsetBox.cpp when the value
363 // is "1in" and "Total Height" is used as unit.
364 // 1in + "Total Height" means "1\height" which is the LaTeX default when
365 // no height is given
366 if (heightCB->checkState() == Qt::Checked)
367 params_.height = Length(height);
369 params_.height = Length("1in");
370 params_.height_special = ids_spec_[3];
375 void GuiBox::setSpecial(bool ibox)
377 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
378 // check if the widget contains the special units
379 int count = widthUnitsLC->count();
380 bool has_special = false;
381 for (int i = 0; i < count; i++)
382 if (widthUnitsLC->itemText(i).contains(qt_("Total Height")) > 0)
384 // insert 'em if needed...
385 if (!ibox && !has_special) {
386 for (unsigned int i = 1; i < gui_names_spec_.size(); i++)
387 widthUnitsLC->addItem(toqstr(gui_names_spec_[i]));
388 // ... or remove 'em if needed
389 } else if (ibox && has_special) {
390 widthUnitsLC->clear();
391 for (int i = 0; i < num_units; i++)
392 widthUnitsLC->addItem(qt_(unit_name_gui[i]));
397 void GuiBox::setInnerType(bool frameless, int i)
399 // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
400 // we have to remove "none" then and adjust the combo
403 innerBoxCO->addItem(qt_("Parbox"));
404 innerBoxCO->addItem(qt_("Minipage"));
406 innerBoxCO->setCurrentIndex(i - 1);
408 innerBoxCO->setCurrentIndex(i);
410 if (innerBoxCO->count() == 2)
413 innerBoxCO->addItem(qt_("None"));
414 innerBoxCO->addItem(qt_("Parbox"));
415 innerBoxCO->addItem(qt_("Minipage"));
416 innerBoxCO->setCurrentIndex(i);
420 bool GuiBox::initialiseParams(string const & data)
422 InsetBoxMailer::string2params(data, params_);
428 void GuiBox::clearParams()
430 params_ = InsetBoxParams("");
434 void GuiBox::dispatchParams()
436 dispatch(FuncRequest(getLfun(), InsetBoxMailer::params2string(params_)));
440 Dialog * createGuiBox(LyXView & lv) { return new GuiBox(lv); }
443 } // namespace frontend
447 #include "GuiBox_moc.cpp"