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 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
236 bool const enable_valign =
237 !multirowCB->isChecked()
238 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
239 && specialAlignmentED->text().isEmpty();
240 vAlignCO->setEnabled(enable_valign);
241 vAlignLA->setEnabled(enable_valign);
243 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
244 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
245 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
246 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
247 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
248 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
249 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
251 // setting as longtable is not allowed when table is inside a float
252 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
253 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
254 bool const longtabular = longTabularCB->isChecked();
255 longtableGB->setEnabled(true);
256 newpageCB->setEnabled(longtabular);
257 alignmentGB->setEnabled(longtabular);
258 // longtables and tabular* cannot have a vertical alignment
259 TableAlignLA->setDisabled(is_tabular_star || longtabular);
260 TableAlignCO->setDisabled(is_tabular_star || longtabular);
261 // longtable cannot be rotated (with rotating package)
262 // FIXME: Add support for [pdf]lscape
263 rotateTabularCB->setDisabled(longtabular);
264 rotateTabularLA->setDisabled(longtabular);
265 // this one would also be disabled with [pdf]lscape
266 rotateTabularAngleSB->setDisabled(longtabular);
268 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
269 // depending on the cursor position is very very unintuitive...
270 // We need some edit boxes to show which rows are header/footer/etc
271 // without having to move the cursor first.
272 headerStatusCB->setEnabled(longtabular
273 && (headerStatusCB->isChecked() ?
274 funcEnabled(Tabular::UNSET_LTHEAD) :
275 funcEnabled(Tabular::SET_LTHEAD)));
276 headerBorderAboveCB->setEnabled(longtabular
277 && headerStatusCB->isChecked());
278 headerBorderBelowCB->setEnabled(longtabular
279 && headerStatusCB->isChecked());
281 // first header can only be suppressed when there is a header
282 // firstheader_suppressable_ is set in paramsToDialog
283 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
284 // check if setting a first header is allowed
285 // additionally check firstheaderNoContentsCB because when this is
286 // the case a first header makes no sense
287 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
288 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
289 funcEnabled(Tabular::SET_LTFIRSTHEAD))
290 && longtabular && !firstheaderNoContentsCB->isChecked());
291 firstheaderBorderAboveCB->setEnabled(longtabular
292 && firstheaderStatusCB->isChecked());
293 firstheaderBorderBelowCB->setEnabled(longtabular
294 && firstheaderStatusCB->isChecked());
296 footerStatusCB->setEnabled(longtabular
297 && (footerStatusCB->isChecked() ?
298 funcEnabled(Tabular::UNSET_LTFOOT) :
299 funcEnabled(Tabular::SET_LTFOOT)));
300 footerBorderAboveCB->setEnabled(longtabular
301 && footerBorderAboveCB->isChecked());
302 footerBorderBelowCB->setEnabled(longtabular
303 && footerBorderAboveCB->isChecked());
305 // last footer can only be suppressed when there is a footer
306 // lastfooter_suppressable_ is set in paramsToDialog
307 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
308 // check if setting a last footer is allowed
309 // additionally check lastfooterNoContentsCB because when this is
310 // the case a last footer makes no sense
311 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
312 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
313 funcEnabled(Tabular::SET_LTLASTFOOT))
314 && longtabular && !lastfooterNoContentsCB->isChecked());
315 lastfooterBorderAboveCB->setEnabled(longtabular
316 && lastfooterBorderAboveCB->isChecked());
317 lastfooterBorderBelowCB->setEnabled(longtabular
318 && lastfooterBorderAboveCB->isChecked());
320 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
323 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
324 && !dalign && !multirowCB->isChecked());
325 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
326 && !dalign && !multicolumnCB->isChecked());
327 bool const enable_mr = multirowCB->isChecked();
328 multirowOffsetLA->setEnabled(enable_mr);
329 multirowOffsetED->setEnabled(enable_mr);
330 multirowOffsetUnitLC->setEnabled(enable_mr);
332 // Vertical lines cannot be set in formal tables
333 borders->setLeftEnabled(!booktabsRB->isChecked());
334 borders->setRightEnabled(!booktabsRB->isChecked());
338 void GuiTabular::checkEnabled()
345 void GuiTabular::borderSet_clicked()
347 borders->setTop(true);
348 borders->setBottom(true);
349 borders->setLeft(true);
350 borders->setRight(true);
351 // repaint the setborder widget
357 void GuiTabular::borderUnset_clicked()
359 borders->setTop(false);
360 borders->setBottom(false);
361 borders->setLeft(false);
362 borders->setRight(false);
363 // repaint the setborder widget
369 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
372 param_str += featureAsString(f) + ' ' + arg;
376 void GuiTabular::setHAlign(string & param_str) const
378 Tabular::Feature num = Tabular::ALIGN_LEFT;
379 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
381 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
382 if (align == "left") {
383 num = Tabular::ALIGN_LEFT;
384 multi_num = Tabular::M_ALIGN_LEFT;
385 } else if (align == "center") {
386 num = Tabular::ALIGN_CENTER;
387 multi_num = Tabular::M_ALIGN_CENTER;
388 } else if (align == "right") {
389 num = Tabular::ALIGN_RIGHT;
390 multi_num = Tabular::M_ALIGN_RIGHT;
391 } else if (align == "justified") {
392 num = Tabular::ALIGN_BLOCK;
393 //multi_num: no equivalent
394 } else if (align == "decimal") {
395 num = Tabular::ALIGN_DECIMAL;
396 //multi_num: no equivalent
399 if (multicolumnCB->isChecked())
400 setParam(param_str, multi_num);
402 setParam(param_str, num);
406 void GuiTabular::setVAlign(string & param_str) const
408 int const align = vAlignCO->currentIndex();
409 enum VALIGN { TOP, MIDDLE, BOTTOM };
413 case 0: v = TOP; break;
414 case 1: v = MIDDLE; break;
415 case 2: v = BOTTOM; break;
418 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
419 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
423 num = Tabular::VALIGN_TOP;
424 multi_num = Tabular::M_VALIGN_TOP;
427 num = Tabular::VALIGN_MIDDLE;
428 multi_num = Tabular::M_VALIGN_MIDDLE;
431 num = Tabular::VALIGN_BOTTOM;
432 multi_num = Tabular::M_VALIGN_BOTTOM;
435 if (multicolumnCB->isChecked() || multirowCB->isChecked())
436 setParam(param_str, multi_num);
438 setParam(param_str, num);
442 void GuiTabular::setTableAlignment(string & param_str) const
444 int const align = TableAlignCO->currentIndex();
446 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
448 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
450 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
456 docstring GuiTabular::dialogToParams() const
458 string param_str = "tabular";
461 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
462 if (tabwidth.empty())
464 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
466 // apply the fixed width values
467 // this must be done before applying the column alignment
468 // because its value influences the alignment of multirow cells
469 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
472 if (multicolumnCB->isChecked())
473 setParam(param_str, Tabular::SET_MPWIDTH, width);
475 setParam(param_str, Tabular::SET_PWIDTH, width);
477 // apply the column alignment
478 // multirows inherit the alignment from the column; if a column width
479 // is set, multirows are always left-aligned so that in this case
480 // its alignment must not be applied (see bug #8084)
481 if (!(multirowCB->isChecked() && width != "0pt"))
482 setHAlign(param_str);
484 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
485 string decimal_point = fromqstr(decimalPointED->text());
486 if (decimal_point.empty())
487 decimal_point = lyxrc.default_decimal_point;
488 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
490 setVAlign(param_str);
491 setTableAlignment(param_str);
493 if (booktabsRB->isChecked())
494 setParam(param_str, Tabular::SET_BOOKTABS);
496 setParam(param_str, Tabular::UNSET_BOOKTABS);
499 switch (topspaceCO->currentIndex()) {
501 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
504 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
507 if (!topspaceED->text().isEmpty())
508 setParam(param_str, Tabular::SET_TOP_SPACE,
509 widgetsToLength(topspaceED, topspaceUnitLC));
514 switch (bottomspaceCO->currentIndex()) {
516 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
519 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
522 if (!bottomspaceED->text().isEmpty())
523 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
524 widgetsToLength(bottomspaceED,
530 switch (interlinespaceCO->currentIndex()) {
532 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
535 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
538 if (!interlinespaceED->text().isEmpty())
539 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
540 widgetsToLength(interlinespaceED,
541 interlinespaceUnitLC));
546 if (borders->getTop() && borders->getBottom() && borders->getLeft()
547 && borders->getRight())
548 setParam(param_str, Tabular::SET_ALL_LINES);
549 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
550 && !borders->getRight())
551 setParam(param_str, Tabular::UNSET_ALL_LINES);
553 setParam(param_str, Tabular::SET_LINE_LEFT,
554 borders->getLeft() ? "true" : "false");
555 setParam(param_str, Tabular::SET_LINE_RIGHT,
556 borders->getRight() ? "true" : "false");
557 setParam(param_str, Tabular::SET_LINE_TOP,
558 borders->getTop() ? "true" : "false");
559 setParam(param_str, Tabular::SET_LINE_BOTTOM,
560 borders->getBottom() ? "true" : "false");
563 // apply the special alignment
564 string special = fromqstr(specialAlignmentED->text());
567 if (multicolumnCB->isChecked())
568 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
570 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
573 if (multicolumnCB->isChecked())
574 setParam(param_str, Tabular::SET_MULTICOLUMN);
576 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
578 // apply the multirow offset
579 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
580 if (mroffset.empty())
582 if (multirowCB->isChecked())
583 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
585 if (multirowCB->isChecked())
586 setParam(param_str, Tabular::SET_MULTIROW);
588 setParam(param_str, Tabular::UNSET_MULTIROW);
589 // store the table rotation angle
590 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
591 if (rotateTabularCB->isChecked())
592 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
594 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
595 // store the cell rotation angle
596 string const cell_angle = convert<string>(rotateCellAngleSB->value());
597 if (rotateCellCB->isChecked())
598 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
600 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
602 if (longTabularCB->isChecked())
603 setParam(param_str, Tabular::SET_LONGTABULAR);
605 setParam(param_str, Tabular::UNSET_LONGTABULAR);
607 if (newpageCB->isChecked())
608 setParam(param_str, Tabular::SET_LTNEWPAGE);
610 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
612 if (captionStatusCB->isChecked())
613 setParam(param_str, Tabular::SET_LTCAPTION);
615 setParam(param_str, Tabular::UNSET_LTCAPTION);
617 if (headerStatusCB->isChecked())
618 setParam(param_str, Tabular::SET_LTHEAD, "none");
620 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
622 if (headerBorderAboveCB->isChecked())
623 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
625 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
627 if (headerBorderBelowCB->isChecked())
628 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
630 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
631 if (firstheaderBorderAboveCB->isChecked())
632 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
634 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
635 if (firstheaderBorderBelowCB->isChecked())
636 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
638 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
639 if (firstheaderStatusCB->isChecked())
640 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
642 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
643 if (firstheaderNoContentsCB->isChecked())
644 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
646 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
647 if (footerStatusCB->isChecked())
648 setParam(param_str, Tabular::SET_LTFOOT, "none");
650 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
651 if (footerBorderAboveCB->isChecked())
652 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
654 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
655 if (footerBorderBelowCB->isChecked())
656 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
658 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
659 if (lastfooterStatusCB->isChecked())
660 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
662 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
663 if (lastfooterBorderAboveCB->isChecked())
664 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
666 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
667 if (lastfooterBorderBelowCB->isChecked())
668 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
670 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
671 if (lastfooterNoContentsCB->isChecked())
672 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
674 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
676 if (leftRB->isChecked())
677 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
678 else if (centerRB->isChecked())
679 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
680 else if (rightRB->isChecked())
681 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
683 return from_utf8(param_str);
687 static Length getColumnPWidth(Tabular const & t, size_t cell)
689 return t.column_info[t.cellColumn(cell)].p_width;
693 static Length getMColumnPWidth(Tabular const & t, size_t cell)
695 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
696 return t.cellInfo(cell).p_width;
701 static Length getMROffset(Tabular const & t, size_t cell)
703 if (t.isMultiRow(cell))
704 return t.cellInfo(cell).mroffset;
709 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
711 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
712 return t.cellInfo(cell).align_special;
713 return t.column_info[t.cellColumn(cell)].align_special;
717 void GuiTabular::paramsToDialog(Inset const * inset)
719 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
720 // Copy Tabular of current inset.
721 Tabular const & tabular = itab->tabular;
723 BufferView const * bv = guiApp->currentView()->currentBufferView();
724 size_t const cell = bv->cursor().idx();
726 Tabular::row_type const row = tabular.cellRow(cell);
727 Tabular::col_type const col = tabular.cellColumn(cell);
729 tabularRowED->setText(QString::number(row + 1));
730 tabularColumnED->setText(QString::number(col + 1));
732 bool const multicol = tabular.isMultiColumn(cell);
733 multicolumnCB->setChecked(multicol);
735 bool const multirow = tabular.isMultiRow(cell);
736 multirowCB->setChecked(multirow);
738 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
739 if (rotateCellCB->isChecked()) {
740 if (tabular.getRotateCell(cell) != 0)
741 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
743 rotateCellAngleSB->setValue(90);
746 rotateTabularCB->setChecked(tabular.rotate != 0);
747 if (rotateTabularCB->isChecked())
748 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
750 longTabularCB->setChecked(tabular.is_long_tabular);
752 borders->setTop(tabular.topLine(cell));
753 borders->setBottom(tabular.bottomLine(cell));
754 borders->setLeft(tabular.leftLine(cell));
755 borders->setRight(tabular.rightLine(cell));
756 // repaint the setborder widget
759 Length::UNIT const default_unit = Length::defaultUnit();
761 ///////////////////////////////////
762 // Set width and alignment
764 Length const tabwidth = tabular.tabularWidth();
766 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
767 tabularWidthED->clear();
769 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
770 tabwidth.asString(), default_unit);
775 special = getAlignSpecial(tabular, cell,
776 Tabular::SET_SPECIAL_MULTICOLUMN);
777 pwidth = getMColumnPWidth(tabular, cell);
779 special = getAlignSpecial(tabular, cell,
780 Tabular::SET_SPECIAL_COLUMN);
781 pwidth = getColumnPWidth(tabular, cell);
785 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0"))
786 columnWidthED->clear();
788 colwidth = pwidth.asString();
789 lengthToWidgets(columnWidthED, columnWidthUnitLC,
790 colwidth, default_unit);
794 mroffset = getMROffset(tabular, cell);
797 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
798 multirowOffsetED->clear();
800 offset = mroffset.asString();
801 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
802 offset, default_unit);
804 specialAlignmentED->setText(toqstr(special));
805 ///////////////////////////////////
808 borderDefaultRB->setChecked(!tabular.use_booktabs);
809 booktabsRB->setChecked(tabular.use_booktabs);
811 if (tabular.row_info[row].top_space.empty()
812 && !tabular.row_info[row].top_space_default) {
813 topspaceCO->setCurrentIndex(0);
814 } else if (tabular.row_info[row].top_space_default) {
815 topspaceCO->setCurrentIndex(1);
817 topspaceCO->setCurrentIndex(2);
818 lengthToWidgets(topspaceED,
820 tabular.row_info[row].top_space.asString(),
824 if (tabular.row_info[row].bottom_space.empty()
825 && !tabular.row_info[row].bottom_space_default) {
826 bottomspaceCO->setCurrentIndex(0);
827 } else if (tabular.row_info[row].bottom_space_default) {
828 bottomspaceCO->setCurrentIndex(1);
830 bottomspaceCO->setCurrentIndex(2);
831 lengthToWidgets(bottomspaceED,
833 tabular.row_info[row].bottom_space.asString(),
837 if (tabular.row_info[row].interline_space.empty()
838 && !tabular.row_info[row].interline_space_default) {
839 interlinespaceCO->setCurrentIndex(0);
840 } else if (tabular.row_info[row].interline_space_default) {
841 interlinespaceCO->setCurrentIndex(1);
843 interlinespaceCO->setCurrentIndex(2);
844 lengthToWidgets(interlinespaceED,
845 interlinespaceUnitLC,
846 tabular.row_info[row].interline_space.asString(),
851 hAlignCO->addItem(qt_("Left"), toqstr("left"));
852 hAlignCO->addItem(qt_("Center"), toqstr("center"));
853 hAlignCO->addItem(qt_("Right"), toqstr("right"));
854 if (!multicol && !pwidth.zero())
855 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
856 if (!multicol && !multirow)
857 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
860 switch (tabular.getAlignment(cell)) {
864 case LYX_ALIGN_CENTER:
867 case LYX_ALIGN_RIGHT:
870 case LYX_ALIGN_BLOCK:
872 if (!multicol && !pwidth.zero())
876 case LYX_ALIGN_DECIMAL:
878 if (!multicol && !multirow)
883 // we should never end up here
886 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
889 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
890 if (decimal_point.isEmpty())
891 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
892 decimalPointED->setText(decimal_point);
895 switch (tabular.getVAlignment(cell)) {
896 case Tabular::LYX_VALIGN_TOP:
899 case Tabular::LYX_VALIGN_MIDDLE:
902 case Tabular::LYX_VALIGN_BOTTOM:
911 vAlignCO->setCurrentIndex(valign);
914 switch (tabular.tabular_valignment) {
915 case Tabular::LYX_VALIGN_TOP:
918 case Tabular::LYX_VALIGN_MIDDLE:
921 case Tabular::LYX_VALIGN_BOTTOM:
928 TableAlignCO->setCurrentIndex(tableValign);
930 if (!tabular.is_long_tabular) {
931 headerStatusCB->setChecked(false);
932 headerBorderAboveCB->setChecked(false);
933 headerBorderBelowCB->setChecked(false);
934 firstheaderStatusCB->setChecked(false);
935 firstheaderBorderAboveCB->setChecked(false);
936 firstheaderBorderBelowCB->setChecked(false);
937 firstheaderNoContentsCB->setChecked(false);
938 footerStatusCB->setChecked(false);
939 footerBorderAboveCB->setChecked(false);
940 footerBorderBelowCB->setChecked(false);
941 lastfooterStatusCB->setChecked(false);
942 lastfooterBorderAboveCB->setChecked(false);
943 lastfooterBorderBelowCB->setChecked(false);
944 lastfooterNoContentsCB->setChecked(false);
945 newpageCB->setChecked(false);
946 captionStatusCB->blockSignals(true);
947 captionStatusCB->setChecked(false);
948 captionStatusCB->blockSignals(false);
952 // longtables cannot have a vertical alignment
953 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
955 switch (tabular.longtabular_alignment) {
956 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
957 leftRB->setChecked(true);
959 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
960 centerRB->setChecked(true);
962 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
963 rightRB->setChecked(true);
966 centerRB->setChecked(true);
969 captionStatusCB->blockSignals(true);
970 captionStatusCB->setChecked(tabular.ltCaption(row));
971 captionStatusCB->blockSignals(false);
975 bool row_set = tabular.getRowOfLTHead(row, ltt);
976 headerStatusCB->setChecked(row_set);
978 headerBorderAboveCB->setChecked(ltt.topDL);
979 headerBorderBelowCB->setChecked(ltt.bottomDL);
982 headerBorderAboveCB->setChecked(false);
983 headerBorderBelowCB->setChecked(false);
984 firstheaderNoContentsCB->setChecked(false);
988 row_set = tabular.getRowOfLTFirstHead(row, ltt);
989 firstheaderStatusCB->setChecked(row_set);
990 if (ltt.set && (!ltt.empty || !use_empty)) {
991 firstheaderBorderAboveCB->setChecked(ltt.topDL);
992 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
994 firstheaderBorderAboveCB->setChecked(false);
995 firstheaderBorderBelowCB->setChecked(false);
998 row_set = tabular.getRowOfLTFoot(row, ltt);
999 footerStatusCB->setChecked(row_set);
1001 footerBorderAboveCB->setChecked(ltt.topDL);
1002 footerBorderBelowCB->setChecked(ltt.bottomDL);
1005 footerBorderAboveCB->setChecked(false);
1006 footerBorderBelowCB->setChecked(false);
1007 lastfooterNoContentsCB->setChecked(false);
1011 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1012 lastfooterStatusCB->setChecked(row_set);
1013 if (ltt.set && (!ltt.empty || !use_empty)) {
1014 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1015 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1017 lastfooterBorderAboveCB->setChecked(false);
1018 lastfooterBorderBelowCB->setChecked(false);
1020 newpageCB->setChecked(tabular.getLTNewPage(row));
1022 // first header can only be suppressed when there is a header
1023 firstheader_suppressable_ = tabular.haveLTHead()
1024 && !tabular.haveLTFirstHead();
1025 // last footer can only be suppressed when there is a footer
1026 lastfooter_suppressable_ = tabular.haveLTFoot()
1027 && !tabular.haveLTLastFoot();
1029 // after setting the features, check if they are enabled
1034 bool GuiTabular::checkWidgets(bool readonly) const
1036 tabularRowED->setReadOnly(readonly);
1037 tabularColumnED->setReadOnly(readonly);
1038 tabularWidthED->setReadOnly(readonly);
1039 specialAlignmentED->setReadOnly(readonly);
1040 columnWidthED->setReadOnly(readonly);
1041 multirowOffsetED->setReadOnly(readonly);
1042 decimalPointED->setReadOnly(readonly);
1045 multicolumnCB->setEnabled(false);
1046 multirowCB->setEnabled(false);
1047 rotateCellCB->setEnabled(false);
1048 rotateCellAngleSB->setEnabled(false);
1049 rotateTabularCB->setEnabled(false);
1050 rotateTabularAngleSB->setEnabled(false);
1051 longTabularCB->setEnabled(false);
1052 borders->setEnabled(false);
1053 tabularWidthUnitLC->setEnabled(false);
1054 columnWidthUnitLC->setEnabled(false);
1055 multirowOffsetUnitLC->setEnabled(false);
1056 setBordersGB->setEnabled(false);
1057 allBordersGB->setEnabled(false);
1058 borderStyleGB->setEnabled(false);
1059 booktabsRB->setEnabled(false);
1060 topspaceCO->setEnabled(false);
1061 topspaceUnitLC->setEnabled(false);
1062 bottomspaceCO->setEnabled(false);
1063 bottomspaceUnitLC->setEnabled(false);
1064 interlinespaceCO->setEnabled(false);
1065 interlinespaceUnitLC->setEnabled(false);
1066 hAlignCO->setEnabled(false);
1067 vAlignCO->setEnabled(false);
1068 TableAlignCO->setEnabled(false);
1069 longtableGB->setEnabled(false);
1070 alignmentGB->setEnabled(false);
1074 return InsetParamsWidget::checkWidgets();
1078 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1080 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1081 return getStatus(r).enabled();
1085 } // namespace frontend
1088 #include "moc_GuiTabular.cpp"