]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiTabular.cpp
If we are in a closeEvent, we don't want to close all buffers, because these may...
[lyx.git] / src / frontends / qt4 / GuiTabular.cpp
index 8ec0cd31f5d6b304cb5e153f50030d07094054cd..25d5427685209530e292016148dc175876ff25df 100644 (file)
@@ -4,8 +4,9 @@
  * Licence details can be found in the file COPYING.
  *
  * \author John Levon
- * \author Jürgen Spitzmüller
- * \author Herbert Voß
+ * \author Jürgen Spitzmüller
+ * \author Herbert Voß
+ * \author Uwe Stöhr
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -23,7 +24,8 @@
 #include "BufferView.h"
 #include "Cursor.h"
 #include "FuncRequest.h"
-#include "LyXRC.h"
+#include "FuncStatus.h"
+#include "LyXFunc.h"
 
 #include "insets/InsetTabular.h"
 
@@ -51,60 +53,112 @@ GuiTabular::GuiTabular(GuiView & lv)
        bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
        interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
 
+       widthUnitCB->setCurrentItem(Length::defaultUnit());
+
        connect(topspaceED, SIGNAL(returnPressed()),
                this, SLOT(topspace_changed()));
        connect(topspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
                this, SLOT(topspace_changed()));
-       connect(topspaceCO, SIGNAL(activated(int)), this, SLOT(topspace_changed()));
+       connect(topspaceCO, SIGNAL(activated(int)),
+               this, SLOT(topspace_changed()));
        connect(bottomspaceED, SIGNAL(returnPressed()),
                this, SLOT(bottomspace_changed()));
        connect(bottomspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
                this, SLOT(bottomspace_changed()));
-       connect(bottomspaceCO, SIGNAL(activated(int)), this, SLOT(bottomspace_changed()));
+       connect(bottomspaceCO, SIGNAL(activated(int)),
+               this, SLOT(bottomspace_changed()));
        connect(interlinespaceED, SIGNAL(returnPressed()),
                this, SLOT(interlinespace_changed()));
        connect(interlinespaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
                this, SLOT(interlinespace_changed()));
