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(columnTypeCO, SIGNAL(activated(int)),
135 this, SLOT(checkEnabled()));
136 connect(columnWidthED, SIGNAL(textEdited(const QString &)),
137 this, SLOT(checkEnabled()));
138 connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
139 this, SLOT(checkEnabled()));
140 connect(borders, SIGNAL(topSet(bool)),
141 this, SLOT(checkEnabled()));
142 connect(borders, SIGNAL(bottomSet(bool)),
143 this, SLOT(checkEnabled()));
144 connect(borders, SIGNAL(rightSet(bool)),
145 this, SLOT(checkEnabled()));
146 connect(borders, SIGNAL(leftSet(bool)),
147 this, SLOT(checkEnabled()));
148 connect(rotateTabularCB, SIGNAL(clicked()),
149 this, SLOT(checkEnabled()));
150 connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
151 this, SLOT(checkEnabled()));
152 connect(rotateCellCB, SIGNAL(clicked()),
153 this, SLOT(checkEnabled()));
154 connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
155 this, SLOT(checkEnabled()));
156 connect(TableAlignCO, SIGNAL(activated(int)),
157 this, SLOT(checkEnabled()));
158 connect(longTabularCB, SIGNAL(clicked()),
159 this, SLOT(checkEnabled()));
160 connect(leftRB, SIGNAL(clicked()),
161 this, SLOT(checkEnabled()));
162 connect(centerRB, SIGNAL(clicked()),
163 this, SLOT(checkEnabled()));
164 connect(rightRB, SIGNAL(clicked()),
165 this, SLOT(checkEnabled()));
166 connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
167 this, SLOT(checkEnabled()));
169 decimalPointED->setInputMask("X; ");
170 decimalPointED->setMaxLength(1);
172 // initialize the length validator
173 addCheckedWidget(columnWidthED, columnWidthLA);
174 addCheckedWidget(multirowOffsetED, multirowOffsetLA);
175 addCheckedWidget(topspaceED, topspaceLA);
176 addCheckedWidget(bottomspaceED, bottomspaceLA);
177 addCheckedWidget(interlinespaceED, interlinespaceLA);
178 addCheckedWidget(tabularWidthED, tabularWidthLA);
182 void GuiTabular::on_topspaceCO_activated(int index)
184 bool const enable = (index == 2);
185 topspaceED->setEnabled(enable);
186 topspaceUnitLC->setEnabled(enable);
190 void GuiTabular::on_bottomspaceCO_activated(int index)
192 bool const enable = (index == 2);
193 bottomspaceED->setEnabled(enable);
194 bottomspaceUnitLC->setEnabled(enable);
198 void GuiTabular::on_interlinespaceCO_activated(int index)
200 bool const enable = (index == 2);
201 interlinespaceED->setEnabled(enable);
202 interlinespaceUnitLC->setEnabled(enable);
206 void GuiTabular::enableWidgets() const
208 // if there is a LaTeX argument, the width and alignment will be overwritten
209 // therefore disable them in this case
210 bool const fixed = specialAlignmentED->text().isEmpty()
211 && columnTypeCO->currentIndex() == 2;
212 columnWidthED->setEnabled(fixed);
213 columnWidthUnitLC->setEnabled(fixed);
214 // if the column has a width, multirows are always left-aligned
215 // therefore disable hAlignCB in this case
216 hAlignCO->setEnabled(!(multirowCB->isChecked()
217 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
218 && specialAlignmentED->text().isEmpty());
219 // decimal alignment is only possible for non-multicol and non-multirow cells
220 if ((multicolumnCB->isChecked() || multirowCB->isChecked() || columnTypeCO->currentIndex() == 1)
221 && hAlignCO->findData(toqstr("decimal")))
222 hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
223 else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
224 && hAlignCO->findData(toqstr("decimal")) == -1)
225 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
227 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
228 decimalPointED->setEnabled(dalign);
229 decimalLA->setEnabled(dalign);
231 bool const setwidth = TableAlignCO->currentText() == qt_("Middle");
232 tabularWidthLA->setEnabled(setwidth);
233 tabularWidthED->setEnabled(setwidth);
234 tabularWidthUnitLC->setEnabled(setwidth);
236 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked()
237 && !longTabularCB->isChecked());
238 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
240 bool const enable_valign =
241 !multirowCB->isChecked()
242 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
243 && specialAlignmentED->text().isEmpty();
244 vAlignCO->setEnabled(enable_valign);
245 vAlignLA->setEnabled(enable_valign);
247 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
248 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
249 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
250 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
251 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
252 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
253 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
255 // setting as longtable is not allowed when table is inside a float
256 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
257 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
258 bool const longtabular = longTabularCB->isChecked();
259 longtableGB->setEnabled(true);
260 newpageCB->setEnabled(longtabular);
261 alignmentGB->setEnabled(longtabular);
262 // longtables and tabular* cannot have a vertical alignment
263 TableAlignLA->setDisabled(is_tabular_star || longtabular);
264 TableAlignCO->setDisabled(is_tabular_star || longtabular);
265 // longtable cannot be rotated with rotating package, only
266 // with [pdf]lscape, which only supports 90 deg.
267 rotateTabularAngleSB->setDisabled(longtabular);
269 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
270 // depending on the cursor position is very very unintuitive...
271 // We need some edit boxes to show which rows are header/footer/etc
272 // without having to move the cursor first.
273 headerStatusCB->setEnabled(longtabular
274 && (headerStatusCB->isChecked() ?
275 funcEnabled(Tabular::UNSET_LTHEAD) :
276 funcEnabled(Tabular::SET_LTHEAD)));
277 headerBorderAboveCB->setEnabled(longtabular
278 && headerStatusCB->isChecked());
279 headerBorderBelowCB->setEnabled(longtabular
280 && headerStatusCB->isChecked());
282 // first header can only be suppressed when there is a header
283 // firstheader_suppressable_ is set in paramsToDialog
284 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
285 // check if setting a first header is allowed
286 // additionally check firstheaderNoContentsCB because when this is
287 // the case a first header makes no sense
288 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
289 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
290 funcEnabled(Tabular::SET_LTFIRSTHEAD))
291 && longtabular && !firstheaderNoContentsCB->isChecked());
292 firstheaderBorderAboveCB->setEnabled(longtabular
293 && firstheaderStatusCB->isChecked());
294 firstheaderBorderBelowCB->setEnabled(longtabular
295 && firstheaderStatusCB->isChecked());
297 footerStatusCB->setEnabled(longtabular
298 && (footerStatusCB->isChecked() ?
299 funcEnabled(Tabular::UNSET_LTFOOT) :
300 funcEnabled(Tabular::SET_LTFOOT)));
301 footerBorderAboveCB->setEnabled(longtabular
302 && footerBorderAboveCB->isChecked());
303 footerBorderBelowCB->setEnabled(longtabular
304 && footerBorderAboveCB->isChecked());
306 // last footer can only be suppressed when there is a footer
307 // lastfooter_suppressable_ is set in paramsToDialog
308 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
309 // check if setting a last footer is allowed
310 // additionally check lastfooterNoContentsCB because when this is
311 // the case a last footer makes no sense
312 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
313 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
314 funcEnabled(Tabular::SET_LTLASTFOOT))
315 && longtabular && !lastfooterNoContentsCB->isChecked());
316 lastfooterBorderAboveCB->setEnabled(longtabular
317 && lastfooterBorderAboveCB->isChecked());
318 lastfooterBorderBelowCB->setEnabled(longtabular
319 && lastfooterBorderAboveCB->isChecked());
321 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
324 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
325 && !dalign && !multirowCB->isChecked());
326 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
327 && !dalign && !multicolumnCB->isChecked());
328 bool const enable_mr = multirowCB->isChecked();
329 multirowOffsetLA->setEnabled(enable_mr);
330 multirowOffsetED->setEnabled(enable_mr);
331 multirowOffsetUnitLC->setEnabled(enable_mr);
333 // Vertical lines cannot be set in formal tables
334 borders->setLeftEnabled(!booktabsRB->isChecked());
335 borders->setRightEnabled(!booktabsRB->isChecked());
339 void GuiTabular::checkEnabled()
346 void GuiTabular::borderSet_clicked()
348 borders->setTop(true);
349 borders->setBottom(true);
350 borders->setLeft(true);
351 borders->setRight(true);
352 // repaint the setborder widget
358 void GuiTabular::borderUnset_clicked()
360 borders->setTop(false);
361 borders->setBottom(false);
362 borders->setLeft(false);
363 borders->setRight(false);
364 // repaint the setborder widget
370 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
373 param_str += featureAsString(f) + ' ' + arg;
377 void GuiTabular::setHAlign(string & param_str) const
379 Tabular::Feature num = Tabular::ALIGN_LEFT;
380 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
382 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
383 if (align == "left") {
384 num = Tabular::ALIGN_LEFT;
385 multi_num = Tabular::M_ALIGN_LEFT;
386 } else if (align == "center") {
387 num = Tabular::ALIGN_CENTER;
388 multi_num = Tabular::M_ALIGN_CENTER;
389 } else if (align == "right") {
390 num = Tabular::ALIGN_RIGHT;
391 multi_num = Tabular::M_ALIGN_RIGHT;
392 } else if (align == "justified") {
393 num = Tabular::ALIGN_BLOCK;
394 //multi_num: no equivalent
395 } else if (align == "decimal") {
396 num = Tabular::ALIGN_DECIMAL;
397 //multi_num: no equivalent
400 if (multicolumnCB->isChecked())
401 setParam(param_str, multi_num);
403 setParam(param_str, num);
407 void GuiTabular::setVAlign(string & param_str) const
409 int const align = vAlignCO->currentIndex();
410 enum VALIGN { TOP, MIDDLE, BOTTOM };
414 case 0: v = TOP; break;
415 case 1: v = MIDDLE; break;
416 case 2: v = BOTTOM; break;
419 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
420 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
424 num = Tabular::VALIGN_TOP;
425 multi_num = Tabular::M_VALIGN_TOP;
428 num = Tabular::VALIGN_MIDDLE;
429 multi_num = Tabular::M_VALIGN_MIDDLE;
432 num = Tabular::VALIGN_BOTTOM;
433 multi_num = Tabular::M_VALIGN_BOTTOM;
436 if (multicolumnCB->isChecked() || multirowCB->isChecked())
437 setParam(param_str, multi_num);
439 setParam(param_str, num);
443 void GuiTabular::setTableAlignment(string & param_str) const
445 int const align = TableAlignCO->currentIndex();
447 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
449 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
451 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
457 docstring GuiTabular::dialogToParams() const
459 string param_str = "tabular";
462 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
463 if (tabwidth.empty())
465 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
467 // apply the fixed width values
468 // this must be done before applying the column alignment
469 // because its value influences the alignment of multirow cells
470 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
471 if (width.empty() || columnTypeCO->currentIndex() != 2)
473 if (multicolumnCB->isChecked())
474 setParam(param_str, Tabular::SET_MPWIDTH, width);
476 setParam(param_str, Tabular::SET_PWIDTH, width);
478 bool const varwidth = specialAlignmentED->text().isEmpty()
479 && columnTypeCO->currentIndex() == 1;
481 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "on");
483 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "off");
485 // apply the column alignment
486 // multirows inherit the alignment from the column; if a column width
487 // is set, multirows are always left-aligned so that in this case
488 // its alignment must not be applied (see bug #8084)
489 if (!(multirowCB->isChecked() && width != "0pt"))
490 setHAlign(param_str);
492 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
493 string decimal_point = fromqstr(decimalPointED->text());
494 if (decimal_point.empty())
495 decimal_point = lyxrc.default_decimal_point;
496 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
498 setVAlign(param_str);
499 setTableAlignment(param_str);
501 if (booktabsRB->isChecked())
502 setParam(param_str, Tabular::SET_BOOKTABS);
504 setParam(param_str, Tabular::UNSET_BOOKTABS);
507 switch (topspaceCO->currentIndex()) {
509 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
512 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
515 if (!topspaceED->text().isEmpty())
516 setParam(param_str, Tabular::SET_TOP_SPACE,
517 widgetsToLength(topspaceED, topspaceUnitLC));
522 switch (bottomspaceCO->currentIndex()) {
524 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
527 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
530 if (!bottomspaceED->text().isEmpty())
531 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
532 widgetsToLength(bottomspaceED,
538 switch (interlinespaceCO->currentIndex()) {
540 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
543 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
546 if (!interlinespaceED->text().isEmpty())
547 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
548 widgetsToLength(interlinespaceED,
549 interlinespaceUnitLC));
554 if (borders->getTop() && borders->getBottom() && borders->getLeft()
555 && borders->getRight())
556 setParam(param_str, Tabular::SET_ALL_LINES);
557 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
558 && !borders->getRight())
559 setParam(param_str, Tabular::UNSET_ALL_LINES);
561 setParam(param_str, Tabular::SET_LINE_LEFT,
562 borders->getLeft() ? "true" : "false");
563 setParam(param_str, Tabular::SET_LINE_RIGHT,
564 borders->getRight() ? "true" : "false");
565 setParam(param_str, Tabular::SET_LINE_TOP,
566 borders->getTop() ? "true" : "false");
567 setParam(param_str, Tabular::SET_LINE_BOTTOM,
568 borders->getBottom() ? "true" : "false");
571 // apply the special alignment
572 string special = fromqstr(specialAlignmentED->text());
575 if (multicolumnCB->isChecked())
576 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
578 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
581 if (multicolumnCB->isChecked())
582 setParam(param_str, Tabular::SET_MULTICOLUMN);
584 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
586 // apply the multirow offset
587 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
588 if (mroffset.empty())
590 if (multirowCB->isChecked())
591 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
593 if (multirowCB->isChecked())
594 setParam(param_str, Tabular::SET_MULTIROW);
596 setParam(param_str, Tabular::UNSET_MULTIROW);
597 // store the table rotation angle
598 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
599 if (rotateTabularCB->isChecked())
600 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
602 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
603 // store the cell rotation angle
604 string const cell_angle = convert<string>(rotateCellAngleSB->value());
605 if (rotateCellCB->isChecked())
606 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
608 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
610 if (longTabularCB->isChecked())
611 setParam(param_str, Tabular::SET_LONGTABULAR);
613 setParam(param_str, Tabular::UNSET_LONGTABULAR);
615 if (newpageCB->isChecked())
616 setParam(param_str, Tabular::SET_LTNEWPAGE);
618 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
620 if (captionStatusCB->isChecked())
621 setParam(param_str, Tabular::SET_LTCAPTION);
623 setParam(param_str, Tabular::UNSET_LTCAPTION);
625 if (headerStatusCB->isChecked())
626 setParam(param_str, Tabular::SET_LTHEAD, "none");
628 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
630 if (headerBorderAboveCB->isChecked())
631 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
633 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
635 if (headerBorderBelowCB->isChecked())
636 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
638 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
639 if (firstheaderBorderAboveCB->isChecked())
640 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
642 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
643 if (firstheaderBorderBelowCB->isChecked())
644 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
646 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
647 if (firstheaderStatusCB->isChecked())
648 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
650 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
651 if (firstheaderNoContentsCB->isChecked())
652 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
654 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
655 if (footerStatusCB->isChecked())
656 setParam(param_str, Tabular::SET_LTFOOT, "none");
658 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
659 if (footerBorderAboveCB->isChecked())
660 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
662 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
663 if (footerBorderBelowCB->isChecked())
664 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
666 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
667 if (lastfooterStatusCB->isChecked())
668 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
670 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
671 if (lastfooterBorderAboveCB->isChecked())
672 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
674 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
675 if (lastfooterBorderBelowCB->isChecked())
676 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
678 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
679 if (lastfooterNoContentsCB->isChecked())
680 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
682 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
684 if (leftRB->isChecked())
685 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
686 else if (centerRB->isChecked())
687 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
688 else if (rightRB->isChecked())
689 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
691 return from_utf8(param_str);
695 static Length getColumnPWidth(Tabular const & t, size_t cell)
697 return t.column_info[t.cellColumn(cell)].p_width;
701 static Length getMColumnPWidth(Tabular const & t, size_t cell)
703 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
704 return t.cellInfo(cell).p_width;
709 static Length getMROffset(Tabular const & t, size_t cell)
711 if (t.isMultiRow(cell))
712 return t.cellInfo(cell).mroffset;
717 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
719 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
720 return t.cellInfo(cell).align_special;
721 return t.column_info[t.cellColumn(cell)].align_special;
725 void GuiTabular::paramsToDialog(Inset const * inset)
727 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
728 // Copy Tabular of current inset.
729 Tabular const & tabular = itab->tabular;
731 BufferView const * bv = guiApp->currentView()->currentBufferView();
732 size_t const cell = bv->cursor().idx();
734 Tabular::row_type const row = tabular.cellRow(cell);
735 Tabular::col_type const col = tabular.cellColumn(cell);
737 tabularRowED->setText(QString::number(row + 1));
738 tabularColumnED->setText(QString::number(col + 1));
740 bool const multicol = tabular.isMultiColumn(cell);
741 multicolumnCB->setChecked(multicol);
743 bool const multirow = tabular.isMultiRow(cell);
744 multirowCB->setChecked(multirow);
746 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
747 if (rotateCellCB->isChecked()) {
748 if (tabular.getRotateCell(cell) != 0)
749 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
751 rotateCellAngleSB->setValue(90);
754 longTabularCB->setChecked(tabular.is_long_tabular);
756 rotateTabularCB->setChecked(tabular.rotate != 0);
757 if (rotateTabularCB->isChecked()) {
758 if (longTabularCB->isChecked())
759 rotateTabularAngleSB->setValue(90);
761 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
764 borders->setTop(tabular.topLine(cell));
765 borders->setBottom(tabular.bottomLine(cell));
766 borders->setLeft(tabular.leftLine(cell));
767 borders->setRight(tabular.rightLine(cell));
768 // repaint the setborder widget
771 Length::UNIT const default_unit = Length::defaultUnit();
773 ///////////////////////////////////
774 // Set width and alignment
776 Length const tabwidth = tabular.tabularWidth();
778 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
779 tabularWidthED->clear();
781 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
782 tabwidth.asString(), default_unit);
787 special = getAlignSpecial(tabular, cell,
788 Tabular::SET_SPECIAL_MULTICOLUMN);
789 pwidth = getMColumnPWidth(tabular, cell);
791 special = getAlignSpecial(tabular, cell,
792 Tabular::SET_SPECIAL_COLUMN);
793 pwidth = getColumnPWidth(tabular, cell);
795 bool const varwidth = tabular.column_info[tabular.cellColumn(cell)].varwidth;
797 columnTypeCO->setCurrentIndex(1);
800 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0")) {
801 columnWidthED->clear();
803 columnTypeCO->setCurrentIndex(0);
805 colwidth = pwidth.asString();
806 lengthToWidgets(columnWidthED, columnWidthUnitLC,
807 colwidth, default_unit);
808 columnTypeCO->setCurrentIndex(2);
812 mroffset = getMROffset(tabular, cell);
815 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
816 multirowOffsetED->clear();
818 offset = mroffset.asString();
819 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
820 offset, default_unit);
822 specialAlignmentED->setText(toqstr(special));
823 ///////////////////////////////////
826 borderDefaultRB->setChecked(!tabular.use_booktabs);
827 booktabsRB->setChecked(tabular.use_booktabs);
829 if (tabular.row_info[row].top_space.empty()
830 && !tabular.row_info[row].top_space_default) {
831 topspaceCO->setCurrentIndex(0);
832 } else if (tabular.row_info[row].top_space_default) {
833 topspaceCO->setCurrentIndex(1);
835 topspaceCO->setCurrentIndex(2);
836 lengthToWidgets(topspaceED,
838 tabular.row_info[row].top_space.asString(),
842 if (tabular.row_info[row].bottom_space.empty()
843 && !tabular.row_info[row].bottom_space_default) {
844 bottomspaceCO->setCurrentIndex(0);
845 } else if (tabular.row_info[row].bottom_space_default) {
846 bottomspaceCO->setCurrentIndex(1);
848 bottomspaceCO->setCurrentIndex(2);
849 lengthToWidgets(bottomspaceED,
851 tabular.row_info[row].bottom_space.asString(),
855 if (tabular.row_info[row].interline_space.empty()
856 && !tabular.row_info[row].interline_space_default) {
857 interlinespaceCO->setCurrentIndex(0);
858 } else if (tabular.row_info[row].interline_space_default) {
859 interlinespaceCO->setCurrentIndex(1);
861 interlinespaceCO->setCurrentIndex(2);
862 lengthToWidgets(interlinespaceED,
863 interlinespaceUnitLC,
864 tabular.row_info[row].interline_space.asString(),
869 hAlignCO->addItem(qt_("Left"), toqstr("left"));
870 hAlignCO->addItem(qt_("Center"), toqstr("center"));
871 hAlignCO->addItem(qt_("Right"), toqstr("right"));
872 if (!multicol && !pwidth.zero())
873 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
874 if (!multicol && !multirow)
875 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
878 switch (tabular.getAlignment(cell)) {
882 case LYX_ALIGN_CENTER:
885 case LYX_ALIGN_RIGHT:
888 case LYX_ALIGN_BLOCK:
890 if (!multicol && !pwidth.zero())
894 case LYX_ALIGN_DECIMAL:
896 if (!multicol && !multirow)
901 // we should never end up here
904 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
907 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
908 if (decimal_point.isEmpty())
909 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
910 decimalPointED->setText(decimal_point);
913 switch (tabular.getVAlignment(cell)) {
914 case Tabular::LYX_VALIGN_TOP:
917 case Tabular::LYX_VALIGN_MIDDLE:
920 case Tabular::LYX_VALIGN_BOTTOM:
929 vAlignCO->setCurrentIndex(valign);
932 switch (tabular.tabular_valignment) {
933 case Tabular::LYX_VALIGN_TOP:
936 case Tabular::LYX_VALIGN_MIDDLE:
939 case Tabular::LYX_VALIGN_BOTTOM:
946 TableAlignCO->setCurrentIndex(tableValign);
948 if (!tabular.is_long_tabular) {
949 headerStatusCB->setChecked(false);
950 headerBorderAboveCB->setChecked(false);
951 headerBorderBelowCB->setChecked(false);
952 firstheaderStatusCB->setChecked(false);
953 firstheaderBorderAboveCB->setChecked(false);
954 firstheaderBorderBelowCB->setChecked(false);
955 firstheaderNoContentsCB->setChecked(false);
956 footerStatusCB->setChecked(false);
957 footerBorderAboveCB->setChecked(false);
958 footerBorderBelowCB->setChecked(false);
959 lastfooterStatusCB->setChecked(false);
960 lastfooterBorderAboveCB->setChecked(false);
961 lastfooterBorderBelowCB->setChecked(false);
962 lastfooterNoContentsCB->setChecked(false);
963 newpageCB->setChecked(false);
964 captionStatusCB->blockSignals(true);
965 captionStatusCB->setChecked(false);
966 captionStatusCB->blockSignals(false);
970 // longtables cannot have a vertical alignment
971 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
973 switch (tabular.longtabular_alignment) {
974 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
975 leftRB->setChecked(true);
977 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
978 centerRB->setChecked(true);
980 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
981 rightRB->setChecked(true);
984 centerRB->setChecked(true);
987 captionStatusCB->blockSignals(true);
988 captionStatusCB->setChecked(tabular.ltCaption(row));
989 captionStatusCB->blockSignals(false);
993 bool row_set = tabular.getRowOfLTHead(row, ltt);
994 headerStatusCB->setChecked(row_set);
996 headerBorderAboveCB->setChecked(ltt.topDL);
997 headerBorderBelowCB->setChecked(ltt.bottomDL);
1000 headerBorderAboveCB->setChecked(false);
1001 headerBorderBelowCB->setChecked(false);
1002 firstheaderNoContentsCB->setChecked(false);
1006 row_set = tabular.getRowOfLTFirstHead(row, ltt);
1007 firstheaderStatusCB->setChecked(row_set);
1008 if (ltt.set && (!ltt.empty || !use_empty)) {
1009 firstheaderBorderAboveCB->setChecked(ltt.topDL);
1010 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
1012 firstheaderBorderAboveCB->setChecked(false);
1013 firstheaderBorderBelowCB->setChecked(false);
1016 row_set = tabular.getRowOfLTFoot(row, ltt);
1017 footerStatusCB->setChecked(row_set);
1019 footerBorderAboveCB->setChecked(ltt.topDL);
1020 footerBorderBelowCB->setChecked(ltt.bottomDL);
1023 footerBorderAboveCB->setChecked(false);
1024 footerBorderBelowCB->setChecked(false);
1025 lastfooterNoContentsCB->setChecked(false);
1029 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1030 lastfooterStatusCB->setChecked(row_set);
1031 if (ltt.set && (!ltt.empty || !use_empty)) {
1032 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1033 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1035 lastfooterBorderAboveCB->setChecked(false);
1036 lastfooterBorderBelowCB->setChecked(false);
1038 newpageCB->setChecked(tabular.getLTNewPage(row));
1040 // first header can only be suppressed when there is a header
1041 firstheader_suppressable_ = tabular.haveLTHead()
1042 && !tabular.haveLTFirstHead();
1043 // last footer can only be suppressed when there is a footer
1044 lastfooter_suppressable_ = tabular.haveLTFoot()
1045 && !tabular.haveLTLastFoot();
1047 // after setting the features, check if they are enabled
1052 bool GuiTabular::checkWidgets(bool readonly) const
1054 tabularRowED->setReadOnly(readonly);
1055 tabularColumnED->setReadOnly(readonly);
1056 tabularWidthED->setReadOnly(readonly);
1057 specialAlignmentED->setReadOnly(readonly);
1058 columnWidthED->setReadOnly(readonly);
1059 multirowOffsetED->setReadOnly(readonly);
1060 decimalPointED->setReadOnly(readonly);
1063 multicolumnCB->setEnabled(false);
1064 multirowCB->setEnabled(false);
1065 rotateCellCB->setEnabled(false);
1066 rotateCellAngleSB->setEnabled(false);
1067 rotateTabularCB->setEnabled(false);
1068 rotateTabularAngleSB->setEnabled(false);
1069 longTabularCB->setEnabled(false);
1070 borders->setEnabled(false);
1071 tabularWidthUnitLC->setEnabled(false);
1072 columnWidthUnitLC->setEnabled(false);
1073 columnTypeCO->setEnabled(false);
1074 multirowOffsetUnitLC->setEnabled(false);
1075 setBordersGB->setEnabled(false);
1076 allBordersGB->setEnabled(false);
1077 borderStyleGB->setEnabled(false);
1078 booktabsRB->setEnabled(false);
1079 topspaceCO->setEnabled(false);
1080 topspaceUnitLC->setEnabled(false);
1081 bottomspaceCO->setEnabled(false);
1082 bottomspaceUnitLC->setEnabled(false);
1083 interlinespaceCO->setEnabled(false);
1084 interlinespaceUnitLC->setEnabled(false);
1085 hAlignCO->setEnabled(false);
1086 vAlignCO->setEnabled(false);
1087 TableAlignCO->setEnabled(false);
1088 longtableGB->setEnabled(false);
1089 alignmentGB->setEnabled(false);
1093 return InsetParamsWidget::checkWidgets();
1097 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1099 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1100 return getStatus(r).enabled();
1104 } // namespace frontend
1107 #include "moc_GuiTabular.cpp"