3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Jürgen Spitzmüller
11 * Full author contact details are available in file CREDITS.
16 #include "GuiTabular.h"
18 #include "GuiApplication.h"
19 #include "GuiSetBorder.h"
21 #include "LengthCombo.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
25 #include "BufferView.h"
27 #include "FuncRequest.h"
28 #include "FuncStatus.h"
32 #include "insets/InsetTabular.h"
34 #include "support/convert.h"
35 #include "support/debug.h"
38 #include <QPushButton>
39 #include <QRadioButton>
47 GuiTabular::GuiTabular(QWidget * parent)
48 : InsetParamsWidget(parent), firstheader_suppressable_(false),
49 lastfooter_suppressable_(false)
54 tabularWidthED->setValidator(unsignedLengthValidator(tabularWidthED));
55 columnWidthED->setValidator(unsignedLengthValidator(columnWidthED));
56 multirowOffsetED->setValidator(new LengthValidator(multirowOffsetED));
57 topspaceED->setValidator(new LengthValidator(topspaceED));
58 bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
59 interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
61 tabularWidthUnitLC->setCurrentItem(Length::defaultUnit());
62 columnWidthUnitLC->setCurrentItem(Length::defaultUnit());
63 multirowOffsetUnitLC->setCurrentItem(Length::defaultUnit());
64 topspaceUnitLC->setCurrentItem(Length::defaultUnit());
65 bottomspaceUnitLC->setCurrentItem(Length::defaultUnit());
66 interlinespaceUnitLC->setCurrentItem(Length::defaultUnit());
68 connect(topspaceED, SIGNAL(textEdited(const QString &)),
69 this, SLOT(checkEnabled()));
70 connect(topspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
71 this, SLOT(checkEnabled()));
72 connect(bottomspaceED, SIGNAL(textEdited(const QString &)),
73 this, SLOT(checkEnabled()));
74 connect(bottomspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
75 this, SLOT(checkEnabled()));
76 connect(interlinespaceED, SIGNAL(textEdited(const QString &)),
77 this, SLOT(checkEnabled()));
78 connect(interlinespaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
79 this, SLOT(checkEnabled()));
80 connect(booktabsRB, SIGNAL(clicked(bool)),
81 this, SLOT(checkEnabled()));
82 connect(borderDefaultRB, SIGNAL(clicked(bool)),
83 this, SLOT(checkEnabled()));
84 connect(borderSetPB, SIGNAL(clicked()),
85 this, SLOT(borderSet_clicked()));
86 connect(borderUnsetPB, SIGNAL(clicked()),
87 this, SLOT(borderUnset_clicked()));
88 connect(hAlignCO, SIGNAL(activated(int)),
89 this, SLOT(checkEnabled()));
90 connect(vAlignCO, SIGNAL(activated(int)),
91 this, SLOT(checkEnabled()));
92 connect(multicolumnCB, SIGNAL(clicked()),
93 this, SLOT(checkEnabled()));
94 connect(multirowCB, SIGNAL(clicked()),
95 this, SLOT(checkEnabled()));
96 connect(multirowOffsetED, SIGNAL(textEdited(const QString &)),
97 this, SLOT(checkEnabled()));
98 connect(multirowOffsetUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
99 this, SLOT(checkEnabled()));
100 connect(newpageCB, SIGNAL(clicked()),
101 this, SLOT(checkEnabled()));
102 connect(headerStatusCB, SIGNAL(clicked()),
103 this, SLOT(checkEnabled()));
104 connect(headerBorderAboveCB, SIGNAL(clicked()),
105 this, SLOT(checkEnabled()));
106 connect(headerBorderBelowCB, SIGNAL(clicked()),
107 this, SLOT(checkEnabled()));
108 connect(firstheaderStatusCB, SIGNAL(clicked()),
109 this, SLOT(checkEnabled()));
110 connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
111 this, SLOT(checkEnabled()));
112 connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
113 this, SLOT(checkEnabled()));
114 connect(firstheaderNoContentsCB, SIGNAL(clicked()),
115 this, SLOT(checkEnabled()));
116 connect(footerStatusCB, SIGNAL(clicked()),
117 this, SLOT(checkEnabled()));
118 connect(footerBorderAboveCB, SIGNAL(clicked()),
119 this, SLOT(checkEnabled()));
120 connect(footerBorderBelowCB, SIGNAL(clicked()),
121 this, SLOT(checkEnabled()));
122 connect(lastfooterStatusCB, SIGNAL(clicked()),
123 this, SLOT(checkEnabled()));
124 connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
125 this, SLOT(checkEnabled()));
126 connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
127 this, SLOT(checkEnabled()));
128 connect(lastfooterNoContentsCB, SIGNAL(clicked()),
129 this, SLOT(checkEnabled()));
130 connect(captionStatusCB, SIGNAL(clicked()),
131 this, SLOT(checkEnabled()));
132 connect(specialAlignmentED, SIGNAL(textEdited(const QString &)),
133 this, SLOT(checkEnabled()));
134 connect(columnWidthED, SIGNAL(textEdited(const QString &)),
135 this, SLOT(checkEnabled()));
136 connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
137 this, SLOT(checkEnabled()));
138 connect(borders, SIGNAL(topSet(bool)),
139 this, SLOT(checkEnabled()));
140 connect(borders, SIGNAL(bottomSet(bool)),
141 this, SLOT(checkEnabled()));
142 connect(borders, SIGNAL(rightSet(bool)),
143 this, SLOT(checkEnabled()));
144 connect(borders, SIGNAL(leftSet(bool)),
145 this, SLOT(checkEnabled()));
146 connect(rotateTabularCB, SIGNAL(clicked()),
147 this, SLOT(checkEnabled()));
148 connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
149 this, SLOT(checkEnabled()));
150 connect(rotateCellCB, SIGNAL(clicked()),
151 this, SLOT(checkEnabled()));
152 connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
153 this, SLOT(checkEnabled()));
154 connect(TableAlignCO, SIGNAL(activated(int)),
155 this, SLOT(checkEnabled()));
156 connect(longTabularCB, SIGNAL(clicked()),
157 this, SLOT(checkEnabled()));
158 connect(leftRB, SIGNAL(clicked()),
159 this, SLOT(checkEnabled()));
160 connect(centerRB, SIGNAL(clicked()),
161 this, SLOT(checkEnabled()));
162 connect(rightRB, SIGNAL(clicked()),
163 this, SLOT(checkEnabled()));
164 connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
165 this, SLOT(checkEnabled()));
167 decimalPointED->setInputMask("X; ");
168 decimalPointED->setMaxLength(1);
170 // initialize the length validator
171 addCheckedWidget(columnWidthED, columnWidthLA);
172 addCheckedWidget(multirowOffsetED, multirowOffsetLA);
173 addCheckedWidget(topspaceED, topspaceLA);
174 addCheckedWidget(bottomspaceED, bottomspaceLA);
175 addCheckedWidget(interlinespaceED, interlinespaceLA);
176 addCheckedWidget(tabularWidthED, tabularWidthLA);
180 void GuiTabular::on_topspaceCO_activated(int index)
182 bool const enable = (index == 2);
183 topspaceED->setEnabled(enable);
184 topspaceUnitLC->setEnabled(enable);
188 void GuiTabular::on_bottomspaceCO_activated(int index)
190 bool const enable = (index == 2);
191 bottomspaceED->setEnabled(enable);
192 bottomspaceUnitLC->setEnabled(enable);
196 void GuiTabular::on_interlinespaceCO_activated(int index)
198 bool const enable = (index == 2);
199 interlinespaceED->setEnabled(enable);
200 interlinespaceUnitLC->setEnabled(enable);
204 void GuiTabular::on_columnTypeCO_activated(int index)
208 columnWidthED->setFocus();
212 void GuiTabular::enableWidgets() const
214 // if there is a LaTeX argument, the width and alignment will be overwritten
215 // therefore disable them in this case
216 bool const fixed = specialAlignmentED->text().isEmpty()
217 && columnTypeCO->currentIndex() == 2;
218 columnWidthED->setEnabled(fixed);
219 columnWidthUnitLC->setEnabled(fixed);
220 // if the column has a width, multirows are always left-aligned
221 // therefore disable hAlignCB in this case
222 hAlignCO->setEnabled(!(multirowCB->isChecked()
223 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
224 && specialAlignmentED->text().isEmpty());
225 // decimal alignment is only possible for non-multicol and non-multirow cells
226 if ((multicolumnCB->isChecked() || multirowCB->isChecked() || columnTypeCO->currentIndex() == 1)
227 && hAlignCO->findData(toqstr("decimal")))
228 hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
229 else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
230 && hAlignCO->findData(toqstr("decimal")) == -1)
231 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
233 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
234 decimalPointED->setEnabled(dalign);
235 decimalLA->setEnabled(dalign);
237 bool const setwidth = TableAlignCO->currentText() == qt_("Middle");
238 tabularWidthLA->setEnabled(setwidth);
239 tabularWidthED->setEnabled(setwidth);
240 tabularWidthUnitLC->setEnabled(setwidth);
242 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked()
243 && !longTabularCB->isChecked());
244 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
246 bool const enable_valign =
247 !multirowCB->isChecked()
248 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
249 && specialAlignmentED->text().isEmpty();
250 vAlignCO->setEnabled(enable_valign);
251 vAlignLA->setEnabled(enable_valign);
253 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
254 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
255 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
256 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
257 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
258 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
259 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
261 // setting as longtable is not allowed when table is inside a float
262 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
263 longTabularCB->setEnabled(funcEnabled(Tabular::SET_LONGTABULAR));
264 bool const longtabular = longTabularCB->isChecked();
265 longtableGB->setEnabled(true);
266 newpageCB->setEnabled(longtabular);
267 alignmentGB->setEnabled(longtabular);
268 // longtables and tabular* cannot have a vertical alignment
269 TableAlignLA->setDisabled(is_tabular_star || longtabular);
270 TableAlignCO->setDisabled(is_tabular_star || longtabular);
271 // longtable cannot be rotated with rotating package, only
272 // with [pdf]lscape, which only supports 90 deg.
273 rotateTabularAngleSB->setDisabled(longtabular);
275 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
276 // depending on the cursor position is very very unintuitive...
277 // We need some edit boxes to show which rows are header/footer/etc
278 // without having to move the cursor first.
279 headerStatusCB->setEnabled(longtabular
280 && (headerStatusCB->isChecked() ?
281 funcEnabled(Tabular::UNSET_LTHEAD) :
282 funcEnabled(Tabular::SET_LTHEAD)));
283 headerBorderAboveCB->setEnabled(longtabular
284 && headerStatusCB->isChecked());
285 headerBorderBelowCB->setEnabled(longtabular
286 && headerStatusCB->isChecked());
288 // first header can only be suppressed when there is a header
289 // firstheader_suppressable_ is set in paramsToDialog
290 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
291 // check if setting a first header is allowed
292 // additionally check firstheaderNoContentsCB because when this is
293 // the case a first header makes no sense
294 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
295 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
296 funcEnabled(Tabular::SET_LTFIRSTHEAD))
297 && longtabular && !firstheaderNoContentsCB->isChecked());
298 firstheaderBorderAboveCB->setEnabled(longtabular
299 && firstheaderStatusCB->isChecked());
300 firstheaderBorderBelowCB->setEnabled(longtabular
301 && firstheaderStatusCB->isChecked());
303 footerStatusCB->setEnabled(longtabular
304 && (footerStatusCB->isChecked() ?
305 funcEnabled(Tabular::UNSET_LTFOOT) :
306 funcEnabled(Tabular::SET_LTFOOT)));
307 footerBorderAboveCB->setEnabled(longtabular
308 && footerBorderAboveCB->isChecked());
309 footerBorderBelowCB->setEnabled(longtabular
310 && footerBorderAboveCB->isChecked());
312 // last footer can only be suppressed when there is a footer
313 // lastfooter_suppressable_ is set in paramsToDialog
314 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
315 // check if setting a last footer is allowed
316 // additionally check lastfooterNoContentsCB because when this is
317 // the case a last footer makes no sense
318 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
319 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
320 funcEnabled(Tabular::SET_LTLASTFOOT))
321 && longtabular && !lastfooterNoContentsCB->isChecked());
322 lastfooterBorderAboveCB->setEnabled(longtabular
323 && lastfooterBorderAboveCB->isChecked());
324 lastfooterBorderBelowCB->setEnabled(longtabular
325 && lastfooterBorderAboveCB->isChecked());
327 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
330 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
331 && !dalign && !multirowCB->isChecked());
332 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
333 && !dalign && !multicolumnCB->isChecked());
334 bool const enable_mr = multirowCB->isChecked();
335 multirowOffsetLA->setEnabled(enable_mr);
336 multirowOffsetED->setEnabled(enable_mr);
337 multirowOffsetUnitLC->setEnabled(enable_mr);
339 // Vertical lines cannot be set in formal tables
340 borders->setLeftEnabled(!booktabsRB->isChecked());
341 borders->setRightEnabled(!booktabsRB->isChecked());
345 void GuiTabular::checkEnabled()
352 void GuiTabular::borderSet_clicked()
354 borders->setTop(true);
355 borders->setBottom(true);
356 borders->setLeft(true);
357 borders->setRight(true);
358 // repaint the setborder widget
364 void GuiTabular::borderUnset_clicked()
366 borders->setTop(false);
367 borders->setBottom(false);
368 borders->setLeft(false);
369 borders->setRight(false);
370 // repaint the setborder widget
376 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
379 param_str += featureAsString(f) + ' ' + arg;
383 void GuiTabular::setHAlign(string & param_str) const
385 Tabular::Feature num = Tabular::ALIGN_LEFT;
386 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
388 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
389 if (align == "left") {
390 num = Tabular::ALIGN_LEFT;
391 multi_num = Tabular::M_ALIGN_LEFT;
392 } else if (align == "center") {
393 num = Tabular::ALIGN_CENTER;
394 multi_num = Tabular::M_ALIGN_CENTER;
395 } else if (align == "right") {
396 num = Tabular::ALIGN_RIGHT;
397 multi_num = Tabular::M_ALIGN_RIGHT;
398 } else if (align == "justified") {
399 num = Tabular::ALIGN_BLOCK;
400 //multi_num: no equivalent
401 } else if (align == "decimal") {
402 num = Tabular::ALIGN_DECIMAL;
403 //multi_num: no equivalent
406 if (multicolumnCB->isChecked())
407 setParam(param_str, multi_num);
409 setParam(param_str, num);
413 void GuiTabular::setVAlign(string & param_str) const
415 int const align = vAlignCO->currentIndex();
416 enum VALIGN { TOP, MIDDLE, BOTTOM };
420 case 0: v = TOP; break;
421 case 1: v = MIDDLE; break;
422 case 2: v = BOTTOM; break;
425 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
426 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
430 num = Tabular::VALIGN_TOP;
431 multi_num = Tabular::M_VALIGN_TOP;
434 num = Tabular::VALIGN_MIDDLE;
435 multi_num = Tabular::M_VALIGN_MIDDLE;
438 num = Tabular::VALIGN_BOTTOM;
439 multi_num = Tabular::M_VALIGN_BOTTOM;
442 if (multicolumnCB->isChecked() || multirowCB->isChecked())
443 setParam(param_str, multi_num);
445 setParam(param_str, num);
449 void GuiTabular::setTableAlignment(string & param_str) const
451 int const align = TableAlignCO->currentIndex();
453 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
455 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
457 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
463 docstring GuiTabular::dialogToParams() const
465 string param_str = "tabular";
468 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
469 if (tabwidth.empty())
471 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
473 // apply the fixed width values
474 // this must be done before applying the column alignment
475 // because its value influences the alignment of multirow cells
476 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
477 if (width.empty() || columnTypeCO->currentIndex() != 2)
479 if (multicolumnCB->isChecked())
480 setParam(param_str, Tabular::SET_MPWIDTH, width);
482 setParam(param_str, Tabular::SET_PWIDTH, width);
484 bool const varwidth = specialAlignmentED->text().isEmpty()
485 && columnTypeCO->currentIndex() == 1;
487 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "on");
489 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "off");
491 // apply the column alignment
492 // multirows inherit the alignment from the column; if a column width
493 // is set, multirows are always left-aligned so that in this case
494 // its alignment must not be applied (see bug #8084)
495 if (!(multirowCB->isChecked() && width != "0pt"))
496 setHAlign(param_str);
498 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
499 string decimal_point = fromqstr(decimalPointED->text());
500 if (decimal_point.empty())
501 decimal_point = lyxrc.default_decimal_point;
502 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
504 setVAlign(param_str);
505 setTableAlignment(param_str);
507 if (booktabsRB->isChecked())
508 setParam(param_str, Tabular::SET_BOOKTABS);
510 setParam(param_str, Tabular::UNSET_BOOKTABS);
513 switch (topspaceCO->currentIndex()) {
515 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
518 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
521 if (!topspaceED->text().isEmpty())
522 setParam(param_str, Tabular::SET_TOP_SPACE,
523 widgetsToLength(topspaceED, topspaceUnitLC));
528 switch (bottomspaceCO->currentIndex()) {
530 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
533 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
536 if (!bottomspaceED->text().isEmpty())
537 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
538 widgetsToLength(bottomspaceED,
544 switch (interlinespaceCO->currentIndex()) {
546 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
549 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
552 if (!interlinespaceED->text().isEmpty())
553 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
554 widgetsToLength(interlinespaceED,
555 interlinespaceUnitLC));
560 if (borders->getTop() && borders->getBottom() && borders->getLeft()
561 && borders->getRight())
562 setParam(param_str, Tabular::SET_ALL_LINES);
563 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
564 && !borders->getRight())
565 setParam(param_str, Tabular::UNSET_ALL_LINES);
567 setParam(param_str, Tabular::SET_LINE_LEFT,
568 borders->getLeft() ? "true" : "false");
569 setParam(param_str, Tabular::SET_LINE_RIGHT,
570 borders->getRight() ? "true" : "false");
571 setParam(param_str, Tabular::SET_LINE_TOP,
572 borders->getTop() ? "true" : "false");
573 setParam(param_str, Tabular::SET_LINE_BOTTOM,
574 borders->getBottom() ? "true" : "false");
577 // apply the special alignment
578 string special = fromqstr(specialAlignmentED->text());
581 if (multicolumnCB->isChecked())
582 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
584 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
587 if (multicolumnCB->isChecked())
588 setParam(param_str, Tabular::SET_MULTICOLUMN);
590 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
592 // apply the multirow offset
593 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
594 if (mroffset.empty())
596 if (multirowCB->isChecked())
597 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
599 if (multirowCB->isChecked())
600 setParam(param_str, Tabular::SET_MULTIROW);
602 setParam(param_str, Tabular::UNSET_MULTIROW);
603 // store the table rotation angle
604 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
605 if (rotateTabularCB->isChecked())
606 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
608 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
609 // store the cell rotation angle
610 string const cell_angle = convert<string>(rotateCellAngleSB->value());
611 if (rotateCellCB->isChecked())
612 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
614 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
616 if (longTabularCB->isChecked())
617 setParam(param_str, Tabular::SET_LONGTABULAR);
619 setParam(param_str, Tabular::UNSET_LONGTABULAR);
621 if (newpageCB->isChecked())
622 setParam(param_str, Tabular::SET_LTNEWPAGE);
624 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
626 if (captionStatusCB->isChecked())
627 setParam(param_str, Tabular::SET_LTCAPTION);
629 setParam(param_str, Tabular::UNSET_LTCAPTION);
631 if (headerStatusCB->isChecked())
632 setParam(param_str, Tabular::SET_LTHEAD, "none");
634 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
636 if (headerBorderAboveCB->isChecked())
637 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
639 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
641 if (headerBorderBelowCB->isChecked())
642 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
644 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
645 if (firstheaderBorderAboveCB->isChecked())
646 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
648 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
649 if (firstheaderBorderBelowCB->isChecked())
650 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
652 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
653 if (firstheaderStatusCB->isChecked())
654 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
656 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
657 if (firstheaderNoContentsCB->isChecked())
658 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
660 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
661 if (footerStatusCB->isChecked())
662 setParam(param_str, Tabular::SET_LTFOOT, "none");
664 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
665 if (footerBorderAboveCB->isChecked())
666 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
668 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
669 if (footerBorderBelowCB->isChecked())
670 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
672 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
673 if (lastfooterStatusCB->isChecked())
674 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
676 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
677 if (lastfooterBorderAboveCB->isChecked())
678 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
680 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
681 if (lastfooterBorderBelowCB->isChecked())
682 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
684 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
685 if (lastfooterNoContentsCB->isChecked())
686 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
688 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
690 if (leftRB->isChecked())
691 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
692 else if (centerRB->isChecked())
693 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
694 else if (rightRB->isChecked())
695 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
697 return from_utf8(param_str);
701 static Length getColumnPWidth(Tabular const & t, size_t cell)
703 return t.column_info[t.cellColumn(cell)].p_width;
707 static Length getMColumnPWidth(Tabular const & t, size_t cell)
709 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
710 return t.cellInfo(cell).p_width;
715 static Length getMROffset(Tabular const & t, size_t cell)
717 if (t.isMultiRow(cell))
718 return t.cellInfo(cell).mroffset;
723 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
725 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
726 return t.cellInfo(cell).align_special;
727 return t.column_info[t.cellColumn(cell)].align_special;
731 void GuiTabular::paramsToDialog(Inset const * inset)
733 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
734 // Copy Tabular of current inset.
735 Tabular const & tabular = itab->tabular;
737 BufferView const * bv = guiApp->currentView()->currentBufferView();
738 size_t const cell = bv->cursor().idx();
740 Tabular::row_type const row = tabular.cellRow(cell);
741 Tabular::col_type const col = tabular.cellColumn(cell);
743 tabularRowED->setText(QString::number(row + 1));
744 tabularColumnED->setText(QString::number(col + 1));
746 bool const multicol = tabular.isMultiColumn(cell);
747 multicolumnCB->setChecked(multicol);
749 bool const multirow = tabular.isMultiRow(cell);
750 multirowCB->setChecked(multirow);
752 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
753 if (rotateCellCB->isChecked()) {
754 if (tabular.getRotateCell(cell) != 0)
755 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
757 rotateCellAngleSB->setValue(90);
760 longTabularCB->setChecked(tabular.is_long_tabular);
762 rotateTabularCB->setChecked(tabular.rotate != 0);
763 if (rotateTabularCB->isChecked()) {
764 if (longTabularCB->isChecked())
765 rotateTabularAngleSB->setValue(90);
767 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
770 borders->setTop(tabular.topLine(cell));
771 borders->setBottom(tabular.bottomLine(cell));
772 borders->setLeft(tabular.leftLine(cell));
773 borders->setRight(tabular.rightLine(cell));
774 // repaint the setborder widget
777 Length::UNIT const default_unit = Length::defaultUnit();
779 ///////////////////////////////////
780 // Set width and alignment
782 Length const tabwidth = tabular.tabularWidth();
784 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
785 tabularWidthED->clear();
787 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
788 tabwidth.asString(), default_unit);
793 special = getAlignSpecial(tabular, cell,
794 Tabular::SET_SPECIAL_MULTICOLUMN);
795 pwidth = getMColumnPWidth(tabular, cell);
797 special = getAlignSpecial(tabular, cell,
798 Tabular::SET_SPECIAL_COLUMN);
799 pwidth = getColumnPWidth(tabular, cell);
801 bool const varwidth = tabular.column_info[tabular.cellColumn(cell)].varwidth;
803 columnTypeCO->setCurrentIndex(1);
806 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0")) {
807 columnWidthED->clear();
809 columnTypeCO->setCurrentIndex(0);
811 colwidth = pwidth.asString();
812 lengthToWidgets(columnWidthED, columnWidthUnitLC,
813 colwidth, default_unit);
814 columnTypeCO->setCurrentIndex(2);
818 mroffset = getMROffset(tabular, cell);
821 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
822 multirowOffsetED->clear();
824 offset = mroffset.asString();
825 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
826 offset, default_unit);
828 specialAlignmentED->setText(toqstr(special));
829 ///////////////////////////////////
832 borderDefaultRB->setChecked(!tabular.use_booktabs);
833 booktabsRB->setChecked(tabular.use_booktabs);
835 if (tabular.row_info[row].top_space.empty()
836 && !tabular.row_info[row].top_space_default) {
837 topspaceCO->setCurrentIndex(0);
838 } else if (tabular.row_info[row].top_space_default) {
839 topspaceCO->setCurrentIndex(1);
841 topspaceCO->setCurrentIndex(2);
842 lengthToWidgets(topspaceED,
844 tabular.row_info[row].top_space.asString(),
848 if (tabular.row_info[row].bottom_space.empty()
849 && !tabular.row_info[row].bottom_space_default) {
850 bottomspaceCO->setCurrentIndex(0);
851 } else if (tabular.row_info[row].bottom_space_default) {
852 bottomspaceCO->setCurrentIndex(1);
854 bottomspaceCO->setCurrentIndex(2);
855 lengthToWidgets(bottomspaceED,
857 tabular.row_info[row].bottom_space.asString(),
861 if (tabular.row_info[row].interline_space.empty()
862 && !tabular.row_info[row].interline_space_default) {
863 interlinespaceCO->setCurrentIndex(0);
864 } else if (tabular.row_info[row].interline_space_default) {
865 interlinespaceCO->setCurrentIndex(1);
867 interlinespaceCO->setCurrentIndex(2);
868 lengthToWidgets(interlinespaceED,
869 interlinespaceUnitLC,
870 tabular.row_info[row].interline_space.asString(),
875 hAlignCO->addItem(qt_("Left"), toqstr("left"));
876 hAlignCO->addItem(qt_("Center"), toqstr("center"));
877 hAlignCO->addItem(qt_("Right"), toqstr("right"));
878 if (!multicol && !pwidth.zero())
879 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
880 if (!multicol && !multirow)
881 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
884 switch (tabular.getAlignment(cell)) {
888 case LYX_ALIGN_CENTER:
891 case LYX_ALIGN_RIGHT:
894 case LYX_ALIGN_BLOCK:
896 if (!multicol && !pwidth.zero())
900 case LYX_ALIGN_DECIMAL:
902 if (!multicol && !multirow)
907 // we should never end up here
910 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
913 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
914 if (decimal_point.isEmpty())
915 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
916 decimalPointED->setText(decimal_point);
919 switch (tabular.getVAlignment(cell)) {
920 case Tabular::LYX_VALIGN_TOP:
923 case Tabular::LYX_VALIGN_MIDDLE:
926 case Tabular::LYX_VALIGN_BOTTOM:
935 vAlignCO->setCurrentIndex(valign);
938 switch (tabular.tabular_valignment) {
939 case Tabular::LYX_VALIGN_TOP:
942 case Tabular::LYX_VALIGN_MIDDLE:
945 case Tabular::LYX_VALIGN_BOTTOM:
952 TableAlignCO->setCurrentIndex(tableValign);
954 if (!tabular.is_long_tabular) {
955 headerStatusCB->setChecked(false);
956 headerBorderAboveCB->setChecked(false);
957 headerBorderBelowCB->setChecked(false);
958 firstheaderStatusCB->setChecked(false);
959 firstheaderBorderAboveCB->setChecked(false);
960 firstheaderBorderBelowCB->setChecked(false);
961 firstheaderNoContentsCB->setChecked(false);
962 footerStatusCB->setChecked(false);
963 footerBorderAboveCB->setChecked(false);
964 footerBorderBelowCB->setChecked(false);
965 lastfooterStatusCB->setChecked(false);
966 lastfooterBorderAboveCB->setChecked(false);
967 lastfooterBorderBelowCB->setChecked(false);
968 lastfooterNoContentsCB->setChecked(false);
969 newpageCB->setChecked(false);
970 captionStatusCB->blockSignals(true);
971 captionStatusCB->setChecked(false);
972 captionStatusCB->blockSignals(false);
976 // longtables cannot have a vertical alignment
977 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
979 switch (tabular.longtabular_alignment) {
980 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
981 leftRB->setChecked(true);
983 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
984 centerRB->setChecked(true);
986 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
987 rightRB->setChecked(true);
990 centerRB->setChecked(true);
993 captionStatusCB->blockSignals(true);
994 captionStatusCB->setChecked(tabular.ltCaption(row));
995 captionStatusCB->blockSignals(false);
999 bool row_set = tabular.getRowOfLTHead(row, ltt);
1000 headerStatusCB->setChecked(row_set);
1002 headerBorderAboveCB->setChecked(ltt.topDL);
1003 headerBorderBelowCB->setChecked(ltt.bottomDL);
1006 headerBorderAboveCB->setChecked(false);
1007 headerBorderBelowCB->setChecked(false);
1008 firstheaderNoContentsCB->setChecked(false);
1012 row_set = tabular.getRowOfLTFirstHead(row, ltt);
1013 firstheaderStatusCB->setChecked(row_set);
1014 if (ltt.set && (!ltt.empty || !use_empty)) {
1015 firstheaderBorderAboveCB->setChecked(ltt.topDL);
1016 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
1018 firstheaderBorderAboveCB->setChecked(false);
1019 firstheaderBorderBelowCB->setChecked(false);
1022 row_set = tabular.getRowOfLTFoot(row, ltt);
1023 footerStatusCB->setChecked(row_set);
1025 footerBorderAboveCB->setChecked(ltt.topDL);
1026 footerBorderBelowCB->setChecked(ltt.bottomDL);
1029 footerBorderAboveCB->setChecked(false);
1030 footerBorderBelowCB->setChecked(false);
1031 lastfooterNoContentsCB->setChecked(false);
1035 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1036 lastfooterStatusCB->setChecked(row_set);
1037 if (ltt.set && (!ltt.empty || !use_empty)) {
1038 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1039 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1041 lastfooterBorderAboveCB->setChecked(false);
1042 lastfooterBorderBelowCB->setChecked(false);
1044 newpageCB->setChecked(tabular.getLTNewPage(row));
1046 // first header can only be suppressed when there is a header
1047 firstheader_suppressable_ = tabular.haveLTHead()
1048 && !tabular.haveLTFirstHead();
1049 // last footer can only be suppressed when there is a footer
1050 lastfooter_suppressable_ = tabular.haveLTFoot()
1051 && !tabular.haveLTLastFoot();
1053 // after setting the features, check if they are enabled
1058 bool GuiTabular::checkWidgets(bool readonly) const
1060 tabularRowED->setReadOnly(readonly);
1061 tabularColumnED->setReadOnly(readonly);
1062 tabularWidthED->setReadOnly(readonly);
1063 specialAlignmentED->setReadOnly(readonly);
1064 columnWidthED->setReadOnly(readonly);
1065 multirowOffsetED->setReadOnly(readonly);
1066 decimalPointED->setReadOnly(readonly);
1069 multicolumnCB->setEnabled(false);
1070 multirowCB->setEnabled(false);
1071 rotateCellCB->setEnabled(false);
1072 rotateCellAngleSB->setEnabled(false);
1073 rotateTabularCB->setEnabled(false);
1074 rotateTabularAngleSB->setEnabled(false);
1075 longTabularCB->setEnabled(false);
1076 borders->setEnabled(false);
1077 tabularWidthUnitLC->setEnabled(false);
1078 columnWidthUnitLC->setEnabled(false);
1079 columnTypeCO->setEnabled(false);
1080 multirowOffsetUnitLC->setEnabled(false);
1081 setBordersGB->setEnabled(false);
1082 allBordersGB->setEnabled(false);
1083 borderStyleGB->setEnabled(false);
1084 booktabsRB->setEnabled(false);
1085 topspaceCO->setEnabled(false);
1086 topspaceUnitLC->setEnabled(false);
1087 bottomspaceCO->setEnabled(false);
1088 bottomspaceUnitLC->setEnabled(false);
1089 interlinespaceCO->setEnabled(false);
1090 interlinespaceUnitLC->setEnabled(false);
1091 hAlignCO->setEnabled(false);
1092 vAlignCO->setEnabled(false);
1093 TableAlignCO->setEnabled(false);
1094 longtableGB->setEnabled(false);
1095 alignmentGB->setEnabled(false);
1099 return InsetParamsWidget::checkWidgets();
1103 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1105 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1106 return getStatus(r).enabled();
1110 } // namespace frontend
1113 #include "moc_GuiTabular.cpp"