-       connect(interlinespaceCO, SIGNAL(activated(int)), this, SLOT(interlinespace_changed()));
-       connect(booktabsRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
-       connect(borderDefaultRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
-       connect(borderSetPB, SIGNAL(clicked()), this, SLOT(borderSet_clicked()));
-       connect(borderUnsetPB, SIGNAL(clicked()), this, SLOT(borderUnset_clicked()));
-       connect(longTabularCB, SIGNAL(toggled(bool)), longtableGB, SLOT(setEnabled(bool)));
-       connect(longTabularCB, SIGNAL(toggled(bool)), newpageCB, SLOT(setEnabled(bool)));
-       connect(hAlignCB, SIGNAL(activated(int)), this, SLOT(hAlign_changed(int)));
-       connect(vAlignCB, SIGNAL(activated(int)), this, SLOT(vAlign_changed(int)));
-       connect(multicolumnCB, SIGNAL(clicked()), this, SLOT(multicolumn_clicked()));
-       connect(newpageCB, SIGNAL(clicked()), this, SLOT(ltNewpage_clicked()));
-       connect(headerStatusCB, SIGNAL(clicked()), this, SLOT(ltHeaderStatus_clicked()));
-       connect(headerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderAbove_clicked()));
-       connect(headerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderBelow_clicked()));
-       connect(firstheaderStatusCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderStatus_clicked()));
-       connect(firstheaderBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderAbove_clicked()));
-       connect(firstheaderBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderBelow_clicked()));
-       connect(firstheaderNoContentsCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderEmpty_clicked()));
-       connect(footerStatusCB, SIGNAL(clicked()), this, SLOT(ltFooterStatus_clicked()));
-       connect(footerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderAbove_clicked()));
-       connect(footerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderBelow_clicked()));
-       connect(lastfooterStatusCB, SIGNAL(clicked()), this, SLOT(ltLastFooterStatus_clicked()));
-       connect(lastfooterBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderAbove_clicked()));
-       connect(lastfooterBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderBelow_clicked()));
-       connect(lastfooterNoContentsCB, SIGNAL(clicked()), this, SLOT(ltLastFooterEmpty_clicked()));
-       connect(specialAlignmentED, SIGNAL(returnPressed()), this, SLOT(specialAlignment_changed()));
-       connect(widthED, SIGNAL(returnPressed()), this, SLOT(width_changed()));
-       connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)), this, SLOT(width_changed()));
-       connect(closePB, SIGNAL(clicked()), this, SLOT(close_clicked()));
-       connect(borders, SIGNAL(topSet(bool)), this, SLOT(topBorder_changed()));
-       connect(borders, SIGNAL(bottomSet(bool)), this, SLOT(bottomBorder_changed()));
-       connect(borders, SIGNAL(rightSet(bool)), this, SLOT(rightBorder_changed()));
-       connect(borders, SIGNAL(leftSet(bool)), this, SLOT(leftBorder_changed()));
-       connect(rotateTabularCB, SIGNAL(clicked()), this, SLOT(rotateTabular()));
-       connect(rotateCellCB, SIGNAL(clicked()), this, SLOT(rotateCell()));
-       connect(longTabularCB, SIGNAL(clicked()), this, SLOT(longTabular()));
-
-       bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
-       bc().setCancel(closePB);
-
+       connect(interlinespaceCO, SIGNAL(activated(int)),
+               this, SLOT(interlinespace_changed()));
+       connect(booktabsRB, SIGNAL(clicked(bool)),
+               this, SLOT(booktabsChanged(bool)));
+       connect(borderDefaultRB, SIGNAL(clicked(bool)),
+               this, SLOT(booktabsChanged(bool)));
+       connect(borderSetPB, SIGNAL(clicked()),
+               this, SLOT(borderSet_clicked()));
+       connect(borderUnsetPB, SIGNAL(clicked()), 
+               this, SLOT(borderUnset_clicked()));
+       connect(longTabularCB, SIGNAL(toggled(bool)),
+               longtableGB, SLOT(setEnabled(bool)));
+       connect(longTabularCB, SIGNAL(toggled(bool)),
+               newpageCB, SLOT(setEnabled(bool)));
+       connect(longTabularCB, SIGNAL(toggled(bool)),
+               alignmentGB, SLOT(setEnabled(bool)));
+       // longtables cannot have a vertical alignment
+       connect(longTabularCB, SIGNAL(toggled(bool)),
+               TableAlignCB, SLOT(setDisabled(bool)));
+       connect(hAlignCB, SIGNAL(activated(int)),
+               this, SLOT(hAlign_changed(int)));
+       connect(vAlignCB, SIGNAL(activated(int)),
+               this, SLOT(vAlign_changed(int)));
+       connect(multicolumnCB, SIGNAL(clicked()),
+               this, SLOT(multicolumn_clicked()));
+       connect(newpageCB, SIGNAL(clicked()),
+               this, SLOT(ltNewpage_clicked()));
+       connect(headerStatusCB, SIGNAL(clicked()),
+               this, SLOT(ltHeaderStatus_clicked()));
+       connect(headerBorderAboveCB, SIGNAL(clicked()),
+               this, SLOT(ltHeaderBorderAbove_clicked()));
+       connect(headerBorderBelowCB, SIGNAL(clicked()),
+               this, SLOT(ltHeaderBorderBelow_clicked()));
+       connect(firstheaderStatusCB, SIGNAL(clicked()),
+               this, SLOT(ltFirstHeaderStatus_clicked()));
+       connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
+               this, SLOT(ltFirstHeaderBorderAbove_clicked()));
+       connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
+               this, SLOT(ltFirstHeaderBorderBelow_clicked()));
+       connect(firstheaderNoContentsCB, SIGNAL(clicked()),
+               this, SLOT(ltFirstHeaderEmpty_clicked()));
+       connect(footerStatusCB, SIGNAL(clicked()),
+               this, SLOT(ltFooterStatus_clicked()));
+       connect(footerBorderAboveCB, SIGNAL(clicked()),
+               this, SLOT(ltFooterBorderAbove_clicked()));
+       connect(footerBorderBelowCB, SIGNAL(clicked()),
+               this, SLOT(ltFooterBorderBelow_clicked()));
+       connect(lastfooterStatusCB, SIGNAL(clicked()),
+               this, SLOT(ltLastFooterStatus_clicked()));
+       connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
+               this, SLOT(ltLastFooterBorderAbove_clicked()));
+       connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
+               this, SLOT(ltLastFooterBorderBelow_clicked()));
+       connect(lastfooterNoContentsCB, SIGNAL(clicked()),
+               this, SLOT(ltLastFooterEmpty_clicked()));
+       connect(specialAlignmentED, SIGNAL(returnPressed()),
+               this, SLOT(specialAlignment_changed()));
+       connect(widthED, SIGNAL(editingFinished()),
+               this, SLOT(width_changed()));
+       connect(widthUnitCB, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+               this, SLOT(width_changed()));
+       connect(closePB, SIGNAL(clicked()),
+               this, SLOT(close_clicked()));
+       connect(borders, SIGNAL(topSet(bool)),
+               this, SLOT(topBorder_changed()));
+       connect(borders, SIGNAL(bottomSet(bool)),
+               this, SLOT(bottomBorder_changed()));
+       connect(borders, SIGNAL(rightSet(bool)),
+               this, SLOT(rightBorder_changed()));
+       connect(borders, SIGNAL(leftSet(bool)),
+               this, SLOT(leftBorder_changed()));
+       connect(rotateTabularCB, SIGNAL(clicked()),
+               this, SLOT(rotateTabular()));
+       connect(rotateCellCB, SIGNAL(clicked()),
+               this, SLOT(rotateCell()));
+       connect(TableAlignCB, SIGNAL(activated(int)),
+               this, SLOT(tableAlignment_changed(int)));
+       connect(longTabularCB, SIGNAL(clicked()),
+               this, SLOT(longTabular()));
+       connect(leftRB, SIGNAL(clicked()),
+               this, SLOT(ltAlignment_clicked()));
+       connect(centerRB, SIGNAL(clicked()),
+               this, SLOT(ltAlignment_clicked()));
+       connect(rightRB, SIGNAL(clicked()),
+               this, SLOT(ltAlignment_clicked()));
+               
+       bc().setPolicy(ButtonPolicy::IgnorantPolicy);
+       
        bc().addReadOnly(topspaceED);
        bc().addReadOnly(topspaceUnit);
        bc().addReadOnly(topspaceCO);
