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(rotateCellCB, SIGNAL(clicked()),
147 this, SLOT(checkEnabled()));
148 connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
149 this, SLOT(checkEnabled()));
150 connect(TableAlignCO, SIGNAL(activated(int)),
151 this, SLOT(checkEnabled()));
152 connect(longTabularCB, SIGNAL(clicked()),
153 this, SLOT(checkEnabled()));
154 connect(leftRB, SIGNAL(clicked()),
155 this, SLOT(checkEnabled()));
156 connect(centerRB, SIGNAL(clicked()),
157 this, SLOT(checkEnabled()));
158 connect(rightRB, SIGNAL(clicked()),
159 this, SLOT(checkEnabled()));
160 connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
161 this, SLOT(checkEnabled()));
163 decimalPointED->setInputMask("X; ");
164 decimalPointED->setMaxLength(1);
166 // initialize the length validator
167 addCheckedWidget(columnWidthED, columnWidthLA);
168 addCheckedWidget(multirowOffsetED, multirowOffsetLA);
169 addCheckedWidget(topspaceED, topspaceLA);
170 addCheckedWidget(bottomspaceED, bottomspaceLA);
171 addCheckedWidget(interlinespaceED, interlinespaceLA);
172 addCheckedWidget(tabularWidthED, tabularWidthLA);
176 void GuiTabular::on_topspaceCO_activated(int index)
178 bool const enable = (index == 2);
179 topspaceED->setEnabled(enable);
180 topspaceUnitLC->setEnabled(enable);
184 void GuiTabular::on_bottomspaceCO_activated(int index)
186 bool const enable = (index == 2);
187 bottomspaceED->setEnabled(enable);
188 bottomspaceUnitLC->setEnabled(enable);
192 void GuiTabular::on_interlinespaceCO_activated(int index)
194 bool const enable = (index == 2);
195 interlinespaceED->setEnabled(enable);
196 interlinespaceUnitLC->setEnabled(enable);
200 void GuiTabular::checkEnabled()
202 // if there is a LaTeX argument, the width and alignment will be overwritten
203 // therefore disable them in this case
204 columnWidthED->setEnabled(specialAlignmentED->text().isEmpty());
205 // if the column has a width, multirows are always left-aligned
206 // therefore disable hAlignCB in this case
207 hAlignCO->setEnabled(!(multirowCB->isChecked()
208 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
209 && specialAlignmentED->text().isEmpty());
211 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
212 decimalPointED->setEnabled(dalign);
213 decimalLA->setEnabled(dalign);
215 bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
216 && !longTabularCB->isChecked() && !rotateTabularCB->isChecked();
217 tabularWidthLA->setEnabled(setwidth);
218 tabularWidthED->setEnabled(setwidth);
219 tabularWidthUnitLC->setEnabled(setwidth);
221 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
223 bool const enable_valign =
224 !multirowCB->isChecked()
225 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
226 && specialAlignmentED->text().isEmpty();
227 vAlignCO->setEnabled(enable_valign);
228 vAlignLA->setEnabled(enable_valign);
230 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
231 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
232 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
233 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
234 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
235 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
236 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
238 // setting as longtable is not allowed when table is inside a float
239 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
240 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
241 bool const longtabular = longTabularCB->isChecked();
242 longtableGB->setEnabled(true);
243 newpageCB->setEnabled(longtabular);
244 alignmentGB->setEnabled(longtabular);
245 // longtables and tabular* cannot have a vertical alignment
246 TableAlignLA->setDisabled(is_tabular_star || longtabular);
247 TableAlignCO->setDisabled(is_tabular_star || longtabular);
249 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
250 // depending on the cursor position is very very unintuitive...
251 // We need some edit boxes to show which rows are header/footer/etc
252 // without having to move the cursor first.
253 headerStatusCB->setEnabled(longtabular
254 && (headerStatusCB->isChecked() ?
255 funcEnabled(Tabular::UNSET_LTHEAD) :
256 funcEnabled(Tabular::SET_LTHEAD)));
257 headerBorderAboveCB->setEnabled(longtabular
258 && headerStatusCB->isChecked());
259 headerBorderBelowCB->setEnabled(longtabular
260 && headerStatusCB->isChecked());
262 // first header can only be suppressed when there is a header
263 // firstheader_suppressable_ is set in paramsToDialog
264 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
265 // check if setting a first header is allowed
266 // additionally check firstheaderNoContentsCB because when this is
267 // the case a first header makes no sense
268 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
269 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
270 funcEnabled(Tabular::SET_LTFIRSTHEAD))
271 && longtabular && !firstheaderNoContentsCB->isChecked());
272 firstheaderBorderAboveCB->setEnabled(longtabular
273 && firstheaderStatusCB->isChecked());
274 firstheaderBorderBelowCB->setEnabled(longtabular
275 && firstheaderStatusCB->isChecked());
277 footerStatusCB->setEnabled(longtabular
278 && (footerStatusCB->isChecked() ?
279 funcEnabled(Tabular::UNSET_LTFOOT) :
280 funcEnabled(Tabular::SET_LTFOOT)));
281 footerBorderAboveCB->setEnabled(longtabular
282 && footerBorderAboveCB->isChecked());
283 footerBorderBelowCB->setEnabled(longtabular
284 && footerBorderAboveCB->isChecked());
286 // last footer can only be suppressed when there is a footer
287 // lastfooter_suppressable_ is set in paramsToDialog
288 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
289 // check if setting a last footer is allowed
290 // additionally check lastfooterNoContentsCB because when this is
291 // the case a last footer makes no sense
292 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
293 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
294 funcEnabled(Tabular::SET_LTLASTFOOT))
295 && longtabular && !lastfooterNoContentsCB->isChecked());
296 lastfooterBorderAboveCB->setEnabled(longtabular
297 && lastfooterBorderAboveCB->isChecked());
298 lastfooterBorderBelowCB->setEnabled(longtabular
299 && lastfooterBorderAboveCB->isChecked());
301 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
304 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN));
305 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW));
306 bool const enable_mr = multirowCB->isChecked();
307 multirowOffsetLA->setEnabled(enable_mr);
308 multirowOffsetED->setEnabled(enable_mr);
309 multirowOffsetUnitLC->setEnabled(enable_mr);
315 void GuiTabular::borderSet_clicked()
317 borders->setTop(true);
318 borders->setBottom(true);
319 borders->setLeft(true);
320 borders->setRight(true);
321 // repaint the setborder widget
327 void GuiTabular::borderUnset_clicked()
329 borders->setTop(false);
330 borders->setBottom(false);
331 borders->setLeft(false);
332 borders->setRight(false);
333 // repaint the setborder widget
339 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
342 param_str += featureAsString(f) + ' ' + arg;
346 void GuiTabular::setHAlign(string & param_str) const
348 Tabular::Feature num = Tabular::ALIGN_LEFT;
349 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
351 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
352 if (align == "left") {
353 num = Tabular::ALIGN_LEFT;
354 multi_num = Tabular::M_ALIGN_LEFT;
355 } else if (align == "center") {
356 num = Tabular::ALIGN_CENTER;
357 multi_num = Tabular::M_ALIGN_CENTER;
358 } else if (align == "right") {
359 num = Tabular::ALIGN_RIGHT;
360 multi_num = Tabular::M_ALIGN_RIGHT;
361 } else if (align == "justified") {
362 num = Tabular::ALIGN_BLOCK;
363 //multi_num: no equivalent
364 } else if (align == "decimal") {
365 num = Tabular::ALIGN_DECIMAL;
366 //multi_num: no equivalent
369 if (multicolumnCB->isChecked())
370 setParam(param_str, multi_num);
372 setParam(param_str, num);
376 void GuiTabular::setVAlign(string & param_str) const
378 int const align = vAlignCO->currentIndex();
379 enum VALIGN { TOP, MIDDLE, BOTTOM };
383 case 0: v = TOP; break;
384 case 1: v = MIDDLE; break;
385 case 2: v = BOTTOM; break;
388 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
389 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
393 num = Tabular::VALIGN_TOP;
394 multi_num = Tabular::M_VALIGN_TOP;
397 num = Tabular::VALIGN_MIDDLE;
398 multi_num = Tabular::M_VALIGN_MIDDLE;
401 num = Tabular::VALIGN_BOTTOM;
402 multi_num = Tabular::M_VALIGN_BOTTOM;
405 if (multicolumnCB->isChecked() || multirowCB->isChecked())
406 setParam(param_str, multi_num);
408 setParam(param_str, num);
412 void GuiTabular::setTableAlignment(string & param_str) const
414 int const align = TableAlignCO->currentIndex();
416 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
418 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
420 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
426 docstring GuiTabular::dialogToParams() const
428 // FIXME: We should use Tabular directly.
429 string param_str = "tabular from-dialog";
432 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
433 if (tabwidth.empty())
435 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
437 // apply the fixed width values
438 // this must be done before applying the column alignment
439 // because its value influences the alignment of multirow cells
440 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
443 if (multicolumnCB->isChecked())
444 setParam(param_str, Tabular::SET_MPWIDTH, width);
446 setParam(param_str, Tabular::SET_PWIDTH, width);
448 // apply the column alignment
449 // multirows inherit the alignment from the column; if a column width
450 // is set, multirows are always left-aligned so that in this case
451 // its alignment must not be applied (see bug #8084)
452 if (!(multirowCB->isChecked() && width != "0pt"))
453 setHAlign(param_str);
455 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
456 string decimal_point = fromqstr(decimalPointED->text());
457 if (decimal_point.empty())
458 decimal_point = lyxrc.default_decimal_point;
459 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
461 setVAlign(param_str);
462 setTableAlignment(param_str);
464 if (booktabsRB->isChecked())
465 setParam(param_str, Tabular::SET_BOOKTABS);
467 setParam(param_str, Tabular::UNSET_BOOKTABS);
470 switch (topspaceCO->currentIndex()) {
472 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
475 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
478 if (!topspaceED->text().isEmpty())
479 setParam(param_str, Tabular::SET_TOP_SPACE,
480 widgetsToLength(topspaceED, topspaceUnitLC));
485 switch (bottomspaceCO->currentIndex()) {
487 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
490 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
493 if (!bottomspaceED->text().isEmpty())
494 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
495 widgetsToLength(bottomspaceED,
501 switch (interlinespaceCO->currentIndex()) {
503 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
506 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
509 if (!interlinespaceED->text().isEmpty())
510 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
511 widgetsToLength(interlinespaceED,
512 interlinespaceUnitLC));
517 if (borders->getTop() && borders->getBottom() && borders->getLeft()
518 && borders->getRight())
519 setParam(param_str, Tabular::SET_ALL_LINES);
520 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
521 && !borders->getRight())
522 setParam(param_str, Tabular::UNSET_ALL_LINES);
524 setParam(param_str, Tabular::SET_LINE_LEFT,
525 borders->getLeft() ? "true" : "false");
526 setParam(param_str, Tabular::SET_LINE_RIGHT,
527 borders->getRight() ? "true" : "false");
528 setParam(param_str, Tabular::SET_LINE_TOP,
529 borders->getTop() ? "true" : "false");
530 setParam(param_str, Tabular::SET_LINE_BOTTOM,
531 borders->getBottom() ? "true" : "false");
534 // apply the special alignment
535 string special = fromqstr(specialAlignmentED->text());
538 if (multicolumnCB->isChecked())
539 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
541 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
544 if (multicolumnCB->isChecked())
545 setParam(param_str, Tabular::SET_MULTICOLUMN);
547 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
549 // apply the multirow offset
550 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
551 if (mroffset.empty())
553 if (multirowCB->isChecked())
554 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
556 if (multirowCB->isChecked())
557 setParam(param_str, Tabular::SET_MULTIROW);
559 setParam(param_str, Tabular::UNSET_MULTIROW);
561 if (rotateTabularCB->isChecked())
562 setParam(param_str, Tabular::SET_ROTATE_TABULAR);
564 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR);
565 // store the cell rotation angle
566 string angle = convert<string>(rotateCellAngleSB->value());
567 if (rotateCellCB->isChecked())
568 setParam(param_str, Tabular::SET_ROTATE_CELL, angle);
570 setParam(param_str, Tabular::UNSET_ROTATE_CELL, angle);
572 if (longTabularCB->isChecked())
573 setParam(param_str, Tabular::SET_LONGTABULAR);
575 setParam(param_str, Tabular::UNSET_LONGTABULAR);
577 if (newpageCB->isChecked())
578 setParam(param_str, Tabular::SET_LTNEWPAGE);
580 if (captionStatusCB->isChecked())
581 setParam(param_str, Tabular::SET_LTCAPTION);
583 setParam(param_str, Tabular::UNSET_LTCAPTION);
585 if (headerStatusCB->isChecked())
586 setParam(param_str, Tabular::SET_LTHEAD, "none");
588 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
590 if (headerBorderAboveCB->isChecked())
591 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
593 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
595 if (headerBorderBelowCB->isChecked())
596 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
598 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
599 if (firstheaderBorderAboveCB->isChecked())
600 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
602 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
603 if (firstheaderBorderBelowCB->isChecked())
604 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
606 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
607 if (firstheaderStatusCB->isChecked())
608 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
610 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
611 if (firstheaderNoContentsCB->isChecked())
612 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
614 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
615 if (footerStatusCB->isChecked())
616 setParam(param_str, Tabular::SET_LTFOOT, "none");
618 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
619 if (footerBorderAboveCB->isChecked())
620 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
622 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
623 if (footerBorderBelowCB->isChecked())
624 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
626 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
627 if (lastfooterStatusCB->isChecked())
628 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
630 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
631 if (lastfooterBorderAboveCB->isChecked())
632 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
634 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
635 if (lastfooterBorderBelowCB->isChecked())
636 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
638 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
639 if (lastfooterNoContentsCB->isChecked())
640 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
642 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
644 if (leftRB->isChecked())
645 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
646 else if (centerRB->isChecked())
647 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
648 else if (rightRB->isChecked())
649 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
651 return from_utf8(param_str);
655 static Length getColumnPWidth(Tabular const & t, size_t cell)
657 return t.column_info[t.cellColumn(cell)].p_width;
661 static Length getMColumnPWidth(Tabular const & t, size_t cell)
663 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
664 return t.cellInfo(cell).p_width;
669 static Length getMROffset(Tabular const & t, size_t cell)
671 if (t.isMultiRow(cell))
672 return t.cellInfo(cell).mroffset;
677 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
679 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
680 return t.cellInfo(cell).align_special;
681 return t.column_info[t.cellColumn(cell)].align_special;
685 void GuiTabular::paramsToDialog(Inset const * inset)
687 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
688 // Copy Tabular of current inset.
689 Tabular const & tabular = itab->tabular;
691 BufferView const * bv = guiApp->currentView()->currentBufferView();
692 size_t const cell = bv->cursor().idx();
694 Tabular::row_type const row = tabular.cellRow(cell);
695 Tabular::col_type const col = tabular.cellColumn(cell);
697 tabularRowED->setText(QString::number(row + 1));
698 tabularColumnED->setText(QString::number(col + 1));
700 bool const multicol = tabular.isMultiColumn(cell);
701 multicolumnCB->setChecked(multicol);
703 bool const multirow = tabular.isMultiRow(cell);
704 multirowCB->setChecked(multirow);
706 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
707 if (tabular.getRotateCell(cell) != 0)
708 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
710 rotateCellAngleSB->setValue(90);
711 rotateTabularCB->setChecked(tabular.rotate);
713 longTabularCB->setChecked(tabular.is_long_tabular);
715 borders->setTop(tabular.topLine(cell));
716 borders->setBottom(tabular.bottomLine(cell));
717 borders->setLeft(tabular.leftLine(cell));
718 borders->setRight(tabular.rightLine(cell));
719 // repaint the setborder widget
722 Length::UNIT const default_unit = Length::defaultUnit();
724 ///////////////////////////////////
725 // Set width and alignment
727 Length const tabwidth = tabular.tabularWidth();
729 tabularWidthED->clear();
731 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
732 tabwidth.asString(), default_unit);
737 special = getAlignSpecial(tabular, cell,
738 Tabular::SET_SPECIAL_MULTICOLUMN);
739 pwidth = getMColumnPWidth(tabular, cell);
741 special = getAlignSpecial(tabular, cell,
742 Tabular::SET_SPECIAL_COLUMN);
743 pwidth = getColumnPWidth(tabular, cell);
747 columnWidthED->clear();
749 colwidth = pwidth.asString();
750 lengthToWidgets(columnWidthED, columnWidthUnitLC,
751 colwidth, default_unit);
755 mroffset = getMROffset(tabular, cell);
758 multirowOffsetED->clear();
760 offset = mroffset.asString();
761 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
762 offset, default_unit);
764 specialAlignmentED->setText(toqstr(special));
765 ///////////////////////////////////
768 borderDefaultRB->setChecked(!tabular.use_booktabs);
769 booktabsRB->setChecked(tabular.use_booktabs);
771 if (tabular.row_info[row].top_space.empty()
772 && !tabular.row_info[row].top_space_default) {
773 topspaceCO->setCurrentIndex(0);
774 } else if (tabular.row_info[row].top_space_default) {
775 topspaceCO->setCurrentIndex(1);
777 topspaceCO->setCurrentIndex(2);
778 lengthToWidgets(topspaceED,
780 tabular.row_info[row].top_space.asString(),
784 if (tabular.row_info[row].bottom_space.empty()
785 && !tabular.row_info[row].bottom_space_default) {
786 bottomspaceCO->setCurrentIndex(0);
787 } else if (tabular.row_info[row].bottom_space_default) {
788 bottomspaceCO->setCurrentIndex(1);
790 bottomspaceCO->setCurrentIndex(2);
791 lengthToWidgets(bottomspaceED,
793 tabular.row_info[row].bottom_space.asString(),
797 if (tabular.row_info[row].interline_space.empty()
798 && !tabular.row_info[row].interline_space_default) {
799 interlinespaceCO->setCurrentIndex(0);
800 } else if (tabular.row_info[row].interline_space_default) {
801 interlinespaceCO->setCurrentIndex(1);
803 interlinespaceCO->setCurrentIndex(2);
804 lengthToWidgets(interlinespaceED,
805 interlinespaceUnitLC,
806 tabular.row_info[row].interline_space.asString(),
811 hAlignCO->addItem(qt_("Left"), toqstr("left"));
812 hAlignCO->addItem(qt_("Center"), toqstr("center"));
813 hAlignCO->addItem(qt_("Right"), toqstr("right"));
814 if (!multicol && !pwidth.zero())
815 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
817 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
820 switch (tabular.getAlignment(cell)) {
824 case LYX_ALIGN_CENTER:
827 case LYX_ALIGN_RIGHT:
830 case LYX_ALIGN_BLOCK:
832 if (!multicol && !pwidth.zero())
836 case LYX_ALIGN_DECIMAL:
843 // we should never end up here
846 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
849 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
850 if (decimal_point.isEmpty())
851 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
852 decimalPointED->setText(decimal_point);
855 switch (tabular.getVAlignment(cell)) {
856 case Tabular::LYX_VALIGN_TOP:
859 case Tabular::LYX_VALIGN_MIDDLE:
862 case Tabular::LYX_VALIGN_BOTTOM:
871 vAlignCO->setCurrentIndex(valign);
874 switch (tabular.tabular_valignment) {
875 case Tabular::LYX_VALIGN_TOP:
878 case Tabular::LYX_VALIGN_MIDDLE:
881 case Tabular::LYX_VALIGN_BOTTOM:
888 TableAlignCO->setCurrentIndex(tableValign);
890 if (!tabular.is_long_tabular) {
891 headerStatusCB->setChecked(false);
892 headerBorderAboveCB->setChecked(false);
893 headerBorderBelowCB->setChecked(false);
894 firstheaderStatusCB->setChecked(false);
895 firstheaderBorderAboveCB->setChecked(false);
896 firstheaderBorderBelowCB->setChecked(false);
897 firstheaderNoContentsCB->setChecked(false);
898 footerStatusCB->setChecked(false);
899 footerBorderAboveCB->setChecked(false);
900 footerBorderBelowCB->setChecked(false);
901 lastfooterStatusCB->setChecked(false);
902 lastfooterBorderAboveCB->setChecked(false);
903 lastfooterBorderBelowCB->setChecked(false);
904 lastfooterNoContentsCB->setChecked(false);
905 newpageCB->setChecked(false);
906 captionStatusCB->blockSignals(true);
907 captionStatusCB->setChecked(false);
908 captionStatusCB->blockSignals(false);
912 // longtables cannot have a vertical alignment
913 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
915 switch (tabular.longtabular_alignment) {
916 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
917 leftRB->setChecked(true);
919 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
920 centerRB->setChecked(true);
922 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
923 rightRB->setChecked(true);
926 centerRB->setChecked(true);
929 captionStatusCB->blockSignals(true);
930 captionStatusCB->setChecked(tabular.ltCaption(row));
931 captionStatusCB->blockSignals(false);
935 bool row_set = tabular.getRowOfLTHead(row, ltt);
936 headerStatusCB->setChecked(row_set);
938 headerBorderAboveCB->setChecked(ltt.topDL);
939 headerBorderBelowCB->setChecked(ltt.bottomDL);
942 headerBorderAboveCB->setChecked(false);
943 headerBorderBelowCB->setChecked(false);
944 firstheaderNoContentsCB->setChecked(false);
948 row_set = tabular.getRowOfLTFirstHead(row, ltt);
949 firstheaderStatusCB->setChecked(row_set);
950 if (ltt.set && (!ltt.empty || !use_empty)) {
951 firstheaderBorderAboveCB->setChecked(ltt.topDL);
952 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
954 firstheaderBorderAboveCB->setChecked(false);
955 firstheaderBorderBelowCB->setChecked(false);
958 row_set = tabular.getRowOfLTFoot(row, ltt);
959 footerStatusCB->setChecked(row_set);
961 footerBorderAboveCB->setChecked(ltt.topDL);
962 footerBorderBelowCB->setChecked(ltt.bottomDL);
965 footerBorderAboveCB->setChecked(false);
966 footerBorderBelowCB->setChecked(false);
967 lastfooterNoContentsCB->setChecked(false);
971 row_set = tabular.getRowOfLTLastFoot(row, ltt);
972 lastfooterStatusCB->setChecked(row_set);
973 if (ltt.set && (!ltt.empty || !use_empty)) {
974 lastfooterBorderAboveCB->setChecked(ltt.topDL);
975 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
977 lastfooterBorderAboveCB->setChecked(false);
978 lastfooterBorderBelowCB->setChecked(false);
980 newpageCB->setChecked(tabular.getLTNewPage(row));
982 // first header can only be suppressed when there is a header
983 firstheader_suppressable_ = tabular.haveLTHead()
984 && !tabular.haveLTFirstHead();
985 // last footer can only be suppressed when there is a footer
986 lastfooter_suppressable_ = tabular.haveLTFoot()
987 && !tabular.haveLTLastFoot();
989 // after setting the features, check if they are enabled
994 bool GuiTabular::funcEnabled(Tabular::Feature f) const
996 string cmd = "tabular " + featureAsString(f);
997 return getStatus(FuncRequest(LFUN_INSET_MODIFY, cmd)).enabled();
1001 } // namespace frontend
1004 #include "moc_GuiTabular.cpp"