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::enableWidgets() const
206 // if there is a LaTeX argument, the width and alignment will be overwritten
207 // therefore disable them in this case
208 columnWidthED->setEnabled(specialAlignmentED->text().isEmpty());
209 columnWidthUnitLC->setEnabled(specialAlignmentED->text().isEmpty());
210 // if the column has a width, multirows are always left-aligned
211 // therefore disable hAlignCB in this case
212 hAlignCO->setEnabled(!(multirowCB->isChecked()
213 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
214 && specialAlignmentED->text().isEmpty());
215 // decimal alignment is only possible for non-multicol and non-multirow cells
216 if ((multicolumnCB->isChecked() || multirowCB->isChecked())
217 && hAlignCO->findData(toqstr("decimal")))
218 hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
219 else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
220 && hAlignCO->findData(toqstr("decimal")) == -1)
221 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
223 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
224 decimalPointED->setEnabled(dalign);
225 decimalLA->setEnabled(dalign);
227 bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
228 && !longTabularCB->isChecked();
229 tabularWidthLA->setEnabled(setwidth);
230 tabularWidthED->setEnabled(setwidth);
231 tabularWidthUnitLC->setEnabled(setwidth);
233 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked()
234 && !longTabularCB->isChecked());
235 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
237 bool const enable_valign =
238 !multirowCB->isChecked()
239 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
240 && specialAlignmentED->text().isEmpty();
241 vAlignCO->setEnabled(enable_valign);
242 vAlignLA->setEnabled(enable_valign);
244 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
245 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
246 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
247 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
248 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
249 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
250 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
252 // setting as longtable is not allowed when table is inside a float
253 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
254 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
255 bool const longtabular = longTabularCB->isChecked();
256 longtableGB->setEnabled(true);
257 newpageCB->setEnabled(longtabular);
258 alignmentGB->setEnabled(longtabular);
259 // longtables and tabular* cannot have a vertical alignment
260 TableAlignLA->setDisabled(is_tabular_star || longtabular);
261 TableAlignCO->setDisabled(is_tabular_star || longtabular);
262 // longtable cannot be rotated with rotating package, only
263 // with [pdf]lscape, which only supports 90 deg.
264 rotateTabularAngleSB->setDisabled(longtabular);
266 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
267 // depending on the cursor position is very very unintuitive...
268 // We need some edit boxes to show which rows are header/footer/etc
269 // without having to move the cursor first.
270 headerStatusCB->setEnabled(longtabular
271 && (headerStatusCB->isChecked() ?
272 funcEnabled(Tabular::UNSET_LTHEAD) :
273 funcEnabled(Tabular::SET_LTHEAD)));
274 headerBorderAboveCB->setEnabled(longtabular
275 && headerStatusCB->isChecked());
276 headerBorderBelowCB->setEnabled(longtabular
277 && headerStatusCB->isChecked());
279 // first header can only be suppressed when there is a header
280 // firstheader_suppressable_ is set in paramsToDialog
281 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
282 // check if setting a first header is allowed
283 // additionally check firstheaderNoContentsCB because when this is
284 // the case a first header makes no sense
285 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
286 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
287 funcEnabled(Tabular::SET_LTFIRSTHEAD))
288 && longtabular && !firstheaderNoContentsCB->isChecked());
289 firstheaderBorderAboveCB->setEnabled(longtabular
290 && firstheaderStatusCB->isChecked());
291 firstheaderBorderBelowCB->setEnabled(longtabular
292 && firstheaderStatusCB->isChecked());
294 footerStatusCB->setEnabled(longtabular
295 && (footerStatusCB->isChecked() ?
296 funcEnabled(Tabular::UNSET_LTFOOT) :
297 funcEnabled(Tabular::SET_LTFOOT)));
298 footerBorderAboveCB->setEnabled(longtabular
299 && footerBorderAboveCB->isChecked());
300 footerBorderBelowCB->setEnabled(longtabular
301 && footerBorderAboveCB->isChecked());
303 // last footer can only be suppressed when there is a footer
304 // lastfooter_suppressable_ is set in paramsToDialog
305 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
306 // check if setting a last footer is allowed
307 // additionally check lastfooterNoContentsCB because when this is
308 // the case a last footer makes no sense
309 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
310 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
311 funcEnabled(Tabular::SET_LTLASTFOOT))
312 && longtabular && !lastfooterNoContentsCB->isChecked());
313 lastfooterBorderAboveCB->setEnabled(longtabular
314 && lastfooterBorderAboveCB->isChecked());
315 lastfooterBorderBelowCB->setEnabled(longtabular
316 && lastfooterBorderAboveCB->isChecked());
318 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
321 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
322 && !dalign && !multirowCB->isChecked());
323 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
324 && !dalign && !multicolumnCB->isChecked());
325 bool const enable_mr = multirowCB->isChecked();
326 multirowOffsetLA->setEnabled(enable_mr);
327 multirowOffsetED->setEnabled(enable_mr);
328 multirowOffsetUnitLC->setEnabled(enable_mr);
330 // Vertical lines cannot be set in formal tables
331 borders->setLeftEnabled(!booktabsRB->isChecked());
332 borders->setRightEnabled(!booktabsRB->isChecked());
336 void GuiTabular::checkEnabled()
343 void GuiTabular::borderSet_clicked()
345 borders->setTop(true);
346 borders->setBottom(true);
347 borders->setLeft(true);
348 borders->setRight(true);
349 // repaint the setborder widget
355 void GuiTabular::borderUnset_clicked()
357 borders->setTop(false);
358 borders->setBottom(false);
359 borders->setLeft(false);
360 borders->setRight(false);
361 // repaint the setborder widget
367 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
370 param_str += featureAsString(f) + ' ' + arg;
374 void GuiTabular::setHAlign(string & param_str) const
376 Tabular::Feature num = Tabular::ALIGN_LEFT;
377 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
379 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
380 if (align == "left") {
381 num = Tabular::ALIGN_LEFT;
382 multi_num = Tabular::M_ALIGN_LEFT;
383 } else if (align == "center") {
384 num = Tabular::ALIGN_CENTER;
385 multi_num = Tabular::M_ALIGN_CENTER;
386 } else if (align == "right") {
387 num = Tabular::ALIGN_RIGHT;
388 multi_num = Tabular::M_ALIGN_RIGHT;
389 } else if (align == "justified") {
390 num = Tabular::ALIGN_BLOCK;
391 //multi_num: no equivalent
392 } else if (align == "decimal") {
393 num = Tabular::ALIGN_DECIMAL;
394 //multi_num: no equivalent
397 if (multicolumnCB->isChecked())
398 setParam(param_str, multi_num);
400 setParam(param_str, num);
404 void GuiTabular::setVAlign(string & param_str) const
406 int const align = vAlignCO->currentIndex();
407 enum VALIGN { TOP, MIDDLE, BOTTOM };
411 case 0: v = TOP; break;
412 case 1: v = MIDDLE; break;
413 case 2: v = BOTTOM; break;
416 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
417 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
421 num = Tabular::VALIGN_TOP;
422 multi_num = Tabular::M_VALIGN_TOP;
425 num = Tabular::VALIGN_MIDDLE;
426 multi_num = Tabular::M_VALIGN_MIDDLE;
429 num = Tabular::VALIGN_BOTTOM;
430 multi_num = Tabular::M_VALIGN_BOTTOM;
433 if (multicolumnCB->isChecked() || multirowCB->isChecked())
434 setParam(param_str, multi_num);
436 setParam(param_str, num);
440 void GuiTabular::setTableAlignment(string & param_str) const
442 int const align = TableAlignCO->currentIndex();
444 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
446 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
448 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
454 docstring GuiTabular::dialogToParams() const
456 string param_str = "tabular";
459 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
460 if (tabwidth.empty())
462 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
464 // apply the fixed width values
465 // this must be done before applying the column alignment
466 // because its value influences the alignment of multirow cells
467 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
470 if (multicolumnCB->isChecked())
471 setParam(param_str, Tabular::SET_MPWIDTH, width);
473 setParam(param_str, Tabular::SET_PWIDTH, width);
475 // apply the column alignment
476 // multirows inherit the alignment from the column; if a column width
477 // is set, multirows are always left-aligned so that in this case
478 // its alignment must not be applied (see bug #8084)
479 if (!(multirowCB->isChecked() && width != "0pt"))
480 setHAlign(param_str);
482 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
483 string decimal_point = fromqstr(decimalPointED->text());
484 if (decimal_point.empty())
485 decimal_point = lyxrc.default_decimal_point;
486 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
488 setVAlign(param_str);
489 setTableAlignment(param_str);
491 if (booktabsRB->isChecked())
492 setParam(param_str, Tabular::SET_BOOKTABS);
494 setParam(param_str, Tabular::UNSET_BOOKTABS);
497 switch (topspaceCO->currentIndex()) {
499 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
502 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
505 if (!topspaceED->text().isEmpty())
506 setParam(param_str, Tabular::SET_TOP_SPACE,
507 widgetsToLength(topspaceED, topspaceUnitLC));
512 switch (bottomspaceCO->currentIndex()) {
514 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
517 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
520 if (!bottomspaceED->text().isEmpty())
521 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
522 widgetsToLength(bottomspaceED,
528 switch (interlinespaceCO->currentIndex()) {
530 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
533 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
536 if (!interlinespaceED->text().isEmpty())
537 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
538 widgetsToLength(interlinespaceED,
539 interlinespaceUnitLC));
544 if (borders->getTop() && borders->getBottom() && borders->getLeft()
545 && borders->getRight())
546 setParam(param_str, Tabular::SET_ALL_LINES);
547 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
548 && !borders->getRight())
549 setParam(param_str, Tabular::UNSET_ALL_LINES);
551 setParam(param_str, Tabular::SET_LINE_LEFT,
552 borders->getLeft() ? "true" : "false");
553 setParam(param_str, Tabular::SET_LINE_RIGHT,
554 borders->getRight() ? "true" : "false");
555 setParam(param_str, Tabular::SET_LINE_TOP,
556 borders->getTop() ? "true" : "false");
557 setParam(param_str, Tabular::SET_LINE_BOTTOM,
558 borders->getBottom() ? "true" : "false");
561 // apply the special alignment
562 string special = fromqstr(specialAlignmentED->text());
565 if (multicolumnCB->isChecked())
566 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
568 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
571 if (multicolumnCB->isChecked())
572 setParam(param_str, Tabular::SET_MULTICOLUMN);
574 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
576 // apply the multirow offset
577 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
578 if (mroffset.empty())
580 if (multirowCB->isChecked())
581 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
583 if (multirowCB->isChecked())
584 setParam(param_str, Tabular::SET_MULTIROW);
586 setParam(param_str, Tabular::UNSET_MULTIROW);
587 // store the table rotation angle
588 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
589 if (rotateTabularCB->isChecked())
590 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
592 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
593 // store the cell rotation angle
594 string const cell_angle = convert<string>(rotateCellAngleSB->value());
595 if (rotateCellCB->isChecked())
596 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
598 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
600 if (longTabularCB->isChecked())
601 setParam(param_str, Tabular::SET_LONGTABULAR);
603 setParam(param_str, Tabular::UNSET_LONGTABULAR);
605 if (newpageCB->isChecked())
606 setParam(param_str, Tabular::SET_LTNEWPAGE);
608 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
610 if (captionStatusCB->isChecked())
611 setParam(param_str, Tabular::SET_LTCAPTION);
613 setParam(param_str, Tabular::UNSET_LTCAPTION);
615 if (headerStatusCB->isChecked())
616 setParam(param_str, Tabular::SET_LTHEAD, "none");
618 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
620 if (headerBorderAboveCB->isChecked())
621 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
623 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
625 if (headerBorderBelowCB->isChecked())
626 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
628 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
629 if (firstheaderBorderAboveCB->isChecked())
630 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
632 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
633 if (firstheaderBorderBelowCB->isChecked())
634 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
636 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
637 if (firstheaderStatusCB->isChecked())
638 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
640 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
641 if (firstheaderNoContentsCB->isChecked())
642 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
644 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
645 if (footerStatusCB->isChecked())
646 setParam(param_str, Tabular::SET_LTFOOT, "none");
648 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
649 if (footerBorderAboveCB->isChecked())
650 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
652 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
653 if (footerBorderBelowCB->isChecked())
654 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
656 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
657 if (lastfooterStatusCB->isChecked())
658 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
660 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
661 if (lastfooterBorderAboveCB->isChecked())
662 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
664 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
665 if (lastfooterBorderBelowCB->isChecked())
666 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
668 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
669 if (lastfooterNoContentsCB->isChecked())
670 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
672 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
674 if (leftRB->isChecked())
675 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
676 else if (centerRB->isChecked())
677 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
678 else if (rightRB->isChecked())
679 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
681 return from_utf8(param_str);
685 static Length getColumnPWidth(Tabular const & t, size_t cell)
687 return t.column_info[t.cellColumn(cell)].p_width;
691 static Length getMColumnPWidth(Tabular const & t, size_t cell)
693 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
694 return t.cellInfo(cell).p_width;
699 static Length getMROffset(Tabular const & t, size_t cell)
701 if (t.isMultiRow(cell))
702 return t.cellInfo(cell).mroffset;
707 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
709 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
710 return t.cellInfo(cell).align_special;
711 return t.column_info[t.cellColumn(cell)].align_special;
715 void GuiTabular::paramsToDialog(Inset const * inset)
717 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
718 // Copy Tabular of current inset.
719 Tabular const & tabular = itab->tabular;
721 BufferView const * bv = guiApp->currentView()->currentBufferView();
722 size_t const cell = bv->cursor().idx();
724 Tabular::row_type const row = tabular.cellRow(cell);
725 Tabular::col_type const col = tabular.cellColumn(cell);
727 tabularRowED->setText(QString::number(row + 1));
728 tabularColumnED->setText(QString::number(col + 1));
730 bool const multicol = tabular.isMultiColumn(cell);
731 multicolumnCB->setChecked(multicol);
733 bool const multirow = tabular.isMultiRow(cell);
734 multirowCB->setChecked(multirow);
736 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
737 if (rotateCellCB->isChecked()) {
738 if (tabular.getRotateCell(cell) != 0)
739 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
741 rotateCellAngleSB->setValue(90);
744 longTabularCB->setChecked(tabular.is_long_tabular);
746 rotateTabularCB->setChecked(tabular.rotate != 0);
747 if (rotateTabularCB->isChecked()) {
748 if (longTabularCB->isChecked())
749 rotateTabularAngleSB->setValue(90);
751 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
754 borders->setTop(tabular.topLine(cell));
755 borders->setBottom(tabular.bottomLine(cell));
756 borders->setLeft(tabular.leftLine(cell));
757 borders->setRight(tabular.rightLine(cell));
758 // repaint the setborder widget
761 Length::UNIT const default_unit = Length::defaultUnit();
763 ///////////////////////////////////
764 // Set width and alignment
766 Length const tabwidth = tabular.tabularWidth();
768 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
769 tabularWidthED->clear();
771 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
772 tabwidth.asString(), default_unit);
777 special = getAlignSpecial(tabular, cell,
778 Tabular::SET_SPECIAL_MULTICOLUMN);
779 pwidth = getMColumnPWidth(tabular, cell);
781 special = getAlignSpecial(tabular, cell,
782 Tabular::SET_SPECIAL_COLUMN);
783 pwidth = getColumnPWidth(tabular, cell);
787 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0"))
788 columnWidthED->clear();
790 colwidth = pwidth.asString();
791 lengthToWidgets(columnWidthED, columnWidthUnitLC,
792 colwidth, default_unit);
796 mroffset = getMROffset(tabular, cell);
799 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
800 multirowOffsetED->clear();
802 offset = mroffset.asString();
803 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
804 offset, default_unit);
806 specialAlignmentED->setText(toqstr(special));
807 ///////////////////////////////////
810 borderDefaultRB->setChecked(!tabular.use_booktabs);
811 booktabsRB->setChecked(tabular.use_booktabs);
813 if (tabular.row_info[row].top_space.empty()
814 && !tabular.row_info[row].top_space_default) {
815 topspaceCO->setCurrentIndex(0);
816 } else if (tabular.row_info[row].top_space_default) {
817 topspaceCO->setCurrentIndex(1);
819 topspaceCO->setCurrentIndex(2);
820 lengthToWidgets(topspaceED,
822 tabular.row_info[row].top_space.asString(),
826 if (tabular.row_info[row].bottom_space.empty()
827 && !tabular.row_info[row].bottom_space_default) {
828 bottomspaceCO->setCurrentIndex(0);
829 } else if (tabular.row_info[row].bottom_space_default) {
830 bottomspaceCO->setCurrentIndex(1);
832 bottomspaceCO->setCurrentIndex(2);
833 lengthToWidgets(bottomspaceED,
835 tabular.row_info[row].bottom_space.asString(),
839 if (tabular.row_info[row].interline_space.empty()
840 && !tabular.row_info[row].interline_space_default) {
841 interlinespaceCO->setCurrentIndex(0);
842 } else if (tabular.row_info[row].interline_space_default) {
843 interlinespaceCO->setCurrentIndex(1);
845 interlinespaceCO->setCurrentIndex(2);
846 lengthToWidgets(interlinespaceED,
847 interlinespaceUnitLC,
848 tabular.row_info[row].interline_space.asString(),
853 hAlignCO->addItem(qt_("Left"), toqstr("left"));
854 hAlignCO->addItem(qt_("Center"), toqstr("center"));
855 hAlignCO->addItem(qt_("Right"), toqstr("right"));
856 if (!multicol && !pwidth.zero())
857 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
858 if (!multicol && !multirow)
859 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
862 switch (tabular.getAlignment(cell)) {
866 case LYX_ALIGN_CENTER:
869 case LYX_ALIGN_RIGHT:
872 case LYX_ALIGN_BLOCK:
874 if (!multicol && !pwidth.zero())
878 case LYX_ALIGN_DECIMAL:
880 if (!multicol && !multirow)
885 // we should never end up here
888 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
891 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
892 if (decimal_point.isEmpty())
893 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
894 decimalPointED->setText(decimal_point);
897 switch (tabular.getVAlignment(cell)) {
898 case Tabular::LYX_VALIGN_TOP:
901 case Tabular::LYX_VALIGN_MIDDLE:
904 case Tabular::LYX_VALIGN_BOTTOM:
913 vAlignCO->setCurrentIndex(valign);
916 switch (tabular.tabular_valignment) {
917 case Tabular::LYX_VALIGN_TOP:
920 case Tabular::LYX_VALIGN_MIDDLE:
923 case Tabular::LYX_VALIGN_BOTTOM:
930 TableAlignCO->setCurrentIndex(tableValign);
932 if (!tabular.is_long_tabular) {
933 headerStatusCB->setChecked(false);
934 headerBorderAboveCB->setChecked(false);
935 headerBorderBelowCB->setChecked(false);
936 firstheaderStatusCB->setChecked(false);
937 firstheaderBorderAboveCB->setChecked(false);
938 firstheaderBorderBelowCB->setChecked(false);
939 firstheaderNoContentsCB->setChecked(false);
940 footerStatusCB->setChecked(false);
941 footerBorderAboveCB->setChecked(false);
942 footerBorderBelowCB->setChecked(false);
943 lastfooterStatusCB->setChecked(false);
944 lastfooterBorderAboveCB->setChecked(false);
945 lastfooterBorderBelowCB->setChecked(false);
946 lastfooterNoContentsCB->setChecked(false);
947 newpageCB->setChecked(false);
948 captionStatusCB->blockSignals(true);
949 captionStatusCB->setChecked(false);
950 captionStatusCB->blockSignals(false);
954 // longtables cannot have a vertical alignment
955 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
957 switch (tabular.longtabular_alignment) {
958 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
959 leftRB->setChecked(true);
961 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
962 centerRB->setChecked(true);
964 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
965 rightRB->setChecked(true);
968 centerRB->setChecked(true);
971 captionStatusCB->blockSignals(true);
972 captionStatusCB->setChecked(tabular.ltCaption(row));
973 captionStatusCB->blockSignals(false);
977 bool row_set = tabular.getRowOfLTHead(row, ltt);
978 headerStatusCB->setChecked(row_set);
980 headerBorderAboveCB->setChecked(ltt.topDL);
981 headerBorderBelowCB->setChecked(ltt.bottomDL);
984 headerBorderAboveCB->setChecked(false);
985 headerBorderBelowCB->setChecked(false);
986 firstheaderNoContentsCB->setChecked(false);
990 row_set = tabular.getRowOfLTFirstHead(row, ltt);
991 firstheaderStatusCB->setChecked(row_set);
992 if (ltt.set && (!ltt.empty || !use_empty)) {
993 firstheaderBorderAboveCB->setChecked(ltt.topDL);
994 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
996 firstheaderBorderAboveCB->setChecked(false);
997 firstheaderBorderBelowCB->setChecked(false);
1000 row_set = tabular.getRowOfLTFoot(row, ltt);
1001 footerStatusCB->setChecked(row_set);
1003 footerBorderAboveCB->setChecked(ltt.topDL);
1004 footerBorderBelowCB->setChecked(ltt.bottomDL);
1007 footerBorderAboveCB->setChecked(false);
1008 footerBorderBelowCB->setChecked(false);
1009 lastfooterNoContentsCB->setChecked(false);
1013 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1014 lastfooterStatusCB->setChecked(row_set);
1015 if (ltt.set && (!ltt.empty || !use_empty)) {
1016 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1017 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1019 lastfooterBorderAboveCB->setChecked(false);
1020 lastfooterBorderBelowCB->setChecked(false);
1022 newpageCB->setChecked(tabular.getLTNewPage(row));
1024 // first header can only be suppressed when there is a header
1025 firstheader_suppressable_ = tabular.haveLTHead()
1026 && !tabular.haveLTFirstHead();
1027 // last footer can only be suppressed when there is a footer
1028 lastfooter_suppressable_ = tabular.haveLTFoot()
1029 && !tabular.haveLTLastFoot();
1031 // after setting the features, check if they are enabled
1036 bool GuiTabular::checkWidgets(bool readonly) const
1038 tabularRowED->setReadOnly(readonly);
1039 tabularColumnED->setReadOnly(readonly);
1040 tabularWidthED->setReadOnly(readonly);
1041 specialAlignmentED->setReadOnly(readonly);
1042 columnWidthED->setReadOnly(readonly);
1043 multirowOffsetED->setReadOnly(readonly);
1044 decimalPointED->setReadOnly(readonly);
1047 multicolumnCB->setEnabled(false);
1048 multirowCB->setEnabled(false);
1049 rotateCellCB->setEnabled(false);
1050 rotateCellAngleSB->setEnabled(false);
1051 rotateTabularCB->setEnabled(false);
1052 rotateTabularAngleSB->setEnabled(false);
1053 longTabularCB->setEnabled(false);
1054 borders->setEnabled(false);
1055 tabularWidthUnitLC->setEnabled(false);
1056 columnWidthUnitLC->setEnabled(false);
1057 multirowOffsetUnitLC->setEnabled(false);
1058 setBordersGB->setEnabled(false);
1059 allBordersGB->setEnabled(false);
1060 borderStyleGB->setEnabled(false);
1061 booktabsRB->setEnabled(false);
1062 topspaceCO->setEnabled(false);
1063 topspaceUnitLC->setEnabled(false);
1064 bottomspaceCO->setEnabled(false);
1065 bottomspaceUnitLC->setEnabled(false);
1066 interlinespaceCO->setEnabled(false);
1067 interlinespaceUnitLC->setEnabled(false);
1068 hAlignCO->setEnabled(false);
1069 vAlignCO->setEnabled(false);
1070 TableAlignCO->setEnabled(false);
1071 longtableGB->setEnabled(false);
1072 alignmentGB->setEnabled(false);
1076 return InsetParamsWidget::checkWidgets();
1080 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1082 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1083 return getStatus(r).enabled();
1087 } // namespace frontend
1090 #include "moc_GuiTabular.cpp"