@@ -122,9 +176,10 @@ GuiTabular::GuiTabular(GuiView & lv)
        bc().addReadOnly(rotateTabularCB);
        bc().addReadOnly(specialAlignmentED);
        bc().addReadOnly(widthED);
-       bc().addReadOnly(widthUnit);
+       bc().addReadOnly(widthUnitCB);
        bc().addReadOnly(hAlignCB);
        bc().addReadOnly(vAlignCB);
+       bc().addReadOnly(TableAlignCB);
        bc().addReadOnly(borderSetPB);
        bc().addReadOnly(borderUnsetPB);
        bc().addReadOnly(borders);
@@ -144,7 +199,10 @@ GuiTabular::GuiTabular(GuiView & lv)
        bc().addReadOnly(lastfooterBorderBelowCB);
        bc().addReadOnly(lastfooterNoContentsCB);
        bc().addReadOnly(newpageCB);
-
+       bc().addReadOnly(leftRB);
+       bc().addReadOnly(centerRB);
+       bc().addReadOnly(rightRB);
+       
        // initialize the length validator
        bc().addCheckedLineEdit(widthED, fixedWidthColLA);
        bc().addCheckedLineEdit(topspaceED, topspaceLA);
@@ -190,7 +248,8 @@ void GuiTabular::topspace_changed()
                case 2: {
                        if (!topspaceED->text().isEmpty())
                                set(Tabular::SET_TOP_SPACE,
-                                       widgetsToLength(topspaceED, topspaceUnit));
+                                       widgetsToLength(topspaceED,
+                                                       topspaceUnit));
                        if (!bc().policy().isReadOnly()) {
                                topspaceED->setEnabled(true);
                                topspaceUnit->setEnabled(true);
@@ -220,7 +279,8 @@ void GuiTabular::bottomspace_changed()
                case 2: {
                        if (!bottomspaceED->text().isEmpty())
                                set(Tabular::SET_BOTTOM_SPACE,
-                                       widgetsToLength(bottomspaceED, bottomspaceUnit));
+                                       widgetsToLength(bottomspaceED,
+                                                       bottomspaceUnit));
                        if (!bc().policy().isReadOnly()) {
                                bottomspaceED->setEnabled(true);
                                bottomspaceUnit->setEnabled(true);
@@ -250,7 +310,8 @@ void GuiTabular::interlinespace_changed()
                case 2: {
                        if (!interlinespaceED->text().isEmpty())
                                set(Tabular::SET_INTERLINE_SPACE,
-                                       widgetsToLength(interlinespaceED, interlinespaceUnit));
+                                       widgetsToLength(interlinespaceED,
+                                                       interlinespaceUnit));
                        if (!bc().policy().isReadOnly()) {
                                interlinespaceED->setEnabled(true);
                                interlinespaceUnit->setEnabled(true);
@@ -324,7 +385,7 @@ void GuiTabular::specialAlignment_changed()
 void GuiTabular::width_changed()
 {
        changed();
-       string const width = widgetsToLength(widthED, widthUnit);
+       string const width = widgetsToLength(widthED, widthUnitCB);
        setWidth(width);
 }
 
@@ -379,6 +440,19 @@ void GuiTabular::vAlign_changed(int align)
 }
 
 
+void GuiTabular::tableAlignment_changed(int align)
+{
+       switch (align) {
+               case 0: set(Tabular::TABULAR_VALIGN_TOP);
+                       break;
+               case 1: set(Tabular::TABULAR_VALIGN_MIDDLE);
+                       break;
+               case 2: set(Tabular::TABULAR_VALIGN_BOTTOM);
+                       break;
+       }
+}
+
+
 void GuiTabular::longTabular()
 {
        longTabular(longTabularCB->isChecked());
@@ -407,9 +481,6 @@ void GuiTabular::ltHeaderStatus_clicked()
                set(Tabular::SET_LTHEAD, "");
        else
                set(Tabular::UNSET_LTHEAD, "");
-       headerBorderAboveCB->setEnabled(enable);
-       headerBorderBelowCB->setEnabled(enable);
-       firstheaderNoContentsCB->setEnabled(enable);
        changed();
 }
 
@@ -461,8 +532,6 @@ void GuiTabular::ltFirstHeaderStatus_clicked()
                set(Tabular::SET_LTFIRSTHEAD, "");
        else
                set(Tabular::UNSET_LTFIRSTHEAD, "");
-       firstheaderBorderAboveCB->setEnabled(enable);
-       firstheaderBorderBelowCB->setEnabled(enable);
        changed();
 }
 
@@ -474,9 +543,6 @@ void GuiTabular::ltFirstHeaderEmpty_clicked()
                set(Tabular::SET_LTFIRSTHEAD, "empty");
        else
                set(Tabular::UNSET_LTFIRSTHEAD, "empty");
-       firstheaderStatusCB->setEnabled(!enable);
-       firstheaderBorderAboveCB->setEnabled(!enable);
-       firstheaderBorderBelowCB->setEnabled(!enable);
        changed();
 }
 
