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"
37 #include <QPushButton>
38 #include <QRadioButton>
46 GuiTabular::GuiTabular(QWidget * parent)
47 : InsetParamsWidget(parent)
51 tabularWidthED->setValidator(unsignedLengthValidator(tabularWidthED));
52 columnWidthED->setValidator(unsignedLengthValidator(columnWidthED));
53 multirowOffsetED->setValidator(new LengthValidator(multirowOffsetED));
54 topspaceED->setValidator(new LengthValidator(topspaceED));
55 bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
56 interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
58 tabularWidthUnitLC->setCurrentItem(Length::defaultUnit());
59 columnWidthUnitLC->setCurrentItem(Length::defaultUnit());
60 multirowOffsetUnitLC->setCurrentItem(Length::defaultUnit());
61 topspaceUnitLC->setCurrentItem(Length::defaultUnit());
62 bottomspaceUnitLC->setCurrentItem(Length::defaultUnit());
63 interlinespaceUnitLC->setCurrentItem(Length::defaultUnit());
65 connect(topspaceED, SIGNAL(textEdited(const QString &)),
66 this, SLOT(checkEnabled()));
67 connect(topspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
68 this, SLOT(checkEnabled()));
69 connect(bottomspaceED, SIGNAL(textEdited(const QString &)),
70 this, SLOT(checkEnabled()));
71 connect(bottomspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
72 this, SLOT(checkEnabled()));
73 connect(interlinespaceED, SIGNAL(textEdited(const QString &)),
74 this, SLOT(checkEnabled()));
75 connect(interlinespaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
76 this, SLOT(checkEnabled()));
77 connect(booktabsRB, SIGNAL(clicked(bool)),
78 this, SLOT(checkEnabled()));
79 connect(borderDefaultRB, SIGNAL(clicked(bool)),
80 this, SLOT(checkEnabled()));
81 connect(borderSetPB, SIGNAL(clicked()),
82 this, SLOT(borderSet_clicked()));
83 connect(borderUnsetPB, SIGNAL(clicked()),
84 this, SLOT(borderUnset_clicked()));
85 connect(hAlignCO, SIGNAL(activated(int)),
86 this, SLOT(checkEnabled()));
87 connect(vAlignCO, SIGNAL(activated(int)),
88 this, SLOT(checkEnabled()));
89 connect(multicolumnCB, SIGNAL(clicked()),
90 this, SLOT(checkEnabled()));
91 connect(multirowCB, SIGNAL(clicked()),
92 this, SLOT(checkEnabled()));
93 connect(multirowOffsetED, SIGNAL(textEdited(const QString &)),
94 this, SLOT(checkEnabled()));
95 connect(multirowOffsetUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
96 this, SLOT(checkEnabled()));
97 connect(newpageCB, SIGNAL(clicked()),
98 this, SLOT(checkEnabled()));
99 connect(headerStatusCB, SIGNAL(clicked()),
100 this, SLOT(checkEnabled()));
101 connect(headerBorderAboveCB, SIGNAL(clicked()),
102 this, SLOT(checkEnabled()));
103 connect(headerBorderBelowCB, SIGNAL(clicked()),
104 this, SLOT(checkEnabled()));
105 connect(firstheaderStatusCB, SIGNAL(clicked()),
106 this, SLOT(checkEnabled()));
107 connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
108 this, SLOT(checkEnabled()));
109 connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
110 this, SLOT(checkEnabled()));
111 connect(firstheaderNoContentsCB, SIGNAL(clicked()),
112 this, SLOT(checkEnabled()));
113 connect(footerStatusCB, SIGNAL(clicked()),
114 this, SLOT(checkEnabled()));
115 connect(footerBorderAboveCB, SIGNAL(clicked()),
116 this, SLOT(checkEnabled()));
117 connect(footerBorderBelowCB, SIGNAL(clicked()),
118 this, SLOT(checkEnabled()));
119 connect(lastfooterStatusCB, SIGNAL(clicked()),
120 this, SLOT(checkEnabled()));
121 connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
122 this, SLOT(checkEnabled()));
123 connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
124 this, SLOT(checkEnabled()));
125 connect(lastfooterNoContentsCB, SIGNAL(clicked()),
126 this, SLOT(checkEnabled()));
127 connect(captionStatusCB, SIGNAL(clicked()),
128 this, SLOT(checkEnabled()));
129 connect(specialAlignmentED, SIGNAL(editingFinished()),
130 this, SLOT(checkEnabled()));
131 connect(columnWidthED, SIGNAL(textEdited(const QString &)),
132 this, SLOT(checkEnabled()));
133 connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
134 this, SLOT(checkEnabled()));
135 connect(borders, SIGNAL(topSet(bool)),
136 this, SLOT(checkEnabled()));
137 connect(borders, SIGNAL(bottomSet(bool)),
138 this, SLOT(checkEnabled()));
139 connect(borders, SIGNAL(rightSet(bool)),
140 this, SLOT(checkEnabled()));
141 connect(borders, SIGNAL(leftSet(bool)),
142 this, SLOT(checkEnabled()));
143 connect(rotateTabularCB, SIGNAL(clicked()),
144 this, SLOT(checkEnabled()));
145 connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
146 this, SLOT(checkEnabled()));
147 connect(rotateCellCB, SIGNAL(clicked()),
148 this, SLOT(checkEnabled()));
149 connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
150 this, SLOT(checkEnabled()));
151 connect(TableAlignCO, SIGNAL(activated(int)),
152 this, SLOT(checkEnabled()));
153 connect(longTabularCB, SIGNAL(clicked()),
154 this, SLOT(checkEnabled()));
155 connect(leftRB, SIGNAL(clicked()),
156 this, SLOT(checkEnabled()));
157 connect(centerRB, SIGNAL(clicked()),
158 this, SLOT(checkEnabled()));
159 connect(rightRB, SIGNAL(clicked()),
160 this, SLOT(checkEnabled()));
161 connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
162 this, SLOT(checkEnabled()));
164 decimalPointED->setInputMask("X; ");
165 decimalPointED->setMaxLength(1);
167 // initialize the length validator
168 addCheckedWidget(columnWidthED, columnWidthLA);
169 addCheckedWidget(multirowOffsetED, multirowOffsetLA);
170 addCheckedWidget(topspaceED, topspaceLA);
171 addCheckedWidget(bottomspaceED, bottomspaceLA);
172 addCheckedWidget(interlinespaceED, interlinespaceLA);
173 addCheckedWidget(tabularWidthED, tabularWidthLA);
177 void GuiTabular::on_topspaceCO_activated(int index)
179 bool const enable = (index == 2);
180 topspaceED->setEnabled(enable);
181 topspaceUnitLC->setEnabled(enable);
185 void GuiTabular::on_bottomspaceCO_activated(int index)
187 bool const enable = (index == 2);
188 bottomspaceED->setEnabled(enable);
189 bottomspaceUnitLC->setEnabled(enable);
193 void GuiTabular::on_interlinespaceCO_activated(int index)
195 bool const enable = (index == 2);
196 interlinespaceED->setEnabled(enable);
197 interlinespaceUnitLC->setEnabled(enable);
201 void GuiTabular::checkEnabled()
203 // if there is a LaTeX argument, the width and alignment will be overwritten
204 // therefore disable them in this case
205 columnWidthED->setEnabled(specialAlignmentED->text().isEmpty());
206 // if the column has a width, multirows are always left-aligned
207 // therefore disable hAlignCB in this case
208 hAlignCO->setEnabled(!(multirowCB->isChecked()
209 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
210 && specialAlignmentED->text().isEmpty());
212 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
213 decimalPointED->setEnabled(dalign);
214 decimalLA->setEnabled(dalign);
216 bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
217 && !longTabularCB->isChecked();
218 tabularWidthLA->setEnabled(setwidth);
219 tabularWidthED->setEnabled(setwidth);
220 tabularWidthUnitLC->setEnabled(setwidth);
222 rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked());
223 rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
225 bool const enable_valign =
226 !multirowCB->isChecked()
227 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
228 && specialAlignmentED->text().isEmpty();
229 vAlignCO->setEnabled(enable_valign);
230 vAlignLA->setEnabled(enable_valign);
232 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
233 topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
234 topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
235 bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
236 bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
237 interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
238 interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
240 // setting as longtable is not allowed when table is inside a float
241 bool const is_tabular_star = !tabularWidthED->text().isEmpty();
242 longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
243 bool const longtabular = longTabularCB->isChecked();
244 longtableGB->setEnabled(true);
245 newpageCB->setEnabled(longtabular);
246 alignmentGB->setEnabled(longtabular);
247 // longtables and tabular* cannot have a vertical alignment
248 TableAlignLA->setDisabled(is_tabular_star || longtabular);
249 TableAlignCO->setDisabled(is_tabular_star || longtabular);
251 // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
252 // depending on the cursor position is very very unintuitive...
253 // We need some edit boxes to show which rows are header/footer/etc
254 // without having to move the cursor first.
255 headerStatusCB->setEnabled(longtabular
256 && (headerStatusCB->isChecked() ?
257 funcEnabled(Tabular::UNSET_LTHEAD) :
258 funcEnabled(Tabular::SET_LTHEAD)));
259 headerBorderAboveCB->setEnabled(longtabular
260 && headerStatusCB->isChecked());
261 headerBorderBelowCB->setEnabled(longtabular
262 && headerStatusCB->isChecked());
264 // first header can only be suppressed when there is a header
265 // firstheader_suppressable_ is set in paramsToDialog
266 firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
267 // check if setting a first header is allowed
268 // additionally check firstheaderNoContentsCB because when this is
269 // the case a first header makes no sense
270 firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
271 funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
272 funcEnabled(Tabular::SET_LTFIRSTHEAD))
273 && longtabular && !firstheaderNoContentsCB->isChecked());
274 firstheaderBorderAboveCB->setEnabled(longtabular
275 && firstheaderStatusCB->isChecked());
276 firstheaderBorderBelowCB->setEnabled(longtabular
277 && firstheaderStatusCB->isChecked());
279 footerStatusCB->setEnabled(longtabular
280 && (footerStatusCB->isChecked() ?
281 funcEnabled(Tabular::UNSET_LTFOOT) :
282 funcEnabled(Tabular::SET_LTFOOT)));
283 footerBorderAboveCB->setEnabled(longtabular
284 && footerBorderAboveCB->isChecked());
285 footerBorderBelowCB->setEnabled(longtabular
286 && footerBorderAboveCB->isChecked());
288 // last footer can only be suppressed when there is a footer
289 // lastfooter_suppressable_ is set in paramsToDialog
290 lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
291 // check if setting a last footer is allowed
292 // additionally check lastfooterNoContentsCB because when this is
293 // the case a last footer makes no sense
294 lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
295 funcEnabled(Tabular::UNSET_LTLASTFOOT) :
296 funcEnabled(Tabular::SET_LTLASTFOOT))
297 && longtabular && !lastfooterNoContentsCB->isChecked());
298 lastfooterBorderAboveCB->setEnabled(longtabular
299 && lastfooterBorderAboveCB->isChecked());
300 lastfooterBorderBelowCB->setEnabled(longtabular
301 && lastfooterBorderAboveCB->isChecked());
303 captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
306 multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN));
307 multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW));
308 bool const enable_mr = multirowCB->isChecked();
309 multirowOffsetLA->setEnabled(enable_mr);
310 multirowOffsetED->setEnabled(enable_mr);
311 multirowOffsetUnitLC->setEnabled(enable_mr);
317 void GuiTabular::borderSet_clicked()
319 borders->setTop(true);
320 borders->setBottom(true);
321 borders->setLeft(true);
322 borders->setRight(true);
323 // repaint the setborder widget
329 void GuiTabular::borderUnset_clicked()
331 borders->setTop(false);
332 borders->setBottom(false);
333 borders->setLeft(false);
334 borders->setRight(false);
335 // repaint the setborder widget
341 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
344 param_str += featureAsString(f) + ' ' + arg;
348 void GuiTabular::setHAlign(string & param_str) const
350 Tabular::Feature num = Tabular::ALIGN_LEFT;
351 Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
353 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
354 if (align == "left") {
355 num = Tabular::ALIGN_LEFT;
356 multi_num = Tabular::M_ALIGN_LEFT;
357 } else if (align == "center") {
358 num = Tabular::ALIGN_CENTER;
359 multi_num = Tabular::M_ALIGN_CENTER;
360 } else if (align == "right") {
361 num = Tabular::ALIGN_RIGHT;
362 multi_num = Tabular::M_ALIGN_RIGHT;
363 } else if (align == "justified") {
364 num = Tabular::ALIGN_BLOCK;
365 //multi_num: no equivalent
366 } else if (align == "decimal") {
367 num = Tabular::ALIGN_DECIMAL;
368 //multi_num: no equivalent
371 if (multicolumnCB->isChecked())
372 setParam(param_str, multi_num);
374 setParam(param_str, num);
378 void GuiTabular::setVAlign(string & param_str) const
380 int const align = vAlignCO->currentIndex();
381 enum VALIGN { TOP, MIDDLE, BOTTOM };
385 case 0: v = TOP; break;
386 case 1: v = MIDDLE; break;
387 case 2: v = BOTTOM; break;
390 Tabular::Feature num = Tabular::VALIGN_MIDDLE;
391 Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
395 num = Tabular::VALIGN_TOP;
396 multi_num = Tabular::M_VALIGN_TOP;
399 num = Tabular::VALIGN_MIDDLE;
400 multi_num = Tabular::M_VALIGN_MIDDLE;
403 num = Tabular::VALIGN_BOTTOM;
404 multi_num = Tabular::M_VALIGN_BOTTOM;
407 if (multicolumnCB->isChecked() || multirowCB->isChecked())
408 setParam(param_str, multi_num);
410 setParam(param_str, num);
414 void GuiTabular::setTableAlignment(string & param_str) const
416 int const align = TableAlignCO->currentIndex();
418 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
420 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
422 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
428 docstring GuiTabular::dialogToParams() const
430 // FIXME: We should use Tabular directly.
431 string param_str = "tabular from-dialog";
434 string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
435 if (tabwidth.empty())
437 setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
439 // apply the fixed width values
440 // this must be done before applying the column alignment
441 // because its value influences the alignment of multirow cells
442 string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
445 if (multicolumnCB->isChecked())
446 setParam(param_str, Tabular::SET_MPWIDTH, width);
448 setParam(param_str, Tabular::SET_PWIDTH, width);
450 // apply the column alignment
451 // multirows inherit the alignment from the column; if a column width
452 // is set, multirows are always left-aligned so that in this case
453 // its alignment must not be applied (see bug #8084)
454 if (!(multirowCB->isChecked() && width != "0pt"))
455 setHAlign(param_str);
457 // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
458 string decimal_point = fromqstr(decimalPointED->text());
459 if (decimal_point.empty())
460 decimal_point = lyxrc.default_decimal_point;
461 setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
463 setVAlign(param_str);
464 setTableAlignment(param_str);
466 if (booktabsRB->isChecked())
467 setParam(param_str, Tabular::SET_BOOKTABS);
469 setParam(param_str, Tabular::UNSET_BOOKTABS);
472 switch (topspaceCO->currentIndex()) {
474 setParam(param_str, Tabular::SET_TOP_SPACE, "none");
477 setParam(param_str, Tabular::SET_TOP_SPACE, "default");
480 if (!topspaceED->text().isEmpty())
481 setParam(param_str, Tabular::SET_TOP_SPACE,
482 widgetsToLength(topspaceED, topspaceUnitLC));
487 switch (bottomspaceCO->currentIndex()) {
489 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
492 setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
495 if (!bottomspaceED->text().isEmpty())
496 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
497 widgetsToLength(bottomspaceED,
503 switch (interlinespaceCO->currentIndex()) {
505 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
508 setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
511 if (!interlinespaceED->text().isEmpty())
512 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
513 widgetsToLength(interlinespaceED,
514 interlinespaceUnitLC));
519 if (borders->getTop() && borders->getBottom() && borders->getLeft()
520 && borders->getRight())
521 setParam(param_str, Tabular::SET_ALL_LINES);
522 else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
523 && !borders->getRight())
524 setParam(param_str, Tabular::UNSET_ALL_LINES);
526 setParam(param_str, Tabular::SET_LINE_LEFT,
527 borders->getLeft() ? "true" : "false");
528 setParam(param_str, Tabular::SET_LINE_RIGHT,
529 borders->getRight() ? "true" : "false");
530 setParam(param_str, Tabular::SET_LINE_TOP,
531 borders->getTop() ? "true" : "false");
532 setParam(param_str, Tabular::SET_LINE_BOTTOM,
533 borders->getBottom() ? "true" : "false");
536 // apply the special alignment
537 string special = fromqstr(specialAlignmentED->text());
540 if (multicolumnCB->isChecked())
541 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
543 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
546 if (multicolumnCB->isChecked())
547 setParam(param_str, Tabular::SET_MULTICOLUMN);
549 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
551 // apply the multirow offset
552 string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
553 if (mroffset.empty())
555 if (multirowCB->isChecked())
556 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
558 if (multirowCB->isChecked())
559 setParam(param_str, Tabular::SET_MULTIROW);
561 setParam(param_str, Tabular::UNSET_MULTIROW);
562 // store the table rotation angle
563 string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
564 if (rotateTabularCB->isChecked())
565 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
567 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
568 // store the cell rotation angle
569 string const cell_angle = convert<string>(rotateCellAngleSB->value());
570 if (rotateCellCB->isChecked())
571 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
573 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
575 if (longTabularCB->isChecked())
576 setParam(param_str, Tabular::SET_LONGTABULAR);
578 setParam(param_str, Tabular::UNSET_LONGTABULAR);
580 if (newpageCB->isChecked())
581 setParam(param_str, Tabular::SET_LTNEWPAGE);
583 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
585 if (captionStatusCB->isChecked())
586 setParam(param_str, Tabular::SET_LTCAPTION);
588 setParam(param_str, Tabular::UNSET_LTCAPTION);
590 if (headerStatusCB->isChecked())
591 setParam(param_str, Tabular::SET_LTHEAD, "none");
593 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
595 if (headerBorderAboveCB->isChecked())
596 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
598 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
600 if (headerBorderBelowCB->isChecked())
601 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
603 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
604 if (firstheaderBorderAboveCB->isChecked())
605 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
607 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
608 if (firstheaderBorderBelowCB->isChecked())
609 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
611 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
612 if (firstheaderStatusCB->isChecked())
613 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
615 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
616 if (firstheaderNoContentsCB->isChecked())
617 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
619 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
620 if (footerStatusCB->isChecked())
621 setParam(param_str, Tabular::SET_LTFOOT, "none");
623 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
624 if (footerBorderAboveCB->isChecked())
625 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
627 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
628 if (footerBorderBelowCB->isChecked())
629 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
631 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
632 if (lastfooterStatusCB->isChecked())
633 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
635 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
636 if (lastfooterBorderAboveCB->isChecked())
637 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
639 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
640 if (lastfooterBorderBelowCB->isChecked())
641 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
643 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
644 if (lastfooterNoContentsCB->isChecked())
645 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
647 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
649 if (leftRB->isChecked())
650 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
651 else if (centerRB->isChecked())
652 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
653 else if (rightRB->isChecked())
654 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
656 return from_utf8(param_str);
660 static Length getColumnPWidth(Tabular const & t, size_t cell)
662 return t.column_info[t.cellColumn(cell)].p_width;
666 static Length getMColumnPWidth(Tabular const & t, size_t cell)
668 if (t.isMultiColumn(cell) || t.isMultiRow(cell))
669 return t.cellInfo(cell).p_width;
674 static Length getMROffset(Tabular const & t, size_t cell)
676 if (t.isMultiRow(cell))
677 return t.cellInfo(cell).mroffset;
682 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
684 if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
685 return t.cellInfo(cell).align_special;
686 return t.column_info[t.cellColumn(cell)].align_special;
690 void GuiTabular::paramsToDialog(Inset const * inset)
692 InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
693 // Copy Tabular of current inset.
694 Tabular const & tabular = itab->tabular;
696 BufferView const * bv = guiApp->currentView()->currentBufferView();
697 size_t const cell = bv->cursor().idx();
699 Tabular::row_type const row = tabular.cellRow(cell);
700 Tabular::col_type const col = tabular.cellColumn(cell);
702 tabularRowED->setText(QString::number(row + 1));
703 tabularColumnED->setText(QString::number(col + 1));
705 bool const multicol = tabular.isMultiColumn(cell);
706 multicolumnCB->setChecked(multicol);
708 bool const multirow = tabular.isMultiRow(cell);
709 multirowCB->setChecked(multirow);
711 rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
712 if (rotateCellCB->isChecked()) {
713 if (tabular.getRotateCell(cell) != 0)
714 rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
716 rotateCellAngleSB->setValue(90);
719 rotateTabularCB->setChecked(tabular.rotate != 0);
720 if (rotateTabularCB->isChecked())
721 rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
723 longTabularCB->setChecked(tabular.is_long_tabular);
725 borders->setTop(tabular.topLine(cell));
726 borders->setBottom(tabular.bottomLine(cell));
727 borders->setLeft(tabular.leftLine(cell));
728 borders->setRight(tabular.rightLine(cell));
729 // repaint the setborder widget
732 Length::UNIT const default_unit = Length::defaultUnit();
734 ///////////////////////////////////
735 // Set width and alignment
737 Length const tabwidth = tabular.tabularWidth();
739 tabularWidthED->clear();
741 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
742 tabwidth.asString(), default_unit);
747 special = getAlignSpecial(tabular, cell,
748 Tabular::SET_SPECIAL_MULTICOLUMN);
749 pwidth = getMColumnPWidth(tabular, cell);
751 special = getAlignSpecial(tabular, cell,
752 Tabular::SET_SPECIAL_COLUMN);
753 pwidth = getColumnPWidth(tabular, cell);
757 columnWidthED->clear();
759 colwidth = pwidth.asString();
760 lengthToWidgets(columnWidthED, columnWidthUnitLC,
761 colwidth, default_unit);
765 mroffset = getMROffset(tabular, cell);
768 multirowOffsetED->clear();
770 offset = mroffset.asString();
771 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
772 offset, default_unit);
774 specialAlignmentED->setText(toqstr(special));
775 ///////////////////////////////////
778 borderDefaultRB->setChecked(!tabular.use_booktabs);
779 booktabsRB->setChecked(tabular.use_booktabs);
781 if (tabular.row_info[row].top_space.empty()
782 && !tabular.row_info[row].top_space_default) {
783 topspaceCO->setCurrentIndex(0);
784 } else if (tabular.row_info[row].top_space_default) {
785 topspaceCO->setCurrentIndex(1);
787 topspaceCO->setCurrentIndex(2);
788 lengthToWidgets(topspaceED,
790 tabular.row_info[row].top_space.asString(),
794 if (tabular.row_info[row].bottom_space.empty()
795 && !tabular.row_info[row].bottom_space_default) {
796 bottomspaceCO->setCurrentIndex(0);
797 } else if (tabular.row_info[row].bottom_space_default) {
798 bottomspaceCO->setCurrentIndex(1);
800 bottomspaceCO->setCurrentIndex(2);
801 lengthToWidgets(bottomspaceED,
803 tabular.row_info[row].bottom_space.asString(),
807 if (tabular.row_info[row].interline_space.empty()
808 && !tabular.row_info[row].interline_space_default) {
809 interlinespaceCO->setCurrentIndex(0);
810 } else if (tabular.row_info[row].interline_space_default) {
811 interlinespaceCO->setCurrentIndex(1);
813 interlinespaceCO->setCurrentIndex(2);
814 lengthToWidgets(interlinespaceED,
815 interlinespaceUnitLC,
816 tabular.row_info[row].interline_space.asString(),
821 hAlignCO->addItem(qt_("Left"), toqstr("left"));
822 hAlignCO->addItem(qt_("Center"), toqstr("center"));
823 hAlignCO->addItem(qt_("Right"), toqstr("right"));
824 if (!multicol && !pwidth.zero())
825 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
827 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
830 switch (tabular.getAlignment(cell)) {
834 case LYX_ALIGN_CENTER:
837 case LYX_ALIGN_RIGHT:
840 case LYX_ALIGN_BLOCK:
842 if (!multicol && !pwidth.zero())
846 case LYX_ALIGN_DECIMAL:
853 // we should never end up here
856 hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
859 QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
860 if (decimal_point.isEmpty())
861 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
862 decimalPointED->setText(decimal_point);
865 switch (tabular.getVAlignment(cell)) {
866 case Tabular::LYX_VALIGN_TOP:
869 case Tabular::LYX_VALIGN_MIDDLE:
872 case Tabular::LYX_VALIGN_BOTTOM:
881 vAlignCO->setCurrentIndex(valign);
884 switch (tabular.tabular_valignment) {
885 case Tabular::LYX_VALIGN_TOP:
888 case Tabular::LYX_VALIGN_MIDDLE:
891 case Tabular::LYX_VALIGN_BOTTOM:
898 TableAlignCO->setCurrentIndex(tableValign);
900 if (!tabular.is_long_tabular) {
901 headerStatusCB->setChecked(false);
902 headerBorderAboveCB->setChecked(false);
903 headerBorderBelowCB->setChecked(false);
904 firstheaderStatusCB->setChecked(false);
905 firstheaderBorderAboveCB->setChecked(false);
906 firstheaderBorderBelowCB->setChecked(false);
907 firstheaderNoContentsCB->setChecked(false);
908 footerStatusCB->setChecked(false);
909 footerBorderAboveCB->setChecked(false);
910 footerBorderBelowCB->setChecked(false);
911 lastfooterStatusCB->setChecked(false);
912 lastfooterBorderAboveCB->setChecked(false);
913 lastfooterBorderBelowCB->setChecked(false);
914 lastfooterNoContentsCB->setChecked(false);
915 newpageCB->setChecked(false);
916 captionStatusCB->blockSignals(true);
917 captionStatusCB->setChecked(false);
918 captionStatusCB->blockSignals(false);
922 // longtables cannot have a vertical alignment
923 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
925 switch (tabular.longtabular_alignment) {
926 case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
927 leftRB->setChecked(true);
929 case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
930 centerRB->setChecked(true);
932 case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
933 rightRB->setChecked(true);
936 centerRB->setChecked(true);
939 captionStatusCB->blockSignals(true);
940 captionStatusCB->setChecked(tabular.ltCaption(row));
941 captionStatusCB->blockSignals(false);
945 bool row_set = tabular.getRowOfLTHead(row, ltt);
946 headerStatusCB->setChecked(row_set);
948 headerBorderAboveCB->setChecked(ltt.topDL);
949 headerBorderBelowCB->setChecked(ltt.bottomDL);
952 headerBorderAboveCB->setChecked(false);
953 headerBorderBelowCB->setChecked(false);
954 firstheaderNoContentsCB->setChecked(false);
958 row_set = tabular.getRowOfLTFirstHead(row, ltt);
959 firstheaderStatusCB->setChecked(row_set);
960 if (ltt.set && (!ltt.empty || !use_empty)) {
961 firstheaderBorderAboveCB->setChecked(ltt.topDL);
962 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
964 firstheaderBorderAboveCB->setChecked(false);
965 firstheaderBorderBelowCB->setChecked(false);
968 row_set = tabular.getRowOfLTFoot(row, ltt);
969 footerStatusCB->setChecked(row_set);
971 footerBorderAboveCB->setChecked(ltt.topDL);
972 footerBorderBelowCB->setChecked(ltt.bottomDL);
975 footerBorderAboveCB->setChecked(false);
976 footerBorderBelowCB->setChecked(false);
977 lastfooterNoContentsCB->setChecked(false);
981 row_set = tabular.getRowOfLTLastFoot(row, ltt);
982 lastfooterStatusCB->setChecked(row_set);
983 if (ltt.set && (!ltt.empty || !use_empty)) {
984 lastfooterBorderAboveCB->setChecked(ltt.topDL);
985 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
987 lastfooterBorderAboveCB->setChecked(false);
988 lastfooterBorderBelowCB->setChecked(false);
990 newpageCB->setChecked(tabular.getLTNewPage(row));
992 // first header can only be suppressed when there is a header
993 firstheader_suppressable_ = tabular.haveLTHead()
994 && !tabular.haveLTFirstHead();
995 // last footer can only be suppressed when there is a footer
996 lastfooter_suppressable_ = tabular.haveLTFoot()
997 && !tabular.haveLTLastFoot();
999 // after setting the features, check if they are enabled
1004 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1006 string cmd = "tabular " + featureAsString(f);
1007 return getStatus(FuncRequest(LFUN_INSET_MODIFY, cmd)).enabled();
1011 } // namespace frontend
1014 #include "moc_GuiTabular.cpp"