]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTabular.cpp
Amend cab46ff9d1ea3
[lyx.git] / src / frontends / qt4 / GuiTabular.cpp
1 /**
2  * \file GuiTabular.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Jürgen Spitzmüller
8  * \author Herbert Voß
9  * \author Uwe Stöhr
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "GuiTabular.h"
17
18 #include "GuiApplication.h"
19 #include "GuiSetBorder.h"
20 #include "GuiView.h"
21 #include "LengthCombo.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
24
25 #include "BufferView.h"
26 #include "Cursor.h"
27 #include "FuncRequest.h"
28 #include "FuncStatus.h"
29 #include "LyX.h"
30 #include "LyXRC.h"
31
32 #include "insets/InsetTabular.h"
33
34 #include "support/convert.h"
35 #include "support/debug.h"
36 #include "support/lstrings.h"
37
38 #include <QCheckBox>
39 #include <QPushButton>
40 #include <QRadioButton>
41 #include <QLineEdit>
42
43 using namespace std;
44
45 namespace lyx {
46 namespace frontend {
47
48 GuiTabular::GuiTabular(QWidget * parent)
49         : InsetParamsWidget(parent), firstheader_suppressable_(false),
50           lastfooter_suppressable_(false)
51
52 {
53         setupUi(this);
54
55         tabularWidthED->setValidator(unsignedLengthValidator(tabularWidthED));
56         columnWidthED->setValidator(unsignedLengthValidator(columnWidthED));
57         multirowOffsetED->setValidator(new LengthValidator(multirowOffsetED));
58         topspaceED->setValidator(new LengthValidator(topspaceED));
59         bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
60         interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
61
62         tabularWidthUnitLC->setCurrentItem(Length::defaultUnit());
63         columnWidthUnitLC->setCurrentItem(Length::defaultUnit());
64         multirowOffsetUnitLC->setCurrentItem(Length::defaultUnit());
65         topspaceUnitLC->setCurrentItem(Length::defaultUnit());
66         bottomspaceUnitLC->setCurrentItem(Length::defaultUnit());
67         interlinespaceUnitLC->setCurrentItem(Length::defaultUnit());
68
69         connect(topspaceED, SIGNAL(textEdited(const QString &)),
70                 this, SLOT(checkEnabled()));
71         connect(topspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
72                 this, SLOT(checkEnabled()));
73         connect(bottomspaceED, SIGNAL(textEdited(const QString &)),
74                 this, SLOT(checkEnabled()));
75         connect(bottomspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
76                 this, SLOT(checkEnabled()));
77         connect(interlinespaceED, SIGNAL(textEdited(const QString &)),
78                 this, SLOT(checkEnabled()));
79         connect(interlinespaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
80                 this, SLOT(checkEnabled()));
81         connect(booktabsRB, SIGNAL(clicked(bool)),
82                 this, SLOT(checkEnabled()));
83         connect(borderDefaultRB, SIGNAL(clicked(bool)),
84                 this, SLOT(checkEnabled()));
85         connect(borderSetPB, SIGNAL(clicked()),
86                 this, SLOT(borderSet_clicked()));
87         connect(borderUnsetPB, SIGNAL(clicked()),
88                 this, SLOT(borderUnset_clicked()));
89         connect(hAlignCO, SIGNAL(activated(int)),
90                 this, SLOT(checkEnabled()));
91         connect(vAlignCO, SIGNAL(activated(int)),
92                 this, SLOT(checkEnabled()));
93         connect(multicolumnCB, SIGNAL(clicked()),
94                 this, SLOT(checkEnabled()));
95         connect(multirowCB, SIGNAL(clicked()),
96                 this, SLOT(checkEnabled()));
97         connect(multirowOffsetED, SIGNAL(textEdited(const QString &)),
98                 this, SLOT(checkEnabled()));
99         connect(multirowOffsetUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
100                 this, SLOT(checkEnabled()));
101         connect(newpageCB, SIGNAL(clicked()),
102                 this, SLOT(checkEnabled()));
103         connect(headerStatusCB, SIGNAL(clicked()),
104                 this, SLOT(checkEnabled()));
105         connect(headerBorderAboveCB, SIGNAL(clicked()),
106                 this, SLOT(checkEnabled()));
107         connect(headerBorderBelowCB, SIGNAL(clicked()),
108                 this, SLOT(checkEnabled()));
109         connect(firstheaderStatusCB, SIGNAL(clicked()),
110                 this, SLOT(checkEnabled()));
111         connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
112                 this, SLOT(checkEnabled()));
113         connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
114                 this, SLOT(checkEnabled()));
115         connect(firstheaderNoContentsCB, SIGNAL(clicked()),
116                 this, SLOT(checkEnabled()));
117         connect(footerStatusCB, SIGNAL(clicked()),
118                 this, SLOT(checkEnabled()));
119         connect(footerBorderAboveCB, SIGNAL(clicked()),
120                 this, SLOT(checkEnabled()));
121         connect(footerBorderBelowCB, SIGNAL(clicked()),
122                 this, SLOT(checkEnabled()));
123         connect(lastfooterStatusCB, SIGNAL(clicked()),
124                 this, SLOT(checkEnabled()));
125         connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
126                 this, SLOT(checkEnabled()));
127         connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
128                 this, SLOT(checkEnabled()));
129         connect(lastfooterNoContentsCB, SIGNAL(clicked()),
130                 this, SLOT(checkEnabled()));
131         connect(captionStatusCB, SIGNAL(clicked()),
132                 this, SLOT(checkEnabled()));
133         connect(specialAlignmentED, SIGNAL(textEdited(const QString &)),
134                 this, SLOT(checkEnabled()));
135         connect(columnWidthED, SIGNAL(textEdited(const QString &)),
136                 this, SLOT(checkEnabled()));
137         connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
138                 this, SLOT(checkEnabled()));
139         connect(borders, SIGNAL(topSet()),
140                 this, SLOT(checkEnabled()));
141         connect(borders, SIGNAL(bottomSet()),
142                 this, SLOT(checkEnabled()));
143         connect(borders, SIGNAL(rightSet()),
144                 this, SLOT(checkEnabled()));
145         connect(borders, SIGNAL(leftSet()),
146                 this, SLOT(checkEnabled()));
147         connect(rotateTabularCB, SIGNAL(clicked()),
148                 this, SLOT(checkEnabled()));
149         connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
150                 this, SLOT(checkEnabled()));
151         connect(rotateCellCB, SIGNAL(clicked()),
152                 this, SLOT(checkEnabled()));
153         connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
154                 this, SLOT(checkEnabled()));
155         connect(TableAlignCO, SIGNAL(activated(int)),
156                 this, SLOT(checkEnabled()));
157         connect(longTabularCB, SIGNAL(clicked()),
158                 this, SLOT(checkEnabled()));
159         connect(leftRB, SIGNAL(clicked()),
160                 this, SLOT(checkEnabled()));
161         connect(centerRB, SIGNAL(clicked()),
162                 this, SLOT(checkEnabled()));
163         connect(rightRB, SIGNAL(clicked()),
164                 this, SLOT(checkEnabled()));
165         connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
166                 this, SLOT(checkEnabled()));
167
168         decimalPointED->setInputMask("X; ");
169         decimalPointED->setMaxLength(1);
170
171         // initialize the length validator
172         addCheckedWidget(columnWidthED, columnWidthLA);
173         addCheckedWidget(multirowOffsetED, multirowOffsetLA);
174         addCheckedWidget(topspaceED, topspaceLA);
175         addCheckedWidget(bottomspaceED, bottomspaceLA);
176         addCheckedWidget(interlinespaceED, interlinespaceLA);
177         addCheckedWidget(tabularWidthED, tabularWidthLA);
178 }
179
180
181 void GuiTabular::on_topspaceCO_activated(int index)
182 {
183         bool const enable = (index == 2);
184         topspaceED->setEnabled(enable);
185         topspaceUnitLC->setEnabled(enable);
186 }
187
188
189 void GuiTabular::on_bottomspaceCO_activated(int index)
190 {
191         bool const enable = (index == 2);
192         bottomspaceED->setEnabled(enable);
193         bottomspaceUnitLC->setEnabled(enable);
194 }
195
196
197 void GuiTabular::on_interlinespaceCO_activated(int index)
198 {
199         bool const enable = (index == 2);
200         interlinespaceED->setEnabled(enable);
201         interlinespaceUnitLC->setEnabled(enable);
202 }
203
204
205 void GuiTabular::on_columnTypeCO_activated(int index)
206 {
207         checkEnabled();
208         if (index == 2)
209                 columnWidthED->setFocus();
210 }
211
212
213 void GuiTabular::enableWidgets() const
214 {
215         // if there is a LaTeX argument, the width and alignment will be overwritten
216         // therefore disable them in this case
217         bool const fixed = specialAlignmentED->text().isEmpty()
218                         && columnTypeCO->currentIndex() == 2;
219         columnWidthED->setEnabled(fixed);
220         columnWidthUnitLC->setEnabled(fixed);
221         // if the column has a width, multirows are always left-aligned
222         // therefore disable hAlignCB in this case
223         hAlignCO->setEnabled(!(multirowCB->isChecked()
224                 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
225                 && specialAlignmentED->text().isEmpty());
226         // decimal alignment is only possible for non-multicol and non-multirow cells
227         if ((multicolumnCB->isChecked() || multirowCB->isChecked() || columnTypeCO->currentIndex() == 1)
228                 && hAlignCO->findData(toqstr("decimal")))
229                 hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
230         else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
231                 && hAlignCO->findData(toqstr("decimal")) == -1)
232                 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
233         bool const dalign =
234                 hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
235         decimalPointED->setEnabled(dalign);
236         decimalLA->setEnabled(dalign);
237
238         bool const setwidth = TableAlignCO->currentText() == qt_("Middle");
239         tabularWidthLA->setEnabled(setwidth);
240         tabularWidthED->setEnabled(setwidth);
241         tabularWidthUnitLC->setEnabled(setwidth);
242
243         rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked()
244                                          && !longTabularCB->isChecked());
245         rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
246
247         bool const enable_valign =
248                 !multirowCB->isChecked()
249                 && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
250                 && specialAlignmentED->text().isEmpty();
251         vAlignCO->setEnabled(enable_valign);
252         vAlignLA->setEnabled(enable_valign);
253
254         topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
255         topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
256         topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
257         bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
258         bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
259         interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
260         interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
261
262         // setting as longtable is not allowed when table is inside a float
263         bool const is_tabular_star = !tabularWidthED->text().isEmpty();
264         longTabularCB->setEnabled(funcEnabled(Tabular::SET_LONGTABULAR));
265         bool const longtabular = longTabularCB->isChecked();
266         longtableGB->setEnabled(true);
267         newpageCB->setEnabled(longtabular);
268         alignmentGB->setEnabled(longtabular);
269         // longtables and tabular* cannot have a vertical alignment
270         TableAlignLA->setDisabled(is_tabular_star || longtabular);
271         TableAlignCO->setDisabled(is_tabular_star || longtabular);
272         // longtable cannot be rotated with rotating package, only
273         // with [pdf]lscape, which only supports 90 deg.
274         rotateTabularAngleSB->setDisabled(longtabular);
275
276         // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
277         // depending on the cursor position is very very unintuitive...
278         // We need some edit boxes to show which rows are header/footer/etc
279         // without having to move the cursor first.
280         headerStatusCB->setEnabled(longtabular
281                 && (headerStatusCB->isChecked() ?
282                     funcEnabled(Tabular::UNSET_LTHEAD) :
283                     funcEnabled(Tabular::SET_LTHEAD)));
284         headerBorderAboveCB->setEnabled(longtabular
285                 && headerStatusCB->isChecked());
286         headerBorderBelowCB->setEnabled(longtabular
287                 && headerStatusCB->isChecked());
288
289         // first header can only be suppressed when there is a header
290         // firstheader_suppressable_ is set in paramsToDialog
291         firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
292         // check if setting a first header is allowed
293         // additionally check firstheaderNoContentsCB because when this is
294         // the case a first header makes no sense
295         firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
296                    funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
297                    funcEnabled(Tabular::SET_LTFIRSTHEAD))
298                 && longtabular && !firstheaderNoContentsCB->isChecked());
299         firstheaderBorderAboveCB->setEnabled(longtabular
300                 && firstheaderStatusCB->isChecked());
301         firstheaderBorderBelowCB->setEnabled(longtabular
302                 && firstheaderStatusCB->isChecked());
303
304         footerStatusCB->setEnabled(longtabular
305                 && (footerStatusCB->isChecked() ?
306                     funcEnabled(Tabular::UNSET_LTFOOT) :
307                     funcEnabled(Tabular::SET_LTFOOT)));
308         footerBorderAboveCB->setEnabled(longtabular
309                 && footerBorderAboveCB->isChecked());
310         footerBorderBelowCB->setEnabled(longtabular
311                 && footerBorderAboveCB->isChecked());
312
313         // last footer can only be suppressed when there is a footer
314         // lastfooter_suppressable_ is set in paramsToDialog
315         lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
316         // check if setting a last footer is allowed
317         // additionally check lastfooterNoContentsCB because when this is
318         // the case a last footer makes no sense
319         lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
320                    funcEnabled(Tabular::UNSET_LTLASTFOOT) :
321                    funcEnabled(Tabular::SET_LTLASTFOOT))
322                 && longtabular && !lastfooterNoContentsCB->isChecked());
323         lastfooterBorderAboveCB->setEnabled(longtabular
324                 && lastfooterBorderAboveCB->isChecked());
325         lastfooterBorderBelowCB->setEnabled(longtabular
326                 && lastfooterBorderAboveCB->isChecked());
327
328         captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
329                 && longtabular);
330
331         multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
332                 && !dalign && !multirowCB->isChecked());
333         multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
334                 && !dalign && !multicolumnCB->isChecked());
335         bool const enable_mr = multirowCB->isChecked();
336         multirowOffsetLA->setEnabled(enable_mr);
337         multirowOffsetED->setEnabled(enable_mr);
338         multirowOffsetUnitLC->setEnabled(enable_mr);
339
340         // Vertical lines cannot be set in formal tables
341         borders->setLeftEnabled(!booktabsRB->isChecked());
342         borders->setRightEnabled(!booktabsRB->isChecked());
343 }
344
345
346 void GuiTabular::checkEnabled()
347 {
348         enableWidgets();
349         changed();
350 }
351
352
353 void GuiTabular::borderSet_clicked()
354 {
355         borders->setTop(GuiSetBorder::LINE_SET);
356         borders->setBottom(GuiSetBorder::LINE_SET);
357         borders->setLeft(GuiSetBorder::LINE_SET);
358         borders->setRight(GuiSetBorder::LINE_SET);
359         // repaint the setborder widget
360         borders->update();
361         checkEnabled();
362 }
363
364
365 void GuiTabular::borderUnset_clicked()
366 {
367         borders->setTop(GuiSetBorder::LINE_UNSET);
368         borders->setBottom(GuiSetBorder::LINE_UNSET);
369         borders->setLeft(GuiSetBorder::LINE_UNSET);
370         borders->setRight(GuiSetBorder::LINE_UNSET);
371         // repaint the setborder widget
372         borders->update();
373         checkEnabled();
374 }
375
376
377 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
378 {
379         param_str += ' ';
380         param_str += featureAsString(f) + ' ' + arg;
381 }
382
383
384 void GuiTabular::setHAlign(string & param_str) const
385 {
386         Tabular::Feature num = Tabular::ALIGN_LEFT;
387         Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
388         string const align =
389                 fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
390         if (align == "left") {
391                 num = Tabular::ALIGN_LEFT;
392                 multi_num = Tabular::M_ALIGN_LEFT;
393         } else if (align == "center") {
394                 num = Tabular::ALIGN_CENTER;
395                 multi_num = Tabular::M_ALIGN_CENTER;
396         } else if (align == "right") {
397                 num = Tabular::ALIGN_RIGHT;
398                 multi_num = Tabular::M_ALIGN_RIGHT;
399         } else if (align == "justified") {
400                 num = Tabular::ALIGN_BLOCK;
401                 //multi_num: no equivalent
402         } else if (align == "decimal") {
403                 num = Tabular::ALIGN_DECIMAL;
404                 //multi_num: no equivalent
405         }
406
407         if (multicolumnCB->isChecked())
408                 setParam(param_str, multi_num);
409         else
410                 setParam(param_str, num);
411 }
412
413
414 void GuiTabular::setVAlign(string & param_str) const
415 {
416         int const align = vAlignCO->currentIndex();
417         enum VALIGN { TOP, MIDDLE, BOTTOM };
418         VALIGN v = TOP;
419
420         switch (align) {
421                 case 0: v = TOP; break;
422                 case 1: v = MIDDLE; break;
423                 case 2: v = BOTTOM; break;
424         }
425
426         Tabular::Feature num = Tabular::VALIGN_MIDDLE;
427         Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
428
429         switch (v) {
430                 case TOP:
431                         num = Tabular::VALIGN_TOP;
432                         multi_num = Tabular::M_VALIGN_TOP;
433                         break;
434                 case MIDDLE:
435                         num = Tabular::VALIGN_MIDDLE;
436                         multi_num = Tabular::M_VALIGN_MIDDLE;
437                         break;
438                 case BOTTOM:
439                         num = Tabular::VALIGN_BOTTOM;
440                         multi_num = Tabular::M_VALIGN_BOTTOM;
441                         break;
442         }
443         if (multicolumnCB->isChecked() || multirowCB->isChecked())
444                 setParam(param_str, multi_num);
445         else
446                 setParam(param_str, num);
447 }
448
449
450 void GuiTabular::setTableAlignment(string & param_str) const
451 {
452         int const align = TableAlignCO->currentIndex();
453         switch (align) {
454                 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
455                         break;
456                 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
457                         break;
458                 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
459                         break;
460         }
461 }
462
463
464 docstring GuiTabular::dialogToParams() const
465 {
466         string param_str = "tabular";
467
468         // table width
469         string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
470         if (tabwidth.empty())
471                 tabwidth = "0pt";
472         setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
473
474         // apply the fixed width values
475         // this must be done before applying the column alignment
476         // because its value influences the alignment of multirow cells
477         string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
478         if (width.empty() || columnTypeCO->currentIndex() != 2)
479                 width = "0pt";
480         if (multicolumnCB->isChecked())
481                 setParam(param_str, Tabular::SET_MPWIDTH, width);
482         else
483                 setParam(param_str, Tabular::SET_PWIDTH, width);
484
485         bool const varwidth = specialAlignmentED->text().isEmpty()
486                         && columnTypeCO->currentIndex() == 1;
487         if (varwidth)
488                 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "on");
489         else
490                 setParam(param_str, Tabular::TOGGLE_VARWIDTH_COLUMN, "off");
491
492         // apply the column alignment
493         // multirows inherit the alignment from the column; if a column width
494         // is set, multirows are always left-aligned so that in this case
495         // its alignment must not be applied (see bug #8084)
496         if (!(multirowCB->isChecked() && width != "0pt"))
497                 setHAlign(param_str);
498
499         // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
500         string decimal_point = fromqstr(decimalPointED->text());
501         if (decimal_point.empty())
502                 decimal_point = lyxrc.default_decimal_point;
503         setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
504
505         setVAlign(param_str);
506         setTableAlignment(param_str);
507         //
508         if (booktabsRB->isChecked())
509                 setParam(param_str, Tabular::SET_BOOKTABS);
510         else
511                 setParam(param_str, Tabular::UNSET_BOOKTABS);
512
513         //
514         switch (topspaceCO->currentIndex()) {
515                 case 0:
516                         setParam(param_str, Tabular::SET_TOP_SPACE, "none");
517                         break;
518                 case 1:
519                         setParam(param_str, Tabular::SET_TOP_SPACE, "default");
520                         break;
521                 case 2:
522                         if (!topspaceED->text().isEmpty())
523                                 setParam(param_str, Tabular::SET_TOP_SPACE,
524                                          widgetsToLength(topspaceED, topspaceUnitLC));
525                         break;
526         }
527
528         //
529         switch (bottomspaceCO->currentIndex()) {
530                 case 0:
531                         setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
532                         break;
533                 case 1:
534                         setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
535                         break;
536                 case 2:
537                         if (!bottomspaceED->text().isEmpty())
538                                 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
539                                         widgetsToLength(bottomspaceED,
540                                                         bottomspaceUnitLC));
541                         break;
542         }
543
544         //
545         switch (interlinespaceCO->currentIndex()) {
546                 case 0:
547                         setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
548                         break;
549                 case 1:
550                         setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
551                         break;
552                 case 2:
553                         if (!interlinespaceED->text().isEmpty())
554                                 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
555                                         widgetsToLength(interlinespaceED,
556                                                         interlinespaceUnitLC));
557                         break;
558         }
559
560         //
561         if (borders->topLineSet() && borders->bottomLineSet() && borders->leftLineSet()
562                 && borders->rightLineSet())
563                 setParam(param_str, Tabular::SET_ALL_LINES);
564         else if (borders->topLineUnset() && borders->bottomLineUnset() && borders->leftLineUnset()
565                 && borders->rightLineUnset())
566                 setParam(param_str, Tabular::UNSET_ALL_LINES);
567         else {
568                 if (borders->getLeft() != GuiSetBorder::LINE_UNDECIDED)
569                         setParam(param_str, Tabular::SET_LINE_LEFT,
570                                  borders->leftLineSet() ? "true" : "false");
571                 if (borders->getRight() != GuiSetBorder::LINE_UNDECIDED)
572                         setParam(param_str, Tabular::SET_LINE_RIGHT,
573                                  borders->rightLineSet() ? "true" : "false");
574                 if (borders->getTop() != GuiSetBorder::LINE_UNDECIDED)
575                         setParam(param_str, Tabular::SET_LINE_TOP,
576                                  borders->topLineSet() ? "true" : "false");
577                 if (borders->getBottom() != GuiSetBorder::LINE_UNDECIDED)
578                         setParam(param_str, Tabular::SET_LINE_BOTTOM,
579                                  borders->bottomLineSet() ? "true" : "false");
580         }
581
582         // apply the special alignment
583         string special = fromqstr(specialAlignmentED->text());
584         if (support::trim(special).empty())
585                 special = "none";
586         if (multicolumnCB->isChecked())
587                 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
588         else
589                 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
590
591         //
592         if (multicolumnCB->isChecked())
593                 setParam(param_str, Tabular::SET_MULTICOLUMN);
594         else
595                 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
596
597         // apply the multirow offset
598         string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
599         if (mroffset.empty())
600                 mroffset = "0pt";
601         if (multirowCB->isChecked())
602                 setParam(param_str, Tabular::SET_MROFFSET, mroffset);
603         //
604         if (multirowCB->isChecked())
605                 setParam(param_str, Tabular::SET_MULTIROW);
606         else
607                 setParam(param_str, Tabular::UNSET_MULTIROW);
608         // store the table rotation angle
609         string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
610         if (rotateTabularCB->isChecked())
611                 setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
612         else
613                 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
614         // store the cell rotation angle
615         string const cell_angle = convert<string>(rotateCellAngleSB->value());
616         if (rotateCellCB->isChecked())
617                 setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
618         else
619                 setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
620         //
621         if (longTabularCB->isChecked())
622                 setParam(param_str, Tabular::SET_LONGTABULAR);
623         else
624                 setParam(param_str, Tabular::UNSET_LONGTABULAR);
625         //
626         if (newpageCB->isChecked())
627                 setParam(param_str, Tabular::SET_LTNEWPAGE);
628         else
629                 setParam(param_str, Tabular::UNSET_LTNEWPAGE);
630         //
631         if (captionStatusCB->isChecked())
632                 setParam(param_str, Tabular::SET_LTCAPTION);
633         else
634                 setParam(param_str, Tabular::UNSET_LTCAPTION);
635         //
636         if (headerStatusCB->isChecked())
637                 setParam(param_str, Tabular::SET_LTHEAD, "none");
638         else
639                 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
640         //
641         if (headerBorderAboveCB->isChecked())
642                 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
643         else
644                 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
645         //
646         if (headerBorderBelowCB->isChecked())
647                 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
648         else
649                 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
650         if (firstheaderBorderAboveCB->isChecked())
651                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
652         else
653                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
654         if (firstheaderBorderBelowCB->isChecked())
655                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
656         else
657                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
658         if (firstheaderStatusCB->isChecked())
659                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
660         else
661                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
662         if (firstheaderNoContentsCB->isChecked())
663                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
664         else
665                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
666         if (footerStatusCB->isChecked())
667                 setParam(param_str, Tabular::SET_LTFOOT, "none");
668         else
669                 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
670         if (footerBorderAboveCB->isChecked())
671                 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
672         else
673                 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
674         if (footerBorderBelowCB->isChecked())
675                 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
676         else
677                 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
678         if (lastfooterStatusCB->isChecked())
679                 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
680         else
681                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
682         if (lastfooterBorderAboveCB->isChecked())
683                 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
684         else
685                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
686         if (lastfooterBorderBelowCB->isChecked())
687                 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
688         else
689                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
690         if (lastfooterNoContentsCB->isChecked())
691                 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
692         else
693                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
694
695         if (leftRB->isChecked())
696                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
697         else if (centerRB->isChecked())
698                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
699         else if (rightRB->isChecked())
700                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
701
702         return from_utf8(param_str);
703 }
704
705
706 static Length getColumnPWidth(Tabular const & t, size_t cell)
707 {
708         return t.column_info[t.cellColumn(cell)].p_width;
709 }
710
711
712 static Length getMColumnPWidth(Tabular const & t, size_t cell)
713 {
714         if (t.isMultiColumn(cell) || t.isMultiRow(cell))
715                 return t.cellInfo(cell).p_width;
716         return Length();
717 }
718
719
720 static Length getMROffset(Tabular const & t, size_t cell)
721 {
722         if (t.isMultiRow(cell))
723                 return t.cellInfo(cell).mroffset;
724         return Length();
725 }
726
727
728 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
729 {
730         if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
731                 return t.cellInfo(cell).align_special;
732         return t.column_info[t.cellColumn(cell)].align_special;
733 }
734
735
736 GuiSetBorder::BorderState GuiTabular::borderState(GuiSetBorder::BorderState bs,
737                                                   bool const line)
738 {
739         if (bs == GuiSetBorder::LINE_UNDEF)
740                 bs = line ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
741         else if ((bs == GuiSetBorder::LINE_SET && !line)
742                  || (bs == GuiSetBorder::LINE_UNSET && line))
743                 bs = GuiSetBorder::LINE_UNDECIDED;
744         return bs;
745 }
746
747
748 void GuiTabular::paramsToDialog(Inset const * inset)
749 {
750         InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
751         // Copy Tabular of current inset.
752         Tabular const & tabular = itab->tabular;
753
754         BufferView const * bv = guiApp->currentView()->currentBufferView();
755         size_t const cell = bv->cursor().idx();
756
757         Tabular::row_type const row = tabular.cellRow(cell);
758         Tabular::col_type const col = tabular.cellColumn(cell);
759
760         tabularRowED->setText(QString::number(row + 1));
761         tabularColumnED->setText(QString::number(col + 1));
762
763         bool const multicol = tabular.isMultiColumn(cell);
764         multicolumnCB->setChecked(multicol);
765
766         bool const multirow = tabular.isMultiRow(cell);
767         multirowCB->setChecked(multirow);
768
769         rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
770         if (rotateCellCB->isChecked()) {
771                 if (tabular.getRotateCell(cell) != 0)
772                         rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
773                 else
774                         rotateCellAngleSB->setValue(90);
775         }
776
777         longTabularCB->setChecked(tabular.is_long_tabular);
778
779         rotateTabularCB->setChecked(tabular.rotate != 0);
780         if (rotateTabularCB->isChecked()) {
781                 if (longTabularCB->isChecked())
782                         rotateTabularAngleSB->setValue(90);
783                 else
784                         rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
785         }
786
787         // In what follows, we check the borders of all selected cells,
788         // and if there are diverging settings, we use the LINE_UNDECIDED
789         // border status.
790         GuiSetBorder::BorderState lt = GuiSetBorder::LINE_UNDEF;
791         GuiSetBorder::BorderState lb = GuiSetBorder::LINE_UNDEF;
792         GuiSetBorder::BorderState ll = GuiSetBorder::LINE_UNDEF;
793         GuiSetBorder::BorderState lr = GuiSetBorder::LINE_UNDEF;
794         CursorSlice const & beg = bv->cursor().selBegin();
795         CursorSlice const & end = bv->cursor().selEnd();
796         if (beg != end) {
797                 Tabular::col_type cs = tabular.cellColumn(beg.idx());
798                 Tabular::col_type ce = tabular.cellColumn(end.idx());
799                 if (cs > ce)
800                         swap(cs, ce);
801                 Tabular::row_type rs = tabular.cellRow(beg.idx());
802                 Tabular::row_type re = tabular.cellRow(end.idx());
803                 if (rs > re)
804                         swap(rs, re);
805                 for (Tabular::row_type r = rs; r <= re; ++r)
806                         for (Tabular::col_type c = cs; c <= ce; ++c) {
807                                 idx_type const cc = tabular.cellIndex(r, c);
808                                 lt = borderState(lt, tabular.topLine(cc));
809                                 lb = borderState(lb, tabular.bottomLine(cc));
810                                 ll = borderState(ll, tabular.leftLine(cc));
811                                 lr = borderState(lr, tabular.rightLine(cc));
812                         }
813         } else {
814                 lt = tabular.topLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
815                 lb = tabular.bottomLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
816                 ll = tabular.leftLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
817                 lr = tabular.rightLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
818         }
819         borders->setTop(lt);
820         borders->setBottom(lb);
821         borders->setLeft(ll);
822         borders->setRight(lr);
823         // repaint the setborder widget
824         borders->update();
825
826         Length::UNIT const default_unit = Length::defaultUnit();
827
828         ///////////////////////////////////
829         // Set width and alignment
830
831         Length const tabwidth = tabular.tabularWidth();
832         if (tabwidth.zero()
833             && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
834                 tabularWidthED->clear();
835         else
836                 lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
837                         tabwidth.asString(), default_unit);
838
839         Length pwidth;
840         docstring special;
841         if (multicol) {
842                 special = getAlignSpecial(tabular, cell,
843                         Tabular::SET_SPECIAL_MULTICOLUMN);
844                 pwidth = getMColumnPWidth(tabular, cell);
845         } else {
846                 special = getAlignSpecial(tabular, cell,
847                         Tabular::SET_SPECIAL_COLUMN);
848                 pwidth = getColumnPWidth(tabular, cell);
849         }
850         bool const varwidth = tabular.column_info[tabular.cellColumn(cell)].varwidth;
851         if (varwidth)
852                 columnTypeCO->setCurrentIndex(1);
853         string colwidth;
854         if (pwidth.zero()
855             && !(columnWidthED->hasFocus() && columnWidthED->text() == "0")) {
856                 columnWidthED->clear();
857                 if (!varwidth)
858                         columnTypeCO->setCurrentIndex(0);
859         } else {
860                 colwidth = pwidth.asString();
861                 lengthToWidgets(columnWidthED, columnWidthUnitLC,
862                         colwidth, default_unit);
863                 columnTypeCO->setCurrentIndex(2);
864         }
865         Length mroffset;
866         if (multirow)
867                 mroffset = getMROffset(tabular, cell);
868         string offset;
869         if (mroffset.zero()
870             && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
871                 multirowOffsetED->clear();
872         else {
873                 offset = mroffset.asString();
874                 lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
875                         offset, default_unit);
876         }
877         specialAlignmentED->setText(toqstr(special));
878         ///////////////////////////////////
879
880
881         borderDefaultRB->setChecked(!tabular.use_booktabs);
882         booktabsRB->setChecked(tabular.use_booktabs);
883
884         if (tabular.row_info[row].top_space.empty()
885             && !tabular.row_info[row].top_space_default) {
886                 topspaceCO->setCurrentIndex(0);
887         } else if (tabular.row_info[row].top_space_default) {
888                 topspaceCO->setCurrentIndex(1);
889         } else {
890                 topspaceCO->setCurrentIndex(2);
891                 lengthToWidgets(topspaceED,
892                                 topspaceUnitLC,
893                                 tabular.row_info[row].top_space.asString(),
894                                 default_unit);
895         }
896
897         if (tabular.row_info[row].bottom_space.empty()
898             && !tabular.row_info[row].bottom_space_default) {
899                 bottomspaceCO->setCurrentIndex(0);
900         } else if (tabular.row_info[row].bottom_space_default) {
901                 bottomspaceCO->setCurrentIndex(1);
902         } else {
903                 bottomspaceCO->setCurrentIndex(2);
904                 lengthToWidgets(bottomspaceED,
905                                 bottomspaceUnitLC,
906                                 tabular.row_info[row].bottom_space.asString(),
907                                 default_unit);
908         }
909
910         if (tabular.row_info[row].interline_space.empty()
911             && !tabular.row_info[row].interline_space_default) {
912                 interlinespaceCO->setCurrentIndex(0);
913         } else if (tabular.row_info[row].interline_space_default) {
914                 interlinespaceCO->setCurrentIndex(1);
915         } else {
916                 interlinespaceCO->setCurrentIndex(2);
917                 lengthToWidgets(interlinespaceED,
918                                 interlinespaceUnitLC,
919                                 tabular.row_info[row].interline_space.asString(),
920                                 default_unit);
921         }
922
923         hAlignCO->clear();
924         hAlignCO->addItem(qt_("Left"), toqstr("left"));
925         hAlignCO->addItem(qt_("Center"), toqstr("center"));
926         hAlignCO->addItem(qt_("Right"), toqstr("right"));
927         if (!multicol && !pwidth.zero())
928                 hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
929         if (!multicol && !multirow)
930                 hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
931
932         string align;
933         switch (tabular.getAlignment(cell)) {
934                 case LYX_ALIGN_LEFT:
935                         align = "left";
936                         break;
937                 case LYX_ALIGN_CENTER:
938                         align = "center";
939                         break;
940                 case LYX_ALIGN_RIGHT:
941                         align = "right";
942                         break;
943                 case LYX_ALIGN_BLOCK:
944                 {
945                         if (!multicol && !pwidth.zero())
946                                 align = "justified";
947                         break;
948                 }
949                 case LYX_ALIGN_DECIMAL:
950                 {
951                         if (!multicol && !multirow)
952                                 align = "decimal";
953                         break;
954                 }
955                 default:
956                         // we should never end up here
957                         break;
958         }
959         hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
960
961         //
962         QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
963         if (decimal_point.isEmpty())
964                 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
965         decimalPointED->setText(decimal_point);
966
967         int valign = 0;
968         switch (tabular.getVAlignment(cell)) {
969         case Tabular::LYX_VALIGN_TOP:
970                 valign = 0;
971                 break;
972         case Tabular::LYX_VALIGN_MIDDLE:
973                 valign = 1;
974                 break;
975         case Tabular::LYX_VALIGN_BOTTOM:
976                 valign = 2;
977                 break;
978         default:
979                 valign = 0;
980                 break;
981         }
982         if (pwidth.zero())
983                 valign = 0;
984         vAlignCO->setCurrentIndex(valign);
985
986         int tableValign = 1;
987         switch (tabular.tabular_valignment) {
988         case Tabular::LYX_VALIGN_TOP:
989                 tableValign = 0;
990                 break;
991         case Tabular::LYX_VALIGN_MIDDLE:
992                 tableValign = 1;
993                 break;
994         case Tabular::LYX_VALIGN_BOTTOM:
995                 tableValign = 2;
996                 break;
997         default:
998                 tableValign = 0;
999                 break;
1000         }
1001         TableAlignCO->setCurrentIndex(tableValign);
1002
1003         if (!tabular.is_long_tabular) {
1004                 headerStatusCB->setChecked(false);
1005                 headerBorderAboveCB->setChecked(false);
1006                 headerBorderBelowCB->setChecked(false);
1007                 firstheaderStatusCB->setChecked(false);
1008                 firstheaderBorderAboveCB->setChecked(false);
1009                 firstheaderBorderBelowCB->setChecked(false);
1010                 firstheaderNoContentsCB->setChecked(false);
1011                 footerStatusCB->setChecked(false);
1012                 footerBorderAboveCB->setChecked(false);
1013                 footerBorderBelowCB->setChecked(false);
1014                 lastfooterStatusCB->setChecked(false);
1015                 lastfooterBorderAboveCB->setChecked(false);
1016                 lastfooterBorderBelowCB->setChecked(false);
1017                 lastfooterNoContentsCB->setChecked(false);
1018                 newpageCB->setChecked(false);
1019                 captionStatusCB->blockSignals(true);
1020                 captionStatusCB->setChecked(false);
1021                 captionStatusCB->blockSignals(false);
1022                 checkEnabled();
1023                 return;
1024         } else {
1025                 // longtables cannot have a vertical alignment
1026                 TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
1027         }
1028         switch (tabular.longtabular_alignment) {
1029         case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
1030                 leftRB->setChecked(true);
1031                 break;
1032         case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
1033                 centerRB->setChecked(true);
1034                 break;
1035         case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
1036                 rightRB->setChecked(true);
1037                 break;
1038         default:
1039                 centerRB->setChecked(true);
1040                 break;
1041         }
1042         captionStatusCB->blockSignals(true);
1043         captionStatusCB->setChecked(tabular.ltCaption(row));
1044         captionStatusCB->blockSignals(false);
1045
1046         Tabular::ltType ltt;
1047         bool use_empty;
1048         bool row_set = tabular.getRowOfLTHead(row, ltt);
1049         headerStatusCB->setChecked(row_set);
1050         if (ltt.set) {
1051                 headerBorderAboveCB->setChecked(ltt.topDL);
1052                 headerBorderBelowCB->setChecked(ltt.bottomDL);
1053                 use_empty = true;
1054         } else {
1055                 headerBorderAboveCB->setChecked(false);
1056                 headerBorderBelowCB->setChecked(false);
1057                 firstheaderNoContentsCB->setChecked(false);
1058                 use_empty = false;
1059         }
1060
1061         row_set = tabular.getRowOfLTFirstHead(row, ltt);
1062         firstheaderStatusCB->setChecked(row_set);
1063         if (ltt.set && (!ltt.empty || !use_empty)) {
1064                 firstheaderBorderAboveCB->setChecked(ltt.topDL);
1065                 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
1066         } else {
1067                 firstheaderBorderAboveCB->setChecked(false);
1068                 firstheaderBorderBelowCB->setChecked(false);
1069         }
1070
1071         row_set = tabular.getRowOfLTFoot(row, ltt);
1072         footerStatusCB->setChecked(row_set);
1073         if (ltt.set) {
1074                 footerBorderAboveCB->setChecked(ltt.topDL);
1075                 footerBorderBelowCB->setChecked(ltt.bottomDL);
1076                 use_empty = true;
1077         } else {
1078                 footerBorderAboveCB->setChecked(false);
1079                 footerBorderBelowCB->setChecked(false);
1080                 lastfooterNoContentsCB->setChecked(false);
1081                 use_empty = false;
1082         }
1083
1084         row_set = tabular.getRowOfLTLastFoot(row, ltt);
1085         lastfooterStatusCB->setChecked(row_set);
1086         if (ltt.set && (!ltt.empty || !use_empty)) {
1087                 lastfooterBorderAboveCB->setChecked(ltt.topDL);
1088                 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
1089         } else {
1090                 lastfooterBorderAboveCB->setChecked(false);
1091                 lastfooterBorderBelowCB->setChecked(false);
1092         }
1093         newpageCB->setChecked(tabular.getLTNewPage(row));
1094
1095         // first header can only be suppressed when there is a header
1096         firstheader_suppressable_ = tabular.haveLTHead()
1097                         && !tabular.haveLTFirstHead();
1098         // last footer can only be suppressed when there is a footer
1099         lastfooter_suppressable_ = tabular.haveLTFoot()
1100                         && !tabular.haveLTLastFoot();
1101
1102         // after setting the features, check if they are enabled
1103         checkEnabled();
1104 }
1105
1106
1107 bool GuiTabular::checkWidgets(bool readonly) const
1108 {
1109         tabularRowED->setReadOnly(readonly);
1110         tabularColumnED->setReadOnly(readonly);
1111         tabularWidthED->setReadOnly(readonly);
1112         specialAlignmentED->setReadOnly(readonly);
1113         columnWidthED->setReadOnly(readonly);
1114         multirowOffsetED->setReadOnly(readonly);
1115         decimalPointED->setReadOnly(readonly);
1116
1117         if (readonly) {
1118                 multicolumnCB->setEnabled(false);
1119                 multirowCB->setEnabled(false);
1120                 rotateCellCB->setEnabled(false);
1121                 rotateCellAngleSB->setEnabled(false);
1122                 rotateTabularCB->setEnabled(false);
1123                 rotateTabularAngleSB->setEnabled(false);
1124                 longTabularCB->setEnabled(false);
1125                 borders->setEnabled(false);
1126                 tabularWidthUnitLC->setEnabled(false);
1127                 columnWidthUnitLC->setEnabled(false);
1128                 columnTypeCO->setEnabled(false);
1129                 multirowOffsetUnitLC->setEnabled(false);
1130                 setBordersGB->setEnabled(false);
1131                 allBordersGB->setEnabled(false);
1132                 borderStyleGB->setEnabled(false);
1133                 booktabsRB->setEnabled(false);
1134                 topspaceCO->setEnabled(false);
1135                 topspaceUnitLC->setEnabled(false);
1136                 bottomspaceCO->setEnabled(false);
1137                 bottomspaceUnitLC->setEnabled(false);
1138                 interlinespaceCO->setEnabled(false);
1139                 interlinespaceUnitLC->setEnabled(false);
1140                 hAlignCO->setEnabled(false);
1141                 vAlignCO->setEnabled(false);
1142                 TableAlignCO->setEnabled(false);
1143                 longtableGB->setEnabled(false);
1144                 alignmentGB->setEnabled(false);
1145         } else
1146                 enableWidgets();
1147
1148         return InsetParamsWidget::checkWidgets();
1149 }
1150
1151
1152 bool GuiTabular::funcEnabled(Tabular::Feature f) const
1153 {
1154         FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
1155         return getStatus(r).enabled();
1156 }
1157
1158
1159 } // namespace frontend
1160 } // namespace lyx
1161
1162 #include "moc_GuiTabular.cpp"