@@ -488,9 +554,6 @@ void GuiTabular::ltFooterStatus_clicked()
                set(Tabular::SET_LTFOOT, "");
        else
                set(Tabular::UNSET_LTFOOT, "");
-       footerBorderAboveCB->setEnabled(enable);
-       footerBorderBelowCB->setEnabled(enable);
-       lastfooterNoContentsCB->setEnabled(enable);
        changed();
 }
 
@@ -522,8 +585,6 @@ void GuiTabular::ltLastFooterStatus_clicked()
                set(Tabular::SET_LTLASTFOOT, "");
        else
                set(Tabular::UNSET_LTLASTFOOT, "");
-       lastfooterBorderAboveCB->setEnabled(enable);
-       lastfooterBorderBelowCB->setEnabled(enable);
        changed();
 }
 
@@ -555,9 +616,18 @@ void GuiTabular::ltLastFooterEmpty_clicked()
                set(Tabular::SET_LTLASTFOOT, "empty");
        else
                set(Tabular::UNSET_LTLASTFOOT, "empty");
-       lastfooterStatusCB->setEnabled(!enable);
-       lastfooterBorderAboveCB->setEnabled(!enable);
-       lastfooterBorderBelowCB->setEnabled(!enable);
+       changed();
+}
+
+
+void GuiTabular::ltAlignment_clicked()
+{
+       if (leftRB->isChecked())
+               set(Tabular::LONGTABULAR_ALIGN_LEFT);
+       else if (centerRB->isChecked())
+               set(Tabular::LONGTABULAR_ALIGN_CENTER);
+       else if (rightRB->isChecked())
+               set(Tabular::LONGTABULAR_ALIGN_RIGHT);
        changed();
 }
 
