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);
262 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
263 // depending on the cursor position is very very unintuitive...
264 // We need some edit boxes to show which rows are header/footer/etc
265 // without having to move the cursor first.
266 headerStatusCB->setEnabled(longtabular
267 && (headerStatusCB->isChecked() ?
268 funcEnabled(Tabular::UNSET_LTHEAD) :
269 funcEnabled(Tabular::SET_LTHEAD)));
270 headerBorderAboveCB->setEnabled(longtabular
271 && headerStatusCB->isChecked());
272 headerBorderBelowCB->setEnabled(longtabular
273 && headerStatusCB->isChecked());
275 // first header can only be suppressed when there is a header
276 // firstheader_suppressable_ is set in paramsToDialog
277 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
278 // check if setting a first header is allowed
279 // additionally check firstheaderNoContentsCB because when this is
280 // the case a first header makes no sense
281 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
282 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
283 funcEnabled(Tabular::SET_LTFIRSTHEAD))
284 && longtabular && !firstheaderNoContentsCB->isChecked());
285 firstheaderBorderAboveCB->setEnabled(longtabular
286 && firstheaderStatusCB->isChecked());
287 firstheaderBorderBelowCB->setEnabled(longtabular
288 && firstheaderStatusCB->isChecked());
290 footerStatusCB->setEnabled(longtabular
291 && (footerStatusCB->isChecked() ?
292 funcEnabled(Tabular::UNSET_LTFOOT) :
293 funcEnabled(Tabular::SET_LTFOOT)));
294 footerBorderAboveCB->setEnabled(longtabular
295 && footerBorderAboveCB->isChecked());
296 footerBorderBelowCB->setEnabled(longtabular
297 && footerBorderAboveCB->isChecked());
299 // last footer can only be suppressed when there is a footer
300 // lastfooter_suppressable_ is set in paramsToDialog
301 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
302 // check if setting a last footer is allowed
303 // additionally check lastfooterNoContentsCB because when this is
304 // the case a last footer makes no sense
305 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
306 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
307 funcEnabled(Tabular::SET_LTLASTFOOT))
308 && longtabular && !lastfooterNoContentsCB->isChecked());
309 lastfooterBorderAboveCB->setEnabled(longtabular
310 && lastfooterBorderAboveCB->isChecked());
311 lastfooterBorderBelowCB->setEnabled(longtabular
312 && lastfooterBorderAboveCB->isChecked());
314 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
317 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
318 && !dalign && !multirowCB->isChecked());
319 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
320 && !dalign && !multicolumnCB->isChecked());
321 bool const enable_mr = multirowCB->isChecked();
322 multirowOffsetLA->setEnabled(enable_mr);
323 multirowOffsetED->setEnabled(enable_mr);
324 multirowOffsetUnitLC->setEnabled(enable_mr);
326 // Vertical lines cannot be set in formal tables
327 borders->setLeftEnabled(!booktabsRB->isChecked());
328 borders->setRightEnabled(!booktabsRB->isChecked());
332 void GuiTabular::checkEnabled()
339 void GuiTabular::borderSet_clicked()
341 borders->setTop(true);
342 borders->setBottom(true);
343 borders->setLeft(true);
344 borders->setRight(true);
345 // repaint the setborder widget
351 void GuiTabular::borderUnset_clicked()
353 borders->setTop(false);
354 borders->setBottom(false);
355 borders->setLeft(false);
356 borders->setRight(false);
357 // repaint the setborder widget
363 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
366 param_str += featureAsString(f) + ' ' + arg;
370 void GuiTabular::setHAlign(string & param_str) const
372 Tabular::Feature num = Tabular::ALIGN_LEFT;
373 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
375 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
376 if (align == "left") {
377 num = Tabular::ALIGN_LEFT;
378 multi_num = Tabular::M_ALIGN_LEFT;
379 } else if (align == "center") {
380 num = Tabular::ALIGN_CENTER;
381 multi_num = Tabular::M_ALIGN_CENTER;
382 } else if (align == "right") {
383 num = Tabular::ALIGN_RIGHT;
384 multi_num = Tabular::M_ALIGN_RIGHT;
385 } else if (align == "justified") {
386 num = Tabular::ALIGN_BLOCK;
387 //multi_num: no equivalent
388 } else if (align == "decimal") {
389 num = Tabular::ALIGN_DECIMAL;
390 //multi_num: no equivalent
393 if (multicolumnCB->isChecked())
394 setParam(param_str, multi_num);
396 setParam(param_str, num);
400 void GuiTabular::setVAlign(string & param_str) const
402 int const align = vAlignCO->currentIndex();
403 enum VALIGN { TOP, MIDDLE, BOTTOM };
407 case 0: v = TOP; break;
408 case 1: v = MIDDLE; break;
409 case 2: v = BOTTOM; break;
412 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
413 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
417 num = Tabular::VALIGN_TOP;
418 multi_num = Tabular::M_VALIGN_TOP;
421 num = Tabular::VALIGN_MIDDLE;
422 multi_num = Tabular::M_VALIGN_MIDDLE;
425 num = Tabular::VALIGN_BOTTOM;
426 multi_num = Tabular::M_VALIGN_BOTTOM;
429 if (multicolumnCB->isChecked() || multirowCB->isChecked())
430 setParam(param_str, multi_num);
432 setParam(param_str, num);
436 void GuiTabular::setTableAlignment(string & param_str) const
438 int const align = TableAlignCO->currentIndex();
440 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
442 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
444 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
450 docstring GuiTabular::dialogToParams() const
452 string param_str = "tabular";
455 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
456 if (tabwidth.empty())
458 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
460 // apply the fixed width values
461 // this must be done before applying the column alignment
462 // because its value influences the alignment of multirow cells
463 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
466 if (multicolumnCB->isChecked())
467 setParam(param_str, Tabular::SET_MPWIDTH, width);
469 setParam(param_str, Tabular::SET_PWIDTH, width);
471 // apply the column alignment
472 // multirows inherit the alignment from the column; if a column width
473 // is set, multirows are always left-aligned so that in this case
474 // its alignment must not be applied (see bug #8084)
475 if (!(multirowCB->isChecked() && width != "0pt"))
476 setHAlign(param_str);
478 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
479 string decimal_point = fromqstr(decimalPointED->text());
480 if (decimal_point.empty())
481 decimal_point = lyxrc.default_decimal_point;
482 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
484 setVAlign(param_str);
485 setTableAlignment(param_str);
487 if (booktabsRB->isChecked())
488 setParam(param_str, Tabular::SET_BOOKTABS);
490 setParam(param_str, Tabular::UNSET_BOOKTABS);
493 switch (topspaceCO->currentIndex()) {
495 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
498 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
501 if (!topspaceED->text().isEmpty())
502 setParam(param_str, Tabular::SET_TOP_SPACE,
503 widgetsToLength(topspaceED, topspaceUnitLC));
508 switch (bottomspaceCO->currentIndex()) {
510 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
513 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
516 if (!bottomspaceED->text().isEmpty())
517 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
518 widgetsToLength(bottomspaceED,
524 switch (interlinespaceCO->currentIndex()) {
526 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
529 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
532 if (!interlinespaceED->text().isEmpty())
533 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
534 widgetsToLength(interlinespaceED,
535 interlinespaceUnitLC));
540 if (borders->getTop() && borders->getBottom() && borders->getLeft()
541 && borders->getRight())
542 setParam(param_str, Tabular::SET_ALL_LINES);
543 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
544 && !borders->getRight())
545 setParam(param_str, Tabular::UNSET_ALL_LINES);
547 setParam(param_str, Tabular::SET_LINE_LEFT,
548 borders->getLeft() ? "true" : "false");
549 setParam(param_str, Tabular::SET_LINE_RIGHT,
550 borders->getRight() ? "true" : "false");
551 setParam(param_str, Tabular::SET_LINE_TOP,
552 borders->getTop() ? "true" : "false");
553 setParam(param_str, Tabular::SET_LINE_BOTTOM,
554 borders->getBottom() ? "true" : "false");
557 // apply the special alignment
558 string special = fromqstr(specialAlignmentED->text());
561 if (multicolumnCB->isChecked())
562 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
564 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
567 if (multicolumnCB->isChecked())
568 setParam(param_str, Tabular::SET_MULTICOLUMN);
570 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
572 // apply the multirow offset
573 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
574 if (mroffset.empty())
576 if (multirowCB->isChecked())
577 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
579 if (multirowCB->isChecked())
580 setParam(param_str, Tabular::SET_MULTIROW);
582 setParam(param_str, Tabular::UNSET_MULTIROW);
583 // store the table rotation angle
584 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
585 if (rotateTabularCB->isChecked())
586 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
588 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
589 // store the cell rotation angle
590 string const cell_angle = convert<string>(rotateCellAngleSB->value());
591 if (rotateCellCB->isChecked())
592 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
594 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
596 if (longTabularCB->isChecked())
597 setParam(param_str, Tabular::SET_LONGTABULAR);
599 setParam(param_str, Tabular::UNSET_LONGTABULAR);
601 if (newpageCB->isChecked())
602 setParam(param_str, Tabular::SET_LTNEWPAGE);
604 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
606 if (captionStatusCB->isChecked())
607 setParam(param_str, Tabular::SET_LTCAPTION);
609 setParam(param_str, Tabular::UNSET_LTCAPTION);
611 if (headerStatusCB->isChecked())
612 setParam(param_str, Tabular::SET_LTHEAD, "none");
614 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
616 if (headerBorderAboveCB->isChecked())
617 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
619 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
621 if (headerBorderBelowCB->isChecked())
622 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
624 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
625 if (firstheaderBorderAboveCB->isChecked())
626 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
628 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
629 if (firstheaderBorderBelowCB->isChecked())
630 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
632 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
633 if (firstheaderStatusCB->isChecked())
634 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
636 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
637 if (firstheaderNoContentsCB->isChecked())
638 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
640 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
641 if (footerStatusCB->isChecked())
642 setParam(param_str, Tabular::SET_LTFOOT, "none");
644 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
645 if (footerBorderAboveCB->isChecked())
646 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
648 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
649 if (footerBorderBelowCB->isChecked())
650 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
652 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
653 if (lastfooterStatusCB->isChecked())
654 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
656 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
657 if (lastfooterBorderAboveCB->isChecked())
658 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
660 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
661 if (lastfooterBorderBelowCB->isChecked())
662 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
664 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
665 if (lastfooterNoContentsCB->isChecked())
666 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
668 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
670 if (leftRB->isChecked())
671 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
672 else if (centerRB->isChecked())
673 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
674 else if (rightRB->isChecked())
675 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
677 return from_utf8(param_str);
681 static Length getColumnPWidth(Tabular const & t, size_t cell)
683 return t.column_info[t.cellColumn(cell)].p_width;
687 static Length getMColumnPWidth(Tabular const & t, size_t cell)
689 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
690 return t.cellInfo(cell).p_width;
695 static Length getMROffset(Tabular const & t, size_t cell)
697 if (t.isMultiRow(cell))
698 return t.cellInfo(cell).mroffset;
703 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
705 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
706 return t.cellInfo(cell).align_special;
707 return t.column_info[t.cellColumn(cell)].align_special;
711 void GuiTabular::paramsToDialog(Inset const * inset)
713 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
714 // Copy Tabular of current inset.
715 Tabular const & tabular = itab->tabular;
717 BufferView const * bv = guiApp->currentView()->currentBufferView();
718 size_t const cell = bv->cursor().idx();
720 Tabular::row_type const row = tabular.cellRow(cell);
721 Tabular::col_type const col = tabular.cellColumn(cell);
723 tabularRowED->setText(QString::number(row + 1));
724 tabularColumnED->setText(QString::number(col + 1));
726 bool const multicol = tabular.isMultiColumn(cell);
727 multicolumnCB->setChecked(multicol);
729 bool const multirow = tabular.isMultiRow(cell);
730 multirowCB->setChecked(multirow);
732 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
733 if (rotateCellCB->isChecked()) {
734 if (tabular.getRotateCell(cell) != 0)
735 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
737 rotateCellAngleSB->setValue(90);
740 rotateTabularCB->setChecked(tabular.rotate != 0);
741 if (rotateTabularCB->isChecked())
742 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
744 longTabularCB->setChecked(tabular.is_long_tabular);
746 borders->setTop(tabular.topLine(cell));
747 borders->setBottom(tabular.bottomLine(cell));
748 borders->setLeft(tabular.leftLine(cell));
749 borders->setRight(tabular.rightLine(cell));
750 // repaint the setborder widget
753 Length::UNIT const default_unit = Length::defaultUnit();
755 ///////////////////////////////////
756 // Set width and alignment
758 Length const tabwidth = tabular.tabularWidth();
760 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
761 tabularWidthED->clear();
763 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
764 tabwidth.asString(), default_unit);
769 special = getAlignSpecial(tabular, cell,
770 Tabular::SET_SPECIAL_MULTICOLUMN);
771 pwidth = getMColumnPWidth(tabular, cell);
773 special = getAlignSpecial(tabular, cell,
774 Tabular::SET_SPECIAL_COLUMN);
775 pwidth = getColumnPWidth(tabular, cell);
779 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0"))
780 columnWidthED->clear();
782 colwidth = pwidth.asString();
783 lengthToWidgets(columnWidthED, columnWidthUnitLC,
784 colwidth, default_unit);
788 mroffset = getMROffset(tabular, cell);
791 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
792 multirowOffsetED->clear();
794 offset = mroffset.asString();
795 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
796 offset, default_unit);
798 specialAlignmentED->setText(toqstr(special));
799 ///////////////////////////////////
802 borderDefaultRB->setChecked(!tabular.use_booktabs);
803 booktabsRB->setChecked(tabular.use_booktabs);
805 if (tabular.row_info[row].top_space.empty()
806 && !tabular.row_info[row].top_space_default) {
807 topspaceCO->setCurrentIndex(0);
808 } else if (tabular.row_info[row].top_space_default) {
809 topspaceCO->setCurrentIndex(1);
811 topspaceCO->setCurrentIndex(2);
812 lengthToWidgets(topspaceED,
814 tabular.row_info[row].top_space.asString(),
818 if (tabular.row_info[row].bottom_space.empty()
819 && !tabular.row_info[row].bottom_space_default) {
820 bottomspaceCO->setCurrentIndex(0);
821 } else if (tabular.row_info[row].bottom_space_default) {
822 bottomspaceCO->setCurrentIndex(1);
824 bottomspaceCO->setCurrentIndex(2);
825 lengthToWidgets(bottomspaceED,
827 tabular.row_info[row].bottom_space.asString(),
831 if (tabular.row_info[row].interline_space.empty()
832 && !tabular.row_info[row].interline_space_default) {
833 interlinespaceCO->setCurrentIndex(0);
834 } else if (tabular.row_info[row].interline_space_default) {
835 interlinespaceCO->setCurrentIndex(1);
837 interlinespaceCO->setCurrentIndex(2);
838 lengthToWidgets(interlinespaceED,
839 interlinespaceUnitLC,
840 tabular.row_info[row].interline_space.asString(),
845 hAlignCO->addItem(qt_("Left"), toqstr("left"));
846 hAlignCO->addItem(qt_("Center"), toqstr("center"));
847 hAlignCO->addItem(qt_("Right"), toqstr("right"));
848 if (!multicol && !pwidth.zero())
849 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
850 if (!multicol && !multirow)
851 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
854 switch (tabular.getAlignment(cell)) {
858 case LYX_ALIGN_CENTER:
861 case LYX_ALIGN_RIGHT:
864 case LYX_ALIGN_BLOCK:
866 if (!multicol && !pwidth.zero())
870 case LYX_ALIGN_DECIMAL:
872 if (!multicol && !multirow)
877 // we should never end up here
880 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
883 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
884 if (decimal_point.isEmpty())
885 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
886 decimalPointED->setText(decimal_point);
889 switch (tabular.getVAlignment(cell)) {
890 case Tabular::LYX_VALIGN_TOP:
893 case Tabular::LYX_VALIGN_MIDDLE:
896 case Tabular::LYX_VALIGN_BOTTOM:
905 vAlignCO->setCurrentIndex(valign);
908 switch (tabular.tabular_valignment) {
909 case Tabular::LYX_VALIGN_TOP:
912 case Tabular::LYX_VALIGN_MIDDLE:
915 case Tabular::LYX_VALIGN_BOTTOM:
922 TableAlignCO->setCurrentIndex(tableValign);
924 if (!tabular.is_long_tabular) {
925 headerStatusCB->setChecked(false);
926 headerBorderAboveCB->setChecked(false);
927 headerBorderBelowCB->setChecked(false);
928 firstheaderStatusCB->setChecked(false);
929 firstheaderBorderAboveCB->setChecked(false);
930 firstheaderBorderBelowCB->setChecked(false);
931 firstheaderNoContentsCB->setChecked(false);
932 footerStatusCB->setChecked(false);
933 footerBorderAboveCB->setChecked(false);
934 footerBorderBelowCB->setChecked(false);
935 lastfooterStatusCB->setChecked(false);
936 lastfooterBorderAboveCB->setChecked(false);
937 lastfooterBorderBelowCB->setChecked(false);
938 lastfooterNoContentsCB->setChecked(false);
939 newpageCB->setChecked(false);
940 captionStatusCB->blockSignals(true);
941 captionStatusCB->setChecked(false);
942 captionStatusCB->blockSignals(false);
946 // longtables cannot have a vertical alignment
947 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
949 switch (tabular.longtabular_alignment) {
950 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
951 leftRB->setChecked(true);
953 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
954 centerRB->setChecked(true);
956 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
957 rightRB->setChecked(true);
960 centerRB->setChecked(true);
963 captionStatusCB->blockSignals(true);
964 captionStatusCB->setChecked(tabular.ltCaption(row));
965 captionStatusCB->blockSignals(false);
969 bool row_set = tabular.getRowOfLTHead(row, ltt);
970 headerStatusCB->setChecked(row_set);
972 headerBorderAboveCB->setChecked(ltt.topDL);
973 headerBorderBelowCB->setChecked(ltt.bottomDL);
976 headerBorderAboveCB->setChecked(false);
977 headerBorderBelowCB->setChecked(false);
978 firstheaderNoContentsCB->setChecked(false);
982 row_set = tabular.getRowOfLTFirstHead(row, ltt);
983 firstheaderStatusCB->setChecked(row_set);
984 if (ltt.set && (!ltt.empty || !use_empty)) {
985 firstheaderBorderAboveCB->setChecked(ltt.topDL);
986 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
988 firstheaderBorderAboveCB->setChecked(false);
989 firstheaderBorderBelowCB->setChecked(false);
992 row_set = tabular.getRowOfLTFoot(row, ltt);
993 footerStatusCB->setChecked(row_set);
995 footerBorderAboveCB->setChecked(ltt.topDL);
996 footerBorderBelowCB->setChecked(ltt.bottomDL);
999 footerBorderAboveCB->setChecked(false);
1000 footerBorderBelowCB->setChecked(false);
1001 lastfooterNoContentsCB->setChecked(false);
1005 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1006 lastfooterStatusCB->setChecked(row_set);
1007 if (ltt.set && (!ltt.empty || !use_empty)) {
1008 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1009 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1011 lastfooterBorderAboveCB->setChecked(false);
1012 lastfooterBorderBelowCB->setChecked(false);
1014 newpageCB->setChecked(tabular.getLTNewPage(row));
1016 // first header can only be suppressed when there is a header
1017 firstheader_suppressable_ = tabular.haveLTHead()
1018 && !tabular.haveLTFirstHead();
1019 // last footer can only be suppressed when there is a footer
1020 lastfooter_suppressable_ = tabular.haveLTFoot()
1021 && !tabular.haveLTLastFoot();
1023 // after setting the features, check if they are enabled
1028 bool GuiTabular::checkWidgets(bool readonly) const
1030 tabularRowED->setReadOnly(readonly);
1031 tabularColumnED->setReadOnly(readonly);
1032 tabularWidthED->setReadOnly(readonly);
1033 specialAlignmentED->setReadOnly(readonly);
1034 columnWidthED->setReadOnly(readonly);
1035 multirowOffsetED->setReadOnly(readonly);
1036 decimalPointED->setReadOnly(readonly);
1039 multicolumnCB->setEnabled(false);
1040 multirowCB->setEnabled(false);
1041 rotateCellCB->setEnabled(false);
1042 rotateCellAngleSB->setEnabled(false);
1043 rotateTabularCB->setEnabled(false);
1044 rotateTabularAngleSB->setEnabled(false);
1045 longTabularCB->setEnabled(false);
1046 borders->setEnabled(false);
1047 tabularWidthUnitLC->setEnabled(false);
1048 columnWidthUnitLC->setEnabled(false);
1049 multirowOffsetUnitLC->setEnabled(false);
1050 setBordersGB->setEnabled(false);
1051 allBordersGB->setEnabled(false);
1052 borderStyleGB->setEnabled(false);
1053 booktabsRB->setEnabled(false);
1054 topspaceCO->setEnabled(false);
1055 topspaceUnitLC->setEnabled(false);
1056 bottomspaceCO->setEnabled(false);
1057 bottomspaceUnitLC->setEnabled(false);
1058 interlinespaceCO->setEnabled(false);
1059 interlinespaceUnitLC->setEnabled(false);
1060 hAlignCO->setEnabled(false);
1061 vAlignCO->setEnabled(false);
1062 TableAlignCO->setEnabled(false);
1063 longtableGB->setEnabled(false);
1064 alignmentGB->setEnabled(false);
1068 return InsetParamsWidget::checkWidgets();
1072 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1074 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1075 return getStatus(r).enabled();
1079 } // namespace frontend
1082 #include "moc_GuiTabular.cpp"