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)
52 tabularWidthED->setValidator(unsignedLengthValidator(tabularWidthED));
53 columnWidthED->setValidator(unsignedLengthValidator(columnWidthED));
54 multirowOffsetED->setValidator(new LengthValidator(multirowOffsetED));
55 topspaceED->setValidator(new LengthValidator(topspaceED));
56 bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
57 interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
59 tabularWidthUnitLC->setCurrentItem(Length::defaultUnit());
60 columnWidthUnitLC->setCurrentItem(Length::defaultUnit());
61 multirowOffsetUnitLC->setCurrentItem(Length::defaultUnit());
62 topspaceUnitLC->setCurrentItem(Length::defaultUnit());
63 bottomspaceUnitLC->setCurrentItem(Length::defaultUnit());
64 interlinespaceUnitLC->setCurrentItem(Length::defaultUnit());
66 connect(topspaceED, SIGNAL(textEdited(const QString &)),
67 this, SLOT(checkEnabled()));
68 connect(topspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
69 this, SLOT(checkEnabled()));
70 connect(bottomspaceED, SIGNAL(textEdited(const QString &)),
71 this, SLOT(checkEnabled()));
72 connect(bottomspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
73 this, SLOT(checkEnabled()));
74 connect(interlinespaceED, SIGNAL(textEdited(const QString &)),
75 this, SLOT(checkEnabled()));
76 connect(interlinespaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
77 this, SLOT(checkEnabled()));
78 connect(booktabsRB, SIGNAL(clicked(bool)),
79 this, SLOT(checkEnabled()));
80 connect(borderDefaultRB, SIGNAL(clicked(bool)),
81 this, SLOT(checkEnabled()));
82 connect(borderSetPB, SIGNAL(clicked()),
83 this, SLOT(borderSet_clicked()));
84 connect(borderUnsetPB, SIGNAL(clicked()),
85 this, SLOT(borderUnset_clicked()));
86 connect(hAlignCO, SIGNAL(activated(int)),
87 this, SLOT(checkEnabled()));
88 connect(vAlignCO, SIGNAL(activated(int)),
89 this, SLOT(checkEnabled()));
90 connect(multicolumnCB, SIGNAL(clicked()),
91 this, SLOT(checkEnabled()));
92 connect(multirowCB, SIGNAL(clicked()),
93 this, SLOT(checkEnabled()));
94 connect(multirowOffsetED, SIGNAL(textEdited(const QString &)),
95 this, SLOT(checkEnabled()));
96 connect(multirowOffsetUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
97 this, SLOT(checkEnabled()));
98 connect(newpageCB, SIGNAL(clicked()),
99 this, SLOT(checkEnabled()));
100 connect(headerStatusCB, SIGNAL(clicked()),
101 this, SLOT(checkEnabled()));
102 connect(headerBorderAboveCB, SIGNAL(clicked()),
103 this, SLOT(checkEnabled()));
104 connect(headerBorderBelowCB, SIGNAL(clicked()),
105 this, SLOT(checkEnabled()));
106 connect(firstheaderStatusCB, SIGNAL(clicked()),
107 this, SLOT(checkEnabled()));
108 connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
109 this, SLOT(checkEnabled()));
110 connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
111 this, SLOT(checkEnabled()));
112 connect(firstheaderNoContentsCB, SIGNAL(clicked()),
113 this, SLOT(checkEnabled()));
114 connect(footerStatusCB, SIGNAL(clicked()),
115 this, SLOT(checkEnabled()));
116 connect(footerBorderAboveCB, SIGNAL(clicked()),
117 this, SLOT(checkEnabled()));
118 connect(footerBorderBelowCB, SIGNAL(clicked()),
119 this, SLOT(checkEnabled()));
120 connect(lastfooterStatusCB, SIGNAL(clicked()),
121 this, SLOT(checkEnabled()));
122 connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
123 this, SLOT(checkEnabled()));
124 connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
125 this, SLOT(checkEnabled()));
126 connect(lastfooterNoContentsCB, SIGNAL(clicked()),
127 this, SLOT(checkEnabled()));
128 connect(captionStatusCB, SIGNAL(clicked()),
129 this, SLOT(checkEnabled()));
130 connect(specialAlignmentED, SIGNAL(editingFinished()),
131 this, SLOT(checkEnabled()));
132 connect(columnWidthED, SIGNAL(textEdited(const QString &)),
133 this, SLOT(checkEnabled()));
134 connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
135 this, SLOT(checkEnabled()));
136 connect(borders, SIGNAL(topSet(bool)),
137 this, SLOT(checkEnabled()));
138 connect(borders, SIGNAL(bottomSet(bool)),
139 this, SLOT(checkEnabled()));
140 connect(borders, SIGNAL(rightSet(bool)),
141 this, SLOT(checkEnabled()));
142 connect(borders, SIGNAL(leftSet(bool)),
143 this, SLOT(checkEnabled()));
144 connect(rotateTabularCB, SIGNAL(clicked()),
145 this, SLOT(checkEnabled()));
146 connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
147 this, SLOT(checkEnabled()));
148 connect(rotateCellCB, SIGNAL(clicked()),
149 this, SLOT(checkEnabled()));
150 connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
151 this, SLOT(checkEnabled()));
152 connect(TableAlignCO, SIGNAL(activated(int)),
153 this, SLOT(checkEnabled()));
154 connect(longTabularCB, SIGNAL(clicked()),
155 this, SLOT(checkEnabled()));
156 connect(leftRB, SIGNAL(clicked()),
157 this, SLOT(checkEnabled()));
158 connect(centerRB, SIGNAL(clicked()),
159 this, SLOT(checkEnabled()));
160 connect(rightRB, SIGNAL(clicked()),
161 this, SLOT(checkEnabled()));
162 connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
163 this, SLOT(checkEnabled()));
165 decimalPointED->setInputMask("X; ");
166 decimalPointED->setMaxLength(1);
168 // initialize the length validator
169 addCheckedWidget(columnWidthED, columnWidthLA);
170 addCheckedWidget(multirowOffsetED, multirowOffsetLA);
171 addCheckedWidget(topspaceED, topspaceLA);
172 addCheckedWidget(bottomspaceED, bottomspaceLA);
173 addCheckedWidget(interlinespaceED, interlinespaceLA);
174 addCheckedWidget(tabularWidthED, tabularWidthLA);
178 void GuiTabular::on_topspaceCO_activated(int index)
180 bool const enable = (index == 2);
181 topspaceED->setEnabled(enable);
182 topspaceUnitLC->setEnabled(enable);
186 void GuiTabular::on_bottomspaceCO_activated(int index)
188 bool const enable = (index == 2);
189 bottomspaceED->setEnabled(enable);
190 bottomspaceUnitLC->setEnabled(enable);
194 void GuiTabular::on_interlinespaceCO_activated(int index)
196 bool const enable = (index == 2);
197 interlinespaceED->setEnabled(enable);
198 interlinespaceUnitLC->setEnabled(enable);
202 void GuiTabular::checkEnabled()
204 // if there is a LaTeX argument, the width and alignment will be overwritten
205 // therefore disable them in this case
206 columnWidthED->setEnabled(specialAlignmentED->text().isEmpty());
207 // if the column has a width, multirows are always left-aligned
208 // therefore disable hAlignCB in this case
209 hAlignCO->setEnabled(!(multirowCB->isChecked()
210 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
211 && specialAlignmentED->text().isEmpty());
213 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
214 decimalPointED->setEnabled(dalign);
215 decimalLA->setEnabled(dalign);
217 bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
218 && !longTabularCB->isChecked();
219 tabularWidthLA->setEnabled(setwidth);
220 tabularWidthED->setEnabled(setwidth);
221 tabularWidthUnitLC->setEnabled(setwidth);
223 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked());
224 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
226 bool const enable_valign =
227 !multirowCB->isChecked()
228 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
229 && specialAlignmentED->text().isEmpty();
230 vAlignCO->setEnabled(enable_valign);
231 vAlignLA->setEnabled(enable_valign);
233 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
234 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
235 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
236 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
237 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
238 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
239 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
241 // setting as longtable is not allowed when table is inside a float
242 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
243 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
244 bool const longtabular = longTabularCB->isChecked();
245 longtableGB->setEnabled(true);
246 newpageCB->setEnabled(longtabular);
247 alignmentGB->setEnabled(longtabular);
248 // longtables and tabular* cannot have a vertical alignment
249 TableAlignLA->setDisabled(is_tabular_star || longtabular);
250 TableAlignCO->setDisabled(is_tabular_star || longtabular);
252 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
253 // depending on the cursor position is very very unintuitive...
254 // We need some edit boxes to show which rows are header/footer/etc
255 // without having to move the cursor first.
256 headerStatusCB->setEnabled(longtabular
257 && (headerStatusCB->isChecked() ?
258 funcEnabled(Tabular::UNSET_LTHEAD) :
259 funcEnabled(Tabular::SET_LTHEAD)));
260 headerBorderAboveCB->setEnabled(longtabular
261 && headerStatusCB->isChecked());
262 headerBorderBelowCB->setEnabled(longtabular
263 && headerStatusCB->isChecked());
265 // first header can only be suppressed when there is a header
266 // firstheader_suppressable_ is set in paramsToDialog
267 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
268 // check if setting a first header is allowed
269 // additionally check firstheaderNoContentsCB because when this is
270 // the case a first header makes no sense
271 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
272 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
273 funcEnabled(Tabular::SET_LTFIRSTHEAD))
274 && longtabular && !firstheaderNoContentsCB->isChecked());
275 firstheaderBorderAboveCB->setEnabled(longtabular
276 && firstheaderStatusCB->isChecked());
277 firstheaderBorderBelowCB->setEnabled(longtabular
278 && firstheaderStatusCB->isChecked());
280 footerStatusCB->setEnabled(longtabular
281 && (footerStatusCB->isChecked() ?
282 funcEnabled(Tabular::UNSET_LTFOOT) :
283 funcEnabled(Tabular::SET_LTFOOT)));
284 footerBorderAboveCB->setEnabled(longtabular
285 && footerBorderAboveCB->isChecked());
286 footerBorderBelowCB->setEnabled(longtabular
287 && footerBorderAboveCB->isChecked());
289 // last footer can only be suppressed when there is a footer
290 // lastfooter_suppressable_ is set in paramsToDialog
291 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
292 // check if setting a last footer is allowed
293 // additionally check lastfooterNoContentsCB because when this is
294 // the case a last footer makes no sense
295 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
296 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
297 funcEnabled(Tabular::SET_LTLASTFOOT))
298 && longtabular && !lastfooterNoContentsCB->isChecked());
299 lastfooterBorderAboveCB->setEnabled(longtabular
300 && lastfooterBorderAboveCB->isChecked());
301 lastfooterBorderBelowCB->setEnabled(longtabular
302 && lastfooterBorderAboveCB->isChecked());
304 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
307 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN));
308 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW));
309 bool const enable_mr = multirowCB->isChecked();
310 multirowOffsetLA->setEnabled(enable_mr);
311 multirowOffsetED->setEnabled(enable_mr);
312 multirowOffsetUnitLC->setEnabled(enable_mr);
318 void GuiTabular::borderSet_clicked()
320 borders->setTop(true);
321 borders->setBottom(true);
322 borders->setLeft(true);
323 borders->setRight(true);
324 // repaint the setborder widget
330 void GuiTabular::borderUnset_clicked()
332 borders->setTop(false);
333 borders->setBottom(false);
334 borders->setLeft(false);
335 borders->setRight(false);
336 // repaint the setborder widget
342 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
345 param_str += featureAsString(f) + ' ' + arg;
349 void GuiTabular::setHAlign(string & param_str) const
351 Tabular::Feature num = Tabular::ALIGN_LEFT;
352 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
354 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
355 if (align == "left") {
356 num = Tabular::ALIGN_LEFT;
357 multi_num = Tabular::M_ALIGN_LEFT;
358 } else if (align == "center") {
359 num = Tabular::ALIGN_CENTER;
360 multi_num = Tabular::M_ALIGN_CENTER;
361 } else if (align == "right") {
362 num = Tabular::ALIGN_RIGHT;
363 multi_num = Tabular::M_ALIGN_RIGHT;
364 } else if (align == "justified") {
365 num = Tabular::ALIGN_BLOCK;
366 //multi_num: no equivalent
367 } else if (align == "decimal") {
368 num = Tabular::ALIGN_DECIMAL;
369 //multi_num: no equivalent
372 if (multicolumnCB->isChecked())
373 setParam(param_str, multi_num);
375 setParam(param_str, num);
379 void GuiTabular::setVAlign(string & param_str) const
381 int const align = vAlignCO->currentIndex();
382 enum VALIGN { TOP, MIDDLE, BOTTOM };
386 case 0: v = TOP; break;
387 case 1: v = MIDDLE; break;
388 case 2: v = BOTTOM; break;
391 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
392 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
396 num = Tabular::VALIGN_TOP;
397 multi_num = Tabular::M_VALIGN_TOP;
400 num = Tabular::VALIGN_MIDDLE;
401 multi_num = Tabular::M_VALIGN_MIDDLE;
404 num = Tabular::VALIGN_BOTTOM;
405 multi_num = Tabular::M_VALIGN_BOTTOM;
408 if (multicolumnCB->isChecked() || multirowCB->isChecked())
409 setParam(param_str, multi_num);
411 setParam(param_str, num);
415 void GuiTabular::setTableAlignment(string & param_str) const
417 int const align = TableAlignCO->currentIndex();
419 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
421 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
423 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
429 docstring GuiTabular::dialogToParams() const
431 // FIXME: We should use Tabular directly.
432 string param_str = "tabular from-dialog";
435 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
436 if (tabwidth.empty())
438 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
440 // apply the fixed width values
441 // this must be done before applying the column alignment
442 // because its value influences the alignment of multirow cells
443 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
446 if (multicolumnCB->isChecked())
447 setParam(param_str, Tabular::SET_MPWIDTH, width);
449 setParam(param_str, Tabular::SET_PWIDTH, width);
451 // apply the column alignment
452 // multirows inherit the alignment from the column; if a column width
453 // is set, multirows are always left-aligned so that in this case
454 // its alignment must not be applied (see bug #8084)
455 if (!(multirowCB->isChecked() && width != "0pt"))
456 setHAlign(param_str);
458 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
459 string decimal_point = fromqstr(decimalPointED->text());
460 if (decimal_point.empty())
461 decimal_point = lyxrc.default_decimal_point;
462 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
464 setVAlign(param_str);
465 setTableAlignment(param_str);
467 if (booktabsRB->isChecked())
468 setParam(param_str, Tabular::SET_BOOKTABS);
470 setParam(param_str, Tabular::UNSET_BOOKTABS);
473 switch (topspaceCO->currentIndex()) {
475 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
478 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
481 if (!topspaceED->text().isEmpty())
482 setParam(param_str, Tabular::SET_TOP_SPACE,
483 widgetsToLength(topspaceED, topspaceUnitLC));
488 switch (bottomspaceCO->currentIndex()) {
490 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
493 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
496 if (!bottomspaceED->text().isEmpty())
497 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
498 widgetsToLength(bottomspaceED,
504 switch (interlinespaceCO->currentIndex()) {
506 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
509 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
512 if (!interlinespaceED->text().isEmpty())
513 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
514 widgetsToLength(interlinespaceED,
515 interlinespaceUnitLC));
520 if (borders->getTop() && borders->getBottom() && borders->getLeft()
521 && borders->getRight())
522 setParam(param_str, Tabular::SET_ALL_LINES);
523 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
524 && !borders->getRight())
525 setParam(param_str, Tabular::UNSET_ALL_LINES);
527 setParam(param_str, Tabular::SET_LINE_LEFT,
528 borders->getLeft() ? "true" : "false");
529 setParam(param_str, Tabular::SET_LINE_RIGHT,
530 borders->getRight() ? "true" : "false");
531 setParam(param_str, Tabular::SET_LINE_TOP,
532 borders->getTop() ? "true" : "false");
533 setParam(param_str, Tabular::SET_LINE_BOTTOM,
534 borders->getBottom() ? "true" : "false");
537 // apply the special alignment
538 string special = fromqstr(specialAlignmentED->text());
541 if (multicolumnCB->isChecked())
542 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
544 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
547 if (multicolumnCB->isChecked())
548 setParam(param_str, Tabular::SET_MULTICOLUMN);
550 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
552 // apply the multirow offset
553 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
554 if (mroffset.empty())
556 if (multirowCB->isChecked())
557 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
559 if (multirowCB->isChecked())
560 setParam(param_str, Tabular::SET_MULTIROW);
562 setParam(param_str, Tabular::UNSET_MULTIROW);
563 // store the table rotation angle
564 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
565 if (rotateTabularCB->isChecked())
566 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
568 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
569 // store the cell rotation angle
570 string const cell_angle = convert<string>(rotateCellAngleSB->value());
571 if (rotateCellCB->isChecked())
572 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
574 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
576 if (longTabularCB->isChecked())
577 setParam(param_str, Tabular::SET_LONGTABULAR);
579 setParam(param_str, Tabular::UNSET_LONGTABULAR);
581 if (newpageCB->isChecked())
582 setParam(param_str, Tabular::SET_LTNEWPAGE);
584 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
586 if (captionStatusCB->isChecked())
587 setParam(param_str, Tabular::SET_LTCAPTION);
589 setParam(param_str, Tabular::UNSET_LTCAPTION);
591 if (headerStatusCB->isChecked())
592 setParam(param_str, Tabular::SET_LTHEAD, "none");
594 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
596 if (headerBorderAboveCB->isChecked())
597 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
599 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
601 if (headerBorderBelowCB->isChecked())
602 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
604 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
605 if (firstheaderBorderAboveCB->isChecked())
606 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
608 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
609 if (firstheaderBorderBelowCB->isChecked())
610 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
612 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
613 if (firstheaderStatusCB->isChecked())
614 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
616 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
617 if (firstheaderNoContentsCB->isChecked())
618 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
620 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
621 if (footerStatusCB->isChecked())
622 setParam(param_str, Tabular::SET_LTFOOT, "none");
624 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
625 if (footerBorderAboveCB->isChecked())
626 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
628 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
629 if (footerBorderBelowCB->isChecked())
630 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
632 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
633 if (lastfooterStatusCB->isChecked())
634 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
636 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
637 if (lastfooterBorderAboveCB->isChecked())
638 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
640 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
641 if (lastfooterBorderBelowCB->isChecked())
642 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
644 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
645 if (lastfooterNoContentsCB->isChecked())
646 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
648 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
650 if (leftRB->isChecked())
651 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
652 else if (centerRB->isChecked())
653 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
654 else if (rightRB->isChecked())
655 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
657 return from_utf8(param_str);
661 static Length getColumnPWidth(Tabular const & t, size_t cell)
663 return t.column_info[t.cellColumn(cell)].p_width;
667 static Length getMColumnPWidth(Tabular const & t, size_t cell)
669 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
670 return t.cellInfo(cell).p_width;
675 static Length getMROffset(Tabular const & t, size_t cell)
677 if (t.isMultiRow(cell))
678 return t.cellInfo(cell).mroffset;
683 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
685 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
686 return t.cellInfo(cell).align_special;
687 return t.column_info[t.cellColumn(cell)].align_special;
691 void GuiTabular::paramsToDialog(Inset const * inset)
693 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
694 // Copy Tabular of current inset.
695 Tabular const & tabular = itab->tabular;
697 BufferView const * bv = guiApp->currentView()->currentBufferView();
698 size_t const cell = bv->cursor().idx();
700 Tabular::row_type const row = tabular.cellRow(cell);
701 Tabular::col_type const col = tabular.cellColumn(cell);
703 tabularRowED->setText(QString::number(row + 1));
704 tabularColumnED->setText(QString::number(col + 1));
706 bool const multicol = tabular.isMultiColumn(cell);
707 multicolumnCB->setChecked(multicol);
709 bool const multirow = tabular.isMultiRow(cell);
710 multirowCB->setChecked(multirow);
712 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
713 if (rotateCellCB->isChecked()) {
714 if (tabular.getRotateCell(cell) != 0)
715 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
717 rotateCellAngleSB->setValue(90);
720 rotateTabularCB->setChecked(tabular.rotate != 0);
721 if (rotateTabularCB->isChecked())
722 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
724 longTabularCB->setChecked(tabular.is_long_tabular);
726 borders->setTop(tabular.topLine(cell));
727 borders->setBottom(tabular.bottomLine(cell));
728 borders->setLeft(tabular.leftLine(cell));
729 borders->setRight(tabular.rightLine(cell));
730 // repaint the setborder widget
733 Length::UNIT const default_unit = Length::defaultUnit();
735 ///////////////////////////////////
736 // Set width and alignment
738 Length const tabwidth = tabular.tabularWidth();
740 tabularWidthED->clear();
742 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
743 tabwidth.asString(), default_unit);
748 special = getAlignSpecial(tabular, cell,
749 Tabular::SET_SPECIAL_MULTICOLUMN);
750 pwidth = getMColumnPWidth(tabular, cell);
752 special = getAlignSpecial(tabular, cell,
753 Tabular::SET_SPECIAL_COLUMN);
754 pwidth = getColumnPWidth(tabular, cell);
758 columnWidthED->clear();
760 colwidth = pwidth.asString();
761 lengthToWidgets(columnWidthED, columnWidthUnitLC,
762 colwidth, default_unit);
766 mroffset = getMROffset(tabular, cell);
769 multirowOffsetED->clear();
771 offset = mroffset.asString();
772 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
773 offset, default_unit);
775 specialAlignmentED->setText(toqstr(special));
776 ///////////////////////////////////
779 borderDefaultRB->setChecked(!tabular.use_booktabs);
780 booktabsRB->setChecked(tabular.use_booktabs);
782 if (tabular.row_info[row].top_space.empty()
783 && !tabular.row_info[row].top_space_default) {
784 topspaceCO->setCurrentIndex(0);
785 } else if (tabular.row_info[row].top_space_default) {
786 topspaceCO->setCurrentIndex(1);
788 topspaceCO->setCurrentIndex(2);
789 lengthToWidgets(topspaceED,
791 tabular.row_info[row].top_space.asString(),
795 if (tabular.row_info[row].bottom_space.empty()
796 && !tabular.row_info[row].bottom_space_default) {
797 bottomspaceCO->setCurrentIndex(0);
798 } else if (tabular.row_info[row].bottom_space_default) {
799 bottomspaceCO->setCurrentIndex(1);
801 bottomspaceCO->setCurrentIndex(2);
802 lengthToWidgets(bottomspaceED,
804 tabular.row_info[row].bottom_space.asString(),
808 if (tabular.row_info[row].interline_space.empty()
809 && !tabular.row_info[row].interline_space_default) {
810 interlinespaceCO->setCurrentIndex(0);
811 } else if (tabular.row_info[row].interline_space_default) {
812 interlinespaceCO->setCurrentIndex(1);
814 interlinespaceCO->setCurrentIndex(2);
815 lengthToWidgets(interlinespaceED,
816 interlinespaceUnitLC,
817 tabular.row_info[row].interline_space.asString(),
822 hAlignCO->addItem(qt_("Left"), toqstr("left"));
823 hAlignCO->addItem(qt_("Center"), toqstr("center"));
824 hAlignCO->addItem(qt_("Right"), toqstr("right"));
825 if (!multicol && !pwidth.zero())
826 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
828 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
831 switch (tabular.getAlignment(cell)) {
835 case LYX_ALIGN_CENTER:
838 case LYX_ALIGN_RIGHT:
841 case LYX_ALIGN_BLOCK:
843 if (!multicol && !pwidth.zero())
847 case LYX_ALIGN_DECIMAL:
854 // we should never end up here
857 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
860 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
861 if (decimal_point.isEmpty())
862 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
863 decimalPointED->setText(decimal_point);
866 switch (tabular.getVAlignment(cell)) {
867 case Tabular::LYX_VALIGN_TOP:
870 case Tabular::LYX_VALIGN_MIDDLE:
873 case Tabular::LYX_VALIGN_BOTTOM:
882 vAlignCO->setCurrentIndex(valign);
885 switch (tabular.tabular_valignment) {
886 case Tabular::LYX_VALIGN_TOP:
889 case Tabular::LYX_VALIGN_MIDDLE:
892 case Tabular::LYX_VALIGN_BOTTOM:
899 TableAlignCO->setCurrentIndex(tableValign);
901 if (!tabular.is_long_tabular) {
902 headerStatusCB->setChecked(false);
903 headerBorderAboveCB->setChecked(false);
904 headerBorderBelowCB->setChecked(false);
905 firstheaderStatusCB->setChecked(false);
906 firstheaderBorderAboveCB->setChecked(false);
907 firstheaderBorderBelowCB->setChecked(false);
908 firstheaderNoContentsCB->setChecked(false);
909 footerStatusCB->setChecked(false);
910 footerBorderAboveCB->setChecked(false);
911 footerBorderBelowCB->setChecked(false);
912 lastfooterStatusCB->setChecked(false);
913 lastfooterBorderAboveCB->setChecked(false);
914 lastfooterBorderBelowCB->setChecked(false);
915 lastfooterNoContentsCB->setChecked(false);
916 newpageCB->setChecked(false);
917 captionStatusCB->blockSignals(true);
918 captionStatusCB->setChecked(false);
919 captionStatusCB->blockSignals(false);
923 // longtables cannot have a vertical alignment
924 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
926 switch (tabular.longtabular_alignment) {
927 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
928 leftRB->setChecked(true);
930 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
931 centerRB->setChecked(true);
933 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
934 rightRB->setChecked(true);
937 centerRB->setChecked(true);
940 captionStatusCB->blockSignals(true);
941 captionStatusCB->setChecked(tabular.ltCaption(row));
942 captionStatusCB->blockSignals(false);
946 bool row_set = tabular.getRowOfLTHead(row, ltt);
947 headerStatusCB->setChecked(row_set);
949 headerBorderAboveCB->setChecked(ltt.topDL);
950 headerBorderBelowCB->setChecked(ltt.bottomDL);
953 headerBorderAboveCB->setChecked(false);
954 headerBorderBelowCB->setChecked(false);
955 firstheaderNoContentsCB->setChecked(false);
959 row_set = tabular.getRowOfLTFirstHead(row, ltt);
960 firstheaderStatusCB->setChecked(row_set);
961 if (ltt.set && (!ltt.empty || !use_empty)) {
962 firstheaderBorderAboveCB->setChecked(ltt.topDL);
963 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
965 firstheaderBorderAboveCB->setChecked(false);
966 firstheaderBorderBelowCB->setChecked(false);
969 row_set = tabular.getRowOfLTFoot(row, ltt);
970 footerStatusCB->setChecked(row_set);
972 footerBorderAboveCB->setChecked(ltt.topDL);
973 footerBorderBelowCB->setChecked(ltt.bottomDL);
976 footerBorderAboveCB->setChecked(false);
977 footerBorderBelowCB->setChecked(false);
978 lastfooterNoContentsCB->setChecked(false);
982 row_set = tabular.getRowOfLTLastFoot(row, ltt);
983 lastfooterStatusCB->setChecked(row_set);
984 if (ltt.set && (!ltt.empty || !use_empty)) {
985 lastfooterBorderAboveCB->setChecked(ltt.topDL);
986 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
988 lastfooterBorderAboveCB->setChecked(false);
989 lastfooterBorderBelowCB->setChecked(false);
991 newpageCB->setChecked(tabular.getLTNewPage(row));
993 // first header can only be suppressed when there is a header
994 firstheader_suppressable_ = tabular.haveLTHead()
995 && !tabular.haveLTFirstHead();
996 // last footer can only be suppressed when there is a footer
997 lastfooter_suppressable_ = tabular.haveLTFoot()
998 && !tabular.haveLTLastFoot();
1000 // after setting the features, check if they are enabled
1005 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1007 string cmd = "tabular " + featureAsString(f);
1008 return getStatus(FuncRequest(LFUN_INSET_MODIFY, cmd)).enabled();
1012 } // namespace frontend
1015 #include "moc_GuiTabular.cpp"