@@ -628,10 +698,12 @@ void GuiTabular::updateContents()
        docstring special;
 
        if (multicol) {
-               special = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_MULTI);
+               special = getAlignSpecial(tabular_, cell,
+                       Tabular::SET_SPECIAL_MULTI);
                pwidth = getMColumnPWidth(tabular_, cell);
        } else {
-               special = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN);
+               special = getAlignSpecial(tabular_, cell,
+                       Tabular::SET_SPECIAL_COLUMN);
                pwidth = getColumnPWidth(tabular_, cell);
        }
 
@@ -640,8 +712,7 @@ void GuiTabular::updateContents()
        bool const isReadonly = bc().policy().isReadOnly();
        specialAlignmentED->setEnabled(!isReadonly);
 
-       Length::UNIT default_unit =
-               useMetricUnits() ? Length::CM : Length::IN;
+       Length::UNIT const default_unit = Length::defaultUnit();
 
        borderDefaultRB->setChecked(!tabular_.use_booktabs);
        booktabsRB->setChecked(tabular_.use_booktabs);
@@ -701,13 +772,15 @@ void GuiTabular::updateContents()
        interlinespaceCO->setEnabled(!isReadonly);
 
        string colwidth;
-       if (!pwidth.zero())
+       if (!pwidth.zero()) {
                colwidth = pwidth.asString();
-       lengthToWidgets(widthED, widthUnit,
-               colwidth, default_unit);
+
+               lengthToWidgets(widthED, widthUnitCB,
+                       colwidth, default_unit);
+       }
 
        widthED->setEnabled(!isReadonly);
-       widthUnit->setEnabled(!isReadonly);
+       widthUnitCB->setEnabled(!isReadonly);
 
        hAlignCB->clear();
        hAlignCB->addItem(qt_("Left"));
@@ -751,16 +824,33 @@ void GuiTabular::updateContents()
                valign = 2;
                break;
        default:
-               valign = 1;
+               valign = 0;
                break;
        }
        if (pwidth.zero())
-               valign = 1;
+               valign = 0;
        vAlignCB->setCurrentIndex(valign);
 
        hAlignCB->setEnabled(true);
        vAlignCB->setEnabled(!pwidth.zero());
 
+       int tableValign = 1;
+       switch (tabular_.tabular_valignment) {
+       case Tabular::LYX_VALIGN_TOP:
+               tableValign = 0;
+               break;
+       case Tabular::LYX_VALIGN_MIDDLE:
+               tableValign = 1;
+               break;
+       case Tabular::LYX_VALIGN_BOTTOM:
+               tableValign = 2;
+               break;
+       default:
+               tableValign = 0;
+               break;
+       }
+       TableAlignCB->setCurrentIndex(tableValign);
+
        if (!tabular_.is_long_tabular) {
                headerStatusCB->setChecked(false);
                headerBorderAboveCB->setChecked(false);
@@ -782,11 +872,62 @@ void GuiTabular::updateContents()
                captionStatusCB->setChecked(false);
                captionStatusCB->blockSignals(false);
                return;
+       } else
+               // longtables cannot have a vertical alignment
+               TableAlignCB->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
+
+       switch (tabular_.longtabular_alignment) {
+       case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
+               leftRB->setChecked(true);
+               break;
+       case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
+               centerRB->setChecked(true);
+               break;
+       case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
+               rightRB->setChecked(true);
+               break;
+       default:
+               centerRB->setChecked(true);
+               break;
        }
        captionStatusCB->blockSignals(true);
        captionStatusCB->setChecked(tabular_.ltCaption(row));
        captionStatusCB->blockSignals(false);
 
