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(textEdited(const QString &)),
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::enableWidgets() const
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 columnWidthUnitLC->setEnabled(specialAlignmentED->text().isEmpty());
208 // if the column has a width, multirows are always left-aligned
209 // therefore disable hAlignCB in this case
210 hAlignCO->setEnabled(!(multirowCB->isChecked()
211 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
212 && specialAlignmentED->text().isEmpty());
213 // decimal alignment is only possible for non-multicol and non-multirow cells
214 if ((multicolumnCB->isChecked() || multirowCB->isChecked())
215 && hAlignCO->findData(toqstr("decimal")))
216 hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
217 else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
218 && hAlignCO->findData(toqstr("decimal")) == -1)
219 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
221 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
222 decimalPointED->setEnabled(dalign);
223 decimalLA->setEnabled(dalign);
225 bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
226 && !longTabularCB->isChecked();
227 tabularWidthLA->setEnabled(setwidth);
228 tabularWidthED->setEnabled(setwidth);
229 tabularWidthUnitLC->setEnabled(setwidth);
231 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked());
232 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
234 bool const enable_valign =
235 !multirowCB->isChecked()
236 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
237 && specialAlignmentED->text().isEmpty();
238 vAlignCO->setEnabled(enable_valign);
239 vAlignLA->setEnabled(enable_valign);
241 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
242 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
243 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
244 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
245 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
246 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
247 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
249 // setting as longtable is not allowed when table is inside a float
250 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
251 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
252 bool const longtabular = longTabularCB->isChecked();
253 longtableGB->setEnabled(true);
254 newpageCB->setEnabled(longtabular);
255 alignmentGB->setEnabled(longtabular);
256 // longtables and tabular* cannot have a vertical alignment
257 TableAlignLA->setDisabled(is_tabular_star || longtabular);
258 TableAlignCO->setDisabled(is_tabular_star || longtabular);
260 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
261 // depending on the cursor position is very very unintuitive...
262 // We need some edit boxes to show which rows are header/footer/etc
263 // without having to move the cursor first.
264 headerStatusCB->setEnabled(longtabular
265 && (headerStatusCB->isChecked() ?
266 funcEnabled(Tabular::UNSET_LTHEAD) :
267 funcEnabled(Tabular::SET_LTHEAD)));
268 headerBorderAboveCB->setEnabled(longtabular
269 && headerStatusCB->isChecked());
270 headerBorderBelowCB->setEnabled(longtabular
271 && headerStatusCB->isChecked());
273 // first header can only be suppressed when there is a header
274 // firstheader_suppressable_ is set in paramsToDialog
275 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
276 // check if setting a first header is allowed
277 // additionally check firstheaderNoContentsCB because when this is
278 // the case a first header makes no sense
279 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
280 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
281 funcEnabled(Tabular::SET_LTFIRSTHEAD))
282 && longtabular && !firstheaderNoContentsCB->isChecked());
283 firstheaderBorderAboveCB->setEnabled(longtabular
284 && firstheaderStatusCB->isChecked());
285 firstheaderBorderBelowCB->setEnabled(longtabular
286 && firstheaderStatusCB->isChecked());
288 footerStatusCB->setEnabled(longtabular
289 && (footerStatusCB->isChecked() ?
290 funcEnabled(Tabular::UNSET_LTFOOT) :
291 funcEnabled(Tabular::SET_LTFOOT)));
292 footerBorderAboveCB->setEnabled(longtabular
293 && footerBorderAboveCB->isChecked());
294 footerBorderBelowCB->setEnabled(longtabular
295 && footerBorderAboveCB->isChecked());
297 // last footer can only be suppressed when there is a footer
298 // lastfooter_suppressable_ is set in paramsToDialog
299 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
300 // check if setting a last footer is allowed
301 // additionally check lastfooterNoContentsCB because when this is
302 // the case a last footer makes no sense
303 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
304 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
305 funcEnabled(Tabular::SET_LTLASTFOOT))
306 && longtabular && !lastfooterNoContentsCB->isChecked());
307 lastfooterBorderAboveCB->setEnabled(longtabular
308 && lastfooterBorderAboveCB->isChecked());
309 lastfooterBorderBelowCB->setEnabled(longtabular
310 && lastfooterBorderAboveCB->isChecked());
312 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
315 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
316 && !dalign && !multirowCB->isChecked());
317 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
318 && !dalign && !multicolumnCB->isChecked());
319 bool const enable_mr = multirowCB->isChecked();
320 multirowOffsetLA->setEnabled(enable_mr);
321 multirowOffsetED->setEnabled(enable_mr);
322 multirowOffsetUnitLC->setEnabled(enable_mr);
324 // Vertical lines cannot be set in formal tables
325 borders->setLeftEnabled(!booktabsRB->isChecked());
326 borders->setRightEnabled(!booktabsRB->isChecked());
330 void GuiTabular::checkEnabled()
337 void GuiTabular::borderSet_clicked()
339 borders->setTop(true);
340 borders->setBottom(true);
341 borders->setLeft(true);
342 borders->setRight(true);
343 // repaint the setborder widget
349 void GuiTabular::borderUnset_clicked()
351 borders->setTop(false);
352 borders->setBottom(false);
353 borders->setLeft(false);
354 borders->setRight(false);
355 // repaint the setborder widget
361 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
364 param_str += featureAsString(f) + ' ' + arg;
368 void GuiTabular::setHAlign(string & param_str) const
370 Tabular::Feature num = Tabular::ALIGN_LEFT;
371 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
373 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
374 if (align == "left") {
375 num = Tabular::ALIGN_LEFT;
376 multi_num = Tabular::M_ALIGN_LEFT;
377 } else if (align == "center") {
378 num = Tabular::ALIGN_CENTER;
379 multi_num = Tabular::M_ALIGN_CENTER;
380 } else if (align == "right") {
381 num = Tabular::ALIGN_RIGHT;
382 multi_num = Tabular::M_ALIGN_RIGHT;
383 } else if (align == "justified") {
384 num = Tabular::ALIGN_BLOCK;
385 //multi_num: no equivalent
386 } else if (align == "decimal") {
387 num = Tabular::ALIGN_DECIMAL;
388 //multi_num: no equivalent
391 if (multicolumnCB->isChecked())
392 setParam(param_str, multi_num);
394 setParam(param_str, num);
398 void GuiTabular::setVAlign(string & param_str) const
400 int const align = vAlignCO->currentIndex();
401 enum VALIGN { TOP, MIDDLE, BOTTOM };
405 case 0: v = TOP; break;
406 case 1: v = MIDDLE; break;
407 case 2: v = BOTTOM; break;
410 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
411 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
415 num = Tabular::VALIGN_TOP;
416 multi_num = Tabular::M_VALIGN_TOP;
419 num = Tabular::VALIGN_MIDDLE;
420 multi_num = Tabular::M_VALIGN_MIDDLE;
423 num = Tabular::VALIGN_BOTTOM;
424 multi_num = Tabular::M_VALIGN_BOTTOM;
427 if (multicolumnCB->isChecked() || multirowCB->isChecked())
428 setParam(param_str, multi_num);
430 setParam(param_str, num);
434 void GuiTabular::setTableAlignment(string & param_str) const
436 int const align = TableAlignCO->currentIndex();
438 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
440 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
442 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
448 docstring GuiTabular::dialogToParams() const
450 string param_str = "tabular";
453 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
454 if (tabwidth.empty())
456 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
458 // apply the fixed width values
459 // this must be done before applying the column alignment
460 // because its value influences the alignment of multirow cells
461 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
464 if (multicolumnCB->isChecked())
465 setParam(param_str, Tabular::SET_MPWIDTH, width);
467 setParam(param_str, Tabular::SET_PWIDTH, width);
469 // apply the column alignment
470 // multirows inherit the alignment from the column; if a column width
471 // is set, multirows are always left-aligned so that in this case
472 // its alignment must not be applied (see bug #8084)
473 if (!(multirowCB->isChecked() && width != "0pt"))
474 setHAlign(param_str);
476 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
477 string decimal_point = fromqstr(decimalPointED->text());
478 if (decimal_point.empty())
479 decimal_point = lyxrc.default_decimal_point;
480 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
482 setVAlign(param_str);
483 setTableAlignment(param_str);
485 if (booktabsRB->isChecked())
486 setParam(param_str, Tabular::SET_BOOKTABS);
488 setParam(param_str, Tabular::UNSET_BOOKTABS);
491 switch (topspaceCO->currentIndex()) {
493 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
496 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
499 if (!topspaceED->text().isEmpty())
500 setParam(param_str, Tabular::SET_TOP_SPACE,
501 widgetsToLength(topspaceED, topspaceUnitLC));
506 switch (bottomspaceCO->currentIndex()) {
508 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
511 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
514 if (!bottomspaceED->text().isEmpty())
515 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
516 widgetsToLength(bottomspaceED,
522 switch (interlinespaceCO->currentIndex()) {
524 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
527 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
530 if (!interlinespaceED->text().isEmpty())
531 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
532 widgetsToLength(interlinespaceED,
533 interlinespaceUnitLC));
538 if (borders->getTop() && borders->getBottom() && borders->getLeft()
539 && borders->getRight())
540 setParam(param_str, Tabular::SET_ALL_LINES);
541 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
542 && !borders->getRight())
543 setParam(param_str, Tabular::UNSET_ALL_LINES);
545 setParam(param_str, Tabular::SET_LINE_LEFT,
546 borders->getLeft() ? "true" : "false");
547 setParam(param_str, Tabular::SET_LINE_RIGHT,
548 borders->getRight() ? "true" : "false");
549 setParam(param_str, Tabular::SET_LINE_TOP,
550 borders->getTop() ? "true" : "false");
551 setParam(param_str, Tabular::SET_LINE_BOTTOM,
552 borders->getBottom() ? "true" : "false");
555 // apply the special alignment
556 string special = fromqstr(specialAlignmentED->text());
559 if (multicolumnCB->isChecked())
560 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
562 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
565 if (multicolumnCB->isChecked())
566 setParam(param_str, Tabular::SET_MULTICOLUMN);
568 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
570 // apply the multirow offset
571 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
572 if (mroffset.empty())
574 if (multirowCB->isChecked())
575 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
577 if (multirowCB->isChecked())
578 setParam(param_str, Tabular::SET_MULTIROW);
580 setParam(param_str, Tabular::UNSET_MULTIROW);
581 // store the table rotation angle
582 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
583 if (rotateTabularCB->isChecked())
584 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
586 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
587 // store the cell rotation angle
588 string const cell_angle = convert<string>(rotateCellAngleSB->value());
589 if (rotateCellCB->isChecked())
590 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
592 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
594 if (longTabularCB->isChecked())
595 setParam(param_str, Tabular::SET_LONGTABULAR);
597 setParam(param_str, Tabular::UNSET_LONGTABULAR);
599 if (newpageCB->isChecked())
600 setParam(param_str, Tabular::SET_LTNEWPAGE);
602 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
604 if (captionStatusCB->isChecked())
605 setParam(param_str, Tabular::SET_LTCAPTION);
607 setParam(param_str, Tabular::UNSET_LTCAPTION);
609 if (headerStatusCB->isChecked())
610 setParam(param_str, Tabular::SET_LTHEAD, "none");
612 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
614 if (headerBorderAboveCB->isChecked())
615 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
617 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
619 if (headerBorderBelowCB->isChecked())
620 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
622 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
623 if (firstheaderBorderAboveCB->isChecked())
624 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
626 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
627 if (firstheaderBorderBelowCB->isChecked())
628 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
630 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
631 if (firstheaderStatusCB->isChecked())
632 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
634 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
635 if (firstheaderNoContentsCB->isChecked())
636 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
638 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
639 if (footerStatusCB->isChecked())
640 setParam(param_str, Tabular::SET_LTFOOT, "none");
642 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
643 if (footerBorderAboveCB->isChecked())
644 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
646 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
647 if (footerBorderBelowCB->isChecked())
648 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
650 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
651 if (lastfooterStatusCB->isChecked())
652 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
654 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
655 if (lastfooterBorderAboveCB->isChecked())
656 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
658 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
659 if (lastfooterBorderBelowCB->isChecked())
660 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
662 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
663 if (lastfooterNoContentsCB->isChecked())
664 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
666 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
668 if (leftRB->isChecked())
669 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
670 else if (centerRB->isChecked())
671 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
672 else if (rightRB->isChecked())
673 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
675 return from_utf8(param_str);
679 static Length getColumnPWidth(Tabular const & t, size_t cell)
681 return t.column_info[t.cellColumn(cell)].p_width;
685 static Length getMColumnPWidth(Tabular const & t, size_t cell)
687 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
688 return t.cellInfo(cell).p_width;
693 static Length getMROffset(Tabular const & t, size_t cell)
695 if (t.isMultiRow(cell))
696 return t.cellInfo(cell).mroffset;
701 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
703 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
704 return t.cellInfo(cell).align_special;
705 return t.column_info[t.cellColumn(cell)].align_special;
709 void GuiTabular::paramsToDialog(Inset const * inset)
711 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
712 // Copy Tabular of current inset.
713 Tabular const & tabular = itab->tabular;
715 BufferView const * bv = guiApp->currentView()->currentBufferView();
716 size_t const cell = bv->cursor().idx();
718 Tabular::row_type const row = tabular.cellRow(cell);
719 Tabular::col_type const col = tabular.cellColumn(cell);
721 tabularRowED->setText(QString::number(row + 1));
722 tabularColumnED->setText(QString::number(col + 1));
724 bool const multicol = tabular.isMultiColumn(cell);
725 multicolumnCB->setChecked(multicol);
727 bool const multirow = tabular.isMultiRow(cell);
728 multirowCB->setChecked(multirow);
730 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
731 if (rotateCellCB->isChecked()) {
732 if (tabular.getRotateCell(cell) != 0)
733 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
735 rotateCellAngleSB->setValue(90);
738 rotateTabularCB->setChecked(tabular.rotate != 0);
739 if (rotateTabularCB->isChecked())
740 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
742 longTabularCB->setChecked(tabular.is_long_tabular);
744 borders->setTop(tabular.topLine(cell));
745 borders->setBottom(tabular.bottomLine(cell));
746 borders->setLeft(tabular.leftLine(cell));
747 borders->setRight(tabular.rightLine(cell));
748 // repaint the setborder widget
751 Length::UNIT const default_unit = Length::defaultUnit();
753 ///////////////////////////////////
754 // Set width and alignment
756 Length const tabwidth = tabular.tabularWidth();
758 && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
759 tabularWidthED->clear();
761 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
762 tabwidth.asString(), default_unit);
767 special = getAlignSpecial(tabular, cell,
768 Tabular::SET_SPECIAL_MULTICOLUMN);
769 pwidth = getMColumnPWidth(tabular, cell);
771 special = getAlignSpecial(tabular, cell,
772 Tabular::SET_SPECIAL_COLUMN);
773 pwidth = getColumnPWidth(tabular, cell);
777 && !(columnWidthED->hasFocus() && columnWidthED->text() == "0"))
778 columnWidthED->clear();
780 colwidth = pwidth.asString();
781 lengthToWidgets(columnWidthED, columnWidthUnitLC,
782 colwidth, default_unit);
786 mroffset = getMROffset(tabular, cell);
789 && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
790 multirowOffsetED->clear();
792 offset = mroffset.asString();
793 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
794 offset, default_unit);
796 specialAlignmentED->setText(toqstr(special));
797 ///////////////////////////////////
800 borderDefaultRB->setChecked(!tabular.use_booktabs);
801 booktabsRB->setChecked(tabular.use_booktabs);
803 if (tabular.row_info[row].top_space.empty()
804 && !tabular.row_info[row].top_space_default) {
805 topspaceCO->setCurrentIndex(0);
806 } else if (tabular.row_info[row].top_space_default) {
807 topspaceCO->setCurrentIndex(1);
809 topspaceCO->setCurrentIndex(2);
810 lengthToWidgets(topspaceED,
812 tabular.row_info[row].top_space.asString(),
816 if (tabular.row_info[row].bottom_space.empty()
817 && !tabular.row_info[row].bottom_space_default) {
818 bottomspaceCO->setCurrentIndex(0);
819 } else if (tabular.row_info[row].bottom_space_default) {
820 bottomspaceCO->setCurrentIndex(1);
822 bottomspaceCO->setCurrentIndex(2);
823 lengthToWidgets(bottomspaceED,
825 tabular.row_info[row].bottom_space.asString(),
829 if (tabular.row_info[row].interline_space.empty()
830 && !tabular.row_info[row].interline_space_default) {
831 interlinespaceCO->setCurrentIndex(0);
832 } else if (tabular.row_info[row].interline_space_default) {
833 interlinespaceCO->setCurrentIndex(1);
835 interlinespaceCO->setCurrentIndex(2);
836 lengthToWidgets(interlinespaceED,
837 interlinespaceUnitLC,
838 tabular.row_info[row].interline_space.asString(),
843 hAlignCO->addItem(qt_("Left"), toqstr("left"));
844 hAlignCO->addItem(qt_("Center"), toqstr("center"));
845 hAlignCO->addItem(qt_("Right"), toqstr("right"));
846 if (!multicol && !pwidth.zero())
847 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
848 if (!multicol && !multirow)
849 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
852 switch (tabular.getAlignment(cell)) {
856 case LYX_ALIGN_CENTER:
859 case LYX_ALIGN_RIGHT:
862 case LYX_ALIGN_BLOCK:
864 if (!multicol && !pwidth.zero())
868 case LYX_ALIGN_DECIMAL:
870 if (!multicol && !multirow)
875 // we should never end up here
878 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
881 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
882 if (decimal_point.isEmpty())
883 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
884 decimalPointED->setText(decimal_point);
887 switch (tabular.getVAlignment(cell)) {
888 case Tabular::LYX_VALIGN_TOP:
891 case Tabular::LYX_VALIGN_MIDDLE:
894 case Tabular::LYX_VALIGN_BOTTOM:
903 vAlignCO->setCurrentIndex(valign);
906 switch (tabular.tabular_valignment) {
907 case Tabular::LYX_VALIGN_TOP:
910 case Tabular::LYX_VALIGN_MIDDLE:
913 case Tabular::LYX_VALIGN_BOTTOM:
920 TableAlignCO->setCurrentIndex(tableValign);
922 if (!tabular.is_long_tabular) {
923 headerStatusCB->setChecked(false);
924 headerBorderAboveCB->setChecked(false);
925 headerBorderBelowCB->setChecked(false);
926 firstheaderStatusCB->setChecked(false);
927 firstheaderBorderAboveCB->setChecked(false);
928 firstheaderBorderBelowCB->setChecked(false);
929 firstheaderNoContentsCB->setChecked(false);
930 footerStatusCB->setChecked(false);
931 footerBorderAboveCB->setChecked(false);
932 footerBorderBelowCB->setChecked(false);
933 lastfooterStatusCB->setChecked(false);
934 lastfooterBorderAboveCB->setChecked(false);
935 lastfooterBorderBelowCB->setChecked(false);
936 lastfooterNoContentsCB->setChecked(false);
937 newpageCB->setChecked(false);
938 captionStatusCB->blockSignals(true);
939 captionStatusCB->setChecked(false);
940 captionStatusCB->blockSignals(false);
944 // longtables cannot have a vertical alignment
945 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
947 switch (tabular.longtabular_alignment) {
948 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
949 leftRB->setChecked(true);
951 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
952 centerRB->setChecked(true);
954 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
955 rightRB->setChecked(true);
958 centerRB->setChecked(true);
961 captionStatusCB->blockSignals(true);
962 captionStatusCB->setChecked(tabular.ltCaption(row));
963 captionStatusCB->blockSignals(false);
967 bool row_set = tabular.getRowOfLTHead(row, ltt);
968 headerStatusCB->setChecked(row_set);
970 headerBorderAboveCB->setChecked(ltt.topDL);
971 headerBorderBelowCB->setChecked(ltt.bottomDL);
974 headerBorderAboveCB->setChecked(false);
975 headerBorderBelowCB->setChecked(false);
976 firstheaderNoContentsCB->setChecked(false);
980 row_set = tabular.getRowOfLTFirstHead(row, ltt);
981 firstheaderStatusCB->setChecked(row_set);
982 if (ltt.set && (!ltt.empty || !use_empty)) {
983 firstheaderBorderAboveCB->setChecked(ltt.topDL);
984 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
986 firstheaderBorderAboveCB->setChecked(false);
987 firstheaderBorderBelowCB->setChecked(false);
990 row_set = tabular.getRowOfLTFoot(row, ltt);
991 footerStatusCB->setChecked(row_set);
993 footerBorderAboveCB->setChecked(ltt.topDL);
994 footerBorderBelowCB->setChecked(ltt.bottomDL);
997 footerBorderAboveCB->setChecked(false);
998 footerBorderBelowCB->setChecked(false);
999 lastfooterNoContentsCB->setChecked(false);
1003 row_set = tabular.getRowOfLTLastFoot(row, ltt);
1004 lastfooterStatusCB->setChecked(row_set);
1005 if (ltt.set && (!ltt.empty || !use_empty)) {
1006 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1007 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1009 lastfooterBorderAboveCB->setChecked(false);
1010 lastfooterBorderBelowCB->setChecked(false);
1012 newpageCB->setChecked(tabular.getLTNewPage(row));
1014 // first header can only be suppressed when there is a header
1015 firstheader_suppressable_ = tabular.haveLTHead()
1016 && !tabular.haveLTFirstHead();
1017 // last footer can only be suppressed when there is a footer
1018 lastfooter_suppressable_ = tabular.haveLTFoot()
1019 && !tabular.haveLTLastFoot();
1021 // after setting the features, check if they are enabled
1026 bool GuiTabular::checkWidgets(bool readonly) const
1028 tabularRowED->setReadOnly(readonly);
1029 tabularColumnED->setReadOnly(readonly);
1030 tabularWidthED->setReadOnly(readonly);
1031 specialAlignmentED->setReadOnly(readonly);
1032 columnWidthED->setReadOnly(readonly);
1033 multirowOffsetED->setReadOnly(readonly);
1034 decimalPointED->setReadOnly(readonly);
1037 multicolumnCB->setEnabled(false);
1038 multirowCB->setEnabled(false);
1039 rotateCellCB->setEnabled(false);
1040 rotateCellAngleSB->setEnabled(false);
1041 rotateTabularCB->setEnabled(false);
1042 rotateTabularAngleSB->setEnabled(false);
1043 longTabularCB->setEnabled(false);
1044 borders->setEnabled(false);
1045 tabularWidthUnitLC->setEnabled(false);
1046 columnWidthUnitLC->setEnabled(false);
1047 multirowOffsetUnitLC->setEnabled(false);
1048 setBordersGB->setEnabled(false);
1049 allBordersGB->setEnabled(false);
1050 borderStyleGB->setEnabled(false);
1051 booktabsRB->setEnabled(false);
1052 topspaceCO->setEnabled(false);
1053 topspaceUnitLC->setEnabled(false);
1054 bottomspaceCO->setEnabled(false);
1055 bottomspaceUnitLC->setEnabled(false);
1056 interlinespaceCO->setEnabled(false);
1057 interlinespaceUnitLC->setEnabled(false);
1058 hAlignCO->setEnabled(false);
1059 vAlignCO->setEnabled(false);
1060 TableAlignCO->setEnabled(false);
1061 longtableGB->setEnabled(false);
1062 alignmentGB->setEnabled(false);
1066 return InsetParamsWidget::checkWidgets();
1070 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1072 FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1073 return getStatus(r).enabled();
1077 } // namespace frontend
1080 #include "moc_GuiTabular.cpp"