+       // FIXME: shouldn't this be handled by GuiDialog?
+       // FIXME: Some of them should be handled directly in TabularUI.ui
+       firstheaderBorderAboveCB->setEnabled(
+               funcEnabled(Tabular::SET_LTFIRSTHEAD));
+       firstheaderBorderBelowCB->setEnabled(
+               funcEnabled(Tabular::SET_LTFIRSTHEAD));
+       // first header can only be suppressed when there is a header
+       firstheaderNoContentsCB->setEnabled(tabular_.haveLTHead()
+               && !tabular_.haveLTFirstHead());
+
+       //firstheaderStatusCB->setEnabled(
+       //      !firstheaderNoContentsCB->isChecked());
+       headerBorderAboveCB->setEnabled(funcEnabled(Tabular::SET_LTHEAD));
+       headerBorderBelowCB->setEnabled(funcEnabled(Tabular::SET_LTHEAD));
+       headerStatusCB->setEnabled(funcEnabled(Tabular::SET_LTHEAD));
+
+       footerBorderAboveCB->setEnabled(funcEnabled(Tabular::SET_LTFOOT));
+       footerBorderBelowCB->setEnabled(funcEnabled(Tabular::SET_LTFOOT));
+       footerStatusCB->setEnabled(funcEnabled(Tabular::SET_LTFOOT));
+
+       lastfooterBorderAboveCB->setEnabled(
+               funcEnabled(Tabular::SET_LTLASTFOOT));
+       lastfooterBorderBelowCB->setEnabled(
+               funcEnabled(Tabular::SET_LTLASTFOOT));
+       // last footer can only be suppressed when there is a footer
+       lastfooterNoContentsCB->setEnabled(tabular_.haveLTFoot()
+               && !tabular_.haveLTLastFoot());
+
+       captionStatusCB->setEnabled(
+               funcEnabled(Tabular::TOGGLE_LTCAPTION));
+       // When a row is set as longtable caption, it must not be allowed
+       // to unset that this row is a multicolumn.
+       multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN));
+
        Tabular::ltType ltt;
        bool use_empty;
        bool row_set = tabular_.getRowOfLTHead(row, ltt);
@@ -806,6 +947,12 @@ void GuiTabular::updateContents()
        }
 
        row_set = tabular_.getRowOfLTFirstHead(row, ltt);
+       // check if setting a first header is allowed
+       // additionally check firstheaderNoContentsCB because when this is
+       // the case a first header makes no sense
+       firstheaderStatusCB->setEnabled(
+               funcEnabled(Tabular::SET_LTFIRSTHEAD)
+               && !firstheaderNoContentsCB->isChecked());
        firstheaderStatusCB->setChecked(row_set);
        if (ltt.set && (!ltt.empty || !use_empty)) {
                firstheaderBorderAboveCB->setChecked(ltt.topDL);
@@ -816,7 +963,6 @@ void GuiTabular::updateContents()
                firstheaderBorderAboveCB->setChecked(false);
                firstheaderBorderBelowCB->setChecked(false);
                if (use_empty) {
-                       firstheaderNoContentsCB->setChecked(ltt.empty);
                        if (ltt.empty)
                                firstheaderStatusCB->setEnabled(false);
                }
@@ -839,7 +985,13 @@ void GuiTabular::updateContents()
        }
 
        row_set = tabular_.getRowOfLTLastFoot(row, ltt);
-               lastfooterStatusCB->setChecked(row_set);
+       // check if setting a last footer is allowed
+       // additionally check lastfooterNoContentsCB because when this is
+       // the case a last footer makes no sense
+       lastfooterStatusCB->setEnabled(
+               funcEnabled(Tabular::SET_LTLASTFOOT)
+               && !lastfooterNoContentsCB->isChecked());
+       lastfooterStatusCB->setChecked(row_set);
        if (ltt.set && (!ltt.empty || !use_empty)) {
                lastfooterBorderAboveCB->setChecked(ltt.topDL);
                lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
@@ -849,7 +1001,6 @@ void GuiTabular::updateContents()
                lastfooterBorderAboveCB->setChecked(false);
                lastfooterBorderBelowCB->setChecked(false);
                if (use_empty) {
-                       lastfooterNoContentsCB->setChecked(ltt.empty);
                        if (ltt.empty)
                                lastfooterStatusCB->setEnabled(false);
                }
@@ -870,7 +1021,7 @@ void GuiTabular::closeGUI()
        // apply the fixed width values
        size_t const cell = getActiveCell();
        bool const multicol = tabular_.isMultiColumn(cell);
-       string width = widgetsToLength(widthED, widthUnit);
+       string width = widgetsToLength(widthED, widthUnitCB);
        string width2;
 
        Length llen = getColumnPWidth(tabular_, cell);
@@ -886,9 +1037,11 @@ void GuiTabular::closeGUI()
        docstring sa2;
 
        if (multicol)
-               sa2 = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_MULTI);
+               sa2 = getAlignSpecial(tabular_, cell,
+                       Tabular::SET_SPECIAL_MULTI);
        else
-               sa2 = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN);
+               sa2 = getAlignSpecial(tabular_, cell,
+                       Tabular::SET_SPECIAL_COLUMN);
 
        if (sa1 != sa2) {
                if (multicol)
@@ -914,7 +1067,8 @@ void GuiTabular::closeGUI()
                        break;
                case 2:
                        set(Tabular::SET_TOP_SPACE,
-                               widgetsToLength(topspaceED, topspaceUnit));
+                               widgetsToLength(topspaceED,
+                                       topspaceUnit));
                        break;
        }
 
@@ -927,7 +1081,8 @@ void GuiTabular::closeGUI()
                        break;
                case 2:
                        set(Tabular::SET_BOTTOM_SPACE,
-                               widgetsToLength(bottomspaceED, bottomspaceUnit));
+                               widgetsToLength(bottomspaceED,
+                                       bottomspaceUnit));
                        break;
        }
 
@@ -940,7 +1095,8 @@ void GuiTabular::closeGUI()
                        break;
                case 2:
                        set(Tabular::SET_INTERLINE_SPACE,
-                               widgetsToLength(interlinespaceED, interlinespaceUnit));
+                               widgetsToLength(interlinespaceED,
+                                       interlinespaceUnit));
                        break;
        }
 */
@@ -958,7 +1114,8 @@ bool GuiTabular::initialiseParams(string const & data)
                // assume that it is "ours"
                for (int i = cur.depth() - 1; i >= 0; --i)
                        if (cur[i].inset().lyxCode() == TABULAR_CODE) {
-                               current_inset = static_cast<InsetTabular const *>(&cur[i].inset());
+                               current_inset =
+                                       static_cast<InsetTabular const *>(&cur[i].inset());
                                active_cell_ = cur[i].idx();
                                break;
                        }
@@ -978,8 +1135,13 @@ bool GuiTabular::initialiseParams(string const & data)
 
 void GuiTabular::clearParams()
 {
-       InsetTabular tmp(const_cast<Buffer &>(buffer()));
-       tabular_ = tmp.tabular;
+       // This function is also called when LyX is closing and the dialog
+       // is still open. At that time, the buffer might not be available
+       // anymore.
+       if (isBufferAvailable()) {
+               InsetTabular tmp(const_cast<Buffer &>(buffer()));
+               tabular_ = tmp.tabular;
+       }
        active_cell_ = Tabular::npos;
 }
 
@@ -997,12 +1159,6 @@ void GuiTabular::set(Tabular::Feature f, string const & arg)
 }
 
 
-bool GuiTabular::useMetricUnits() const
-{
-       return lyxrc.default_papersize > PAPER_USEXECUTIVE;
-}
-
-
 void GuiTabular::setSpecial(string const & special)
 {
        if (tabular_.isMultiColumn(getActiveCell()))
@@ -1124,6 +1280,14 @@ void GuiTabular::longTabular(bool yes)
 }
 
 
+// to get the status of the longtable row settings
+bool GuiTabular::funcEnabled(Tabular::Feature f) const
+{
+       return getStatus(
+               FuncRequest(getLfun(), featureAsString(f))).enabled();
+}
+
+
 Dialog * createGuiTabular(GuiView & lv) { return new GuiTabular(lv); }