]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
Circumvent odd stmary font metrics (part of #9990).
[lyx.git] / src / insets / InsetTabular.cpp
index ac8e723d87cfc3f4a3acf5b970713ba703be1c1c..6d8f7d0737138f45d5a1b6183e0290c2f96b66d9 100644 (file)
@@ -110,6 +110,8 @@ TabularFeature tabularFeature[] =
 {
        // the SET/UNSET actions are used by the table dialog,
        // the TOGGLE actions by the table toolbar buttons
+       // FIXME: these values have been hardcoded in InsetMathGrid and other
+       // math insets.
        { Tabular::APPEND_ROW, "append-row", false },
        { Tabular::APPEND_COLUMN, "append-column", false },
        { Tabular::DELETE_ROW, "delete-row", false },
@@ -151,6 +153,7 @@ TabularFeature tabularFeature[] =
        { Tabular::SET_MROFFSET, "set-mroffset", true },
        { Tabular::SET_ALL_LINES, "set-all-lines", false },
        { Tabular::UNSET_ALL_LINES, "unset-all-lines", false },
+       { Tabular::TOGGLE_LONGTABULAR, "toggle-longtabular", false },
        { Tabular::SET_LONGTABULAR, "set-longtabular", false },
        { Tabular::UNSET_LONGTABULAR, "unset-longtabular", false },
        { Tabular::SET_PWIDTH, "set-pwidth", true },
@@ -177,6 +180,7 @@ TabularFeature tabularFeature[] =
        { Tabular::UNSET_LTCAPTION, "unset-ltcaption", false },
        { Tabular::SET_SPECIAL_COLUMN, "set-special-column", true },
        { Tabular::SET_SPECIAL_MULTICOLUMN, "set-special-multicolumn", true },
+       { Tabular::TOGGLE_BOOKTABS, "toggle-booktabs", false },
        { Tabular::SET_BOOKTABS, "set-booktabs", false },
        { Tabular::UNSET_BOOKTABS, "unset-booktabs", false },
        { Tabular::SET_TOP_SPACE, "set-top-space", true },
@@ -652,7 +656,7 @@ Tabular::ColumnData::ColumnData()
 
 
 Tabular::ltType::ltType()
-       : topDL(false),
+       : set(false), topDL(false),
          bottomDL(false),
          empty(false)
 {}
@@ -1123,7 +1127,6 @@ namespace {
  */
 void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
 {
-       inset->setAutoBreakRows(fixedWidth);
        inset->toggleFixedWidth(fixedWidth);
        if (fixedWidth)
                return;
@@ -1688,7 +1691,8 @@ Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
                cs.alignment = column_info[col].alignment;
        setRightLine(cell, right_border);
 
-       for (idx_type i = 1; i < number; ++i) {
+       idx_type lastcell = cellIndex(row, col + number - 1);
+       for (idx_type i = 1; i < lastcell - cell + 1; ++i) {
                CellData & cs1 = cellInfo(cell + i);
                cs1.multicolumn = CELL_PART_OF_MULTICOLUMN;
                cs.inset->appendParagraphs(cs1.inset->paragraphs());
@@ -2572,6 +2576,9 @@ void Tabular::TeXRow(otexstream & os, row_type row,
                shared_ptr<InsetTableCell> inset = cellInset(cell);
 
                Paragraph const & par = inset->paragraphs().front();
+
+               os.texrow().forceStart(par.id(), 0);
+
                bool rtl = par.isRTL(buffer().params())
                        && !par.empty()
                        && getPWidth(cell).zero()
@@ -2673,14 +2680,16 @@ void Tabular::TeXRow(otexstream & os, row_type row,
 void Tabular::latex(otexstream & os, OutputParams const & runparams) const
 {
        bool const is_tabular_star = !tabular_width.zero();
+       TexRow::RowEntry pos = TexRow::textEntry(runparams.lastid,
+                                                                                        runparams.lastpos);
 
        //+---------------------------------------------------------------------
        //+                      first the opening preamble                    +
        //+---------------------------------------------------------------------
 
        os << safebreakln;
-       if (runparams.lastid != -1)
-               os.texrow().start(runparams.lastid, runparams.lastpos);
+       if (!TexRow::isNone(pos))
+               os.texrow().start(pos);
 
        if (rotate != 0)
                os << "\\begin{turn}{" << convert<string>(rotate) << "}\n";
@@ -2809,6 +2818,9 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const
 
        if (rotate != 0)
                os << breakln << "\\end{turn}";
+
+       if (!TexRow::isNone(pos))
+               os.texrow().start(pos);
 }
 
 
@@ -3390,6 +3402,12 @@ bool InsetTableCell::allowParagraphCustomization(idx_type) const
 }
 
 
+bool InsetTableCell::forceLocalFontSwitch() const
+{
+       return isFixedWidth;
+}
+
+
 bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
        FuncStatus & status) const
 {
@@ -3433,9 +3451,10 @@ docstring InsetTableCell::asString(bool intoInsets)
 }
 
 
-void InsetTableCell::addToToc(DocIterator const & di, bool output_active) const
+void InsetTableCell::addToToc(DocIterator const & di, bool output_active,
+                                                         UpdateType utype) const
 {
-       InsetText::iterateForToc(di, output_active);
+       InsetText::iterateForToc(di, output_active, utype);
 }
 
 
@@ -3456,14 +3475,14 @@ docstring InsetTableCell::xhtml(XHTMLStream & xs, OutputParams const & rp) const
 
 InsetTabular::InsetTabular(Buffer * buf, row_type rows,
                           col_type columns)
-       : Inset(buf), tabular(buf, max(rows, row_type(1)), max(columns, col_type(1))), scx_(0),
-       rowselect_(false), colselect_(false)
+       : Inset(buf), tabular(buf, max(rows, row_type(1)), max(columns, col_type(1))),
+         first_visible_cell_(0), offset_valign_(0), rowselect_(false), colselect_(false)
 {
 }
 
 
 InsetTabular::InsetTabular(InsetTabular const & tab)
-       : Inset(tab), tabular(tab.tabular),  scx_(0)
+       : Inset(tab), tabular(tab.tabular)
 {
 }
 
@@ -3590,7 +3609,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                        MetricsInfo m = mi;
                        Length const p_width = tabular.getPWidth(cell);
                        if (!p_width.zero())
-                               m.base.textwidth = p_width.inPixels(mi.base.textwidth);
+                               m.base.textwidth = p_width.inPixels(mi.base);
                        tabular.cellInset(cell)->metrics(m, dim);
                        if (!p_width.zero())
                                dim.wid = m.base.textwidth;
@@ -3651,11 +3670,11 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                }
                int const top_space = tabular.row_info[r].top_space_default ?
                        default_line_space :
-                       tabular.row_info[r].top_space.inPixels(mi.base.textwidth);
+                       tabular.row_info[r].top_space.inPixels(mi.base);
                tabular.setRowAscent(r, maxasc + ADD_TO_HEIGHT + top_space);
                int const bottom_space = tabular.row_info[r].bottom_space_default ?
                        default_line_space :
-                       tabular.row_info[r].bottom_space.inPixels(mi.base.textwidth);
+                       tabular.row_info[r].bottom_space.inPixels(mi.base);
                tabular.setRowDescent(r, maxdes + ADD_TO_HEIGHT + bottom_space);
        }
 
@@ -3714,11 +3733,10 @@ bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col)
 
 void InsetTabular::draw(PainterInfo & pi, int x, int y) const
 {
-       x += scx_ + ADD_TO_TABULAR_WIDTH;
+       x += ADD_TO_TABULAR_WIDTH;
 
        BufferView * bv = pi.base.bv;
        Cursor & cur = pi.base.bv->cursor();
-       resetPos(cur);
 
        // FIXME: As the full background is painted in drawBackground(),
        // we have no choice but to do a full repaint for the Text cells.
@@ -3727,7 +3745,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
        bool const original_selection_state = pi.selected;
 
        idx_type idx = 0;
-       first_visible_cell = Tabular::npos;
+       first_visible_cell_ = Tabular::npos;
 
        int yy = y + offset_valign_;
        for (row_type r = 0; r < tabular.nrows(); ++r) {
@@ -3743,8 +3761,8 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
                                continue;
                        }
 
-                       if (first_visible_cell == Tabular::npos)
-                               first_visible_cell = idx;
+                       if (first_visible_cell_ == Tabular::npos)
+                               first_visible_cell_ = idx;
 
                        pi.selected |= isCellSelected(cur, r, c);
                        int const cx = nx + tabular.textHOffset(idx);
@@ -3766,7 +3784,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
 
 void InsetTabular::drawBackground(PainterInfo & pi, int x, int y) const
 {
-       x += scx_ + ADD_TO_TABULAR_WIDTH;
+       x += ADD_TO_TABULAR_WIDTH;
        y += offset_valign_ - tabular.rowAscent(0);
        pi.pain.fillRectangle(x, y, tabular.width(), tabular.height(),
                pi.backgroundColor(this));
@@ -3776,9 +3794,8 @@ void InsetTabular::drawBackground(PainterInfo & pi, int x, int y) const
 void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
 {
        Cursor & cur = pi.base.bv->cursor();
-       resetPos(cur);
 
-       x += scx_ + ADD_TO_TABULAR_WIDTH;
+       x += ADD_TO_TABULAR_WIDTH;
 
        if (!cur.selection())
                return;
@@ -3875,7 +3892,6 @@ void InsetTabular::edit(Cursor & cur, bool front, EntryDirection)
 {
        //lyxerr << "InsetTabular::edit: " << this << endl;
        cur.finishUndo();
-       cur.setSelection(false);
        cur.push(*this);
        if (front) {
                if (isRightToLeft(cur))
@@ -3894,7 +3910,6 @@ void InsetTabular::edit(Cursor & cur, bool front, EntryDirection)
        }
        cur.setCurrentFont();
        // FIXME: this accesses the position cache before it is initialized
-       //resetPos(cur);
        //cur.bv().fitCursor();
 }
 
@@ -3925,13 +3940,14 @@ void InsetTabular::updateBuffer(ParIterator const & it, UpdateType utype)
 }
 
 
-void InsetTabular::addToToc(DocIterator const & cpit, bool output_active) const
+void InsetTabular::addToToc(DocIterator const & cpit, bool output_active,
+                                                       UpdateType utype) const
 {
        DocIterator dit = cpit;
        dit.forwardPos();
        size_t const end = dit.nargs();
        for ( ; dit.idx() < end; dit.top().forwardIdx())
-               cell(dit.idx())->addToToc(dit, output_active);
+               cell(dit.idx())->addToToc(dit, output_active, utype);
 }
 
 
@@ -3953,9 +3969,11 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        || cmd.x() > xo(cur.bv()) + tabular.width()) {
                        row_type r = rowFromY(cur, cmd.y());
                        cur.idx() = tabular.getFirstCellInRow(r);
+                       cur.pit() = 0;
                        cur.pos() = 0;
                        cur.resetAnchor();
                        cur.idx() = tabular.getLastCellInRow(r);
+                       cur.pit() = cur.lastpit();
                        cur.pos() = cur.lastpos();
                        cur.setSelection(true);
                        bvcur = cur;
@@ -3968,9 +3986,11 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        || cmd.y() > y0 + tabular.height()) {
                        col_type c = columnFromX(cur, cmd.x());
                        cur.idx() = tabular.cellIndex(0, c);
+                       cur.pit() = 0;
                        cur.pos() = 0;
                        cur.resetAnchor();
                        cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c);
+                       cur.pit() = cur.lastpit();
                        cur.pos() = cur.lastpos();
                        cur.setSelection(true);
                        bvcur = cur;
@@ -4155,9 +4175,10 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                else
                        movePrevCell(cur, entry_from);
                // if we're exiting the table, call the appropriate FINISHED lfun
-               if (sl == cur.top())
+               if (sl == cur.top()) {
                        cmd = FuncRequest(finish_lfun);
-               else
+                       cur.undispatched();
+               } else
                        cur.dispatched();
 
                cur.screenUpdateFlags(Update::Force | Update::FitCursor);
@@ -4251,7 +4272,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 //             int const t =   cur.bv().top_y() + cur.bv().height();
 //             if (t < yo() + tabular.getHeightOfTabular()) {
 //                     cur.bv().scrollDocView(t, true);
-//                     cur.idx() = tabular.cellBelow(first_visible_cell) + col;
+//                     cur.idx() = tabular.cellBelow(first_visible_cell_) + col;
 //             } else {
 //                     cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col;
 //             }
@@ -4270,7 +4291,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 //                     if (yo() > 0)
 //                             cur.idx() = col;
 //                     else
-//                             cur.idx() = tabular.cellBelow(first_visible_cell) + col;
+//                             cur.idx() = tabular.cellBelow(first_visible_cell_) + col;
 //             } else {
 //                     cur.idx() = col;
 //             }
@@ -4283,16 +4304,17 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                cur.bv().showDialog("tabular");
                break;
 
-       case LFUN_INSET_MODIFY: {
-               string arg;
-               if (cmd.getArg(1) == "from-dialog")
-                       arg = cmd.getArg(0) + to_utf8(cmd.argument().substr(19));
+       case LFUN_INSET_MODIFY:
+               // we come from the dialog
+               if (cmd.getArg(0) == "tabular")
+                       tabularFeatures(cur, cmd.getLongArg(1));
                else
-                       arg = to_utf8(cmd.argument());
-               if (!tabularFeatures(cur, arg))
                        cur.undispatched();
                break;
-       }
+
+       case LFUN_TABULAR_FEATURE:
+               tabularFeatures(cur, to_utf8(cmd.argument()));
+               break;
 
        // insert file functions
        case LFUN_FILE_INSERT_PLAINTEXT_PARA:
@@ -4459,25 +4481,9 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 }
 
 
-// function sets an object as defined in func_status.h:
-// states OK, Unknown, Disabled, On, Off.
-bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
-       FuncStatus & status) const
+bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
+                      string const & argument, FuncStatus & status) const
 {
-       switch (cmd.action()) {
-       case LFUN_INSET_MODIFY: {
-               if (&cur.inset() != this || cmd.getArg(0) != "tabular")
-                       break;
-
-               // FIXME: We only check for the very first argument...
-               string const s = cmd.getArg(1);
-               // We always enable the lfun if it is coming from the dialog
-               // because the dialog makes sure all the settings are valid,
-               // even though the first argument might not be valid now.
-               if (s == "from-dialog") {
-                       status.setEnabled(true);
-                       return true;
-               }
 
                int action = Tabular::LAST_ACTION;
                int i = 0;
@@ -4493,8 +4499,6 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        return true;
                }
 
-               string const argument = cmd.getLongArg(2);
-
                row_type sel_row_start = 0;
                row_type sel_row_end = 0;
                col_type sel_col_start = 0;
@@ -4609,9 +4613,13 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
 
                case Tabular::SET_LINE_TOP:
                case Tabular::SET_LINE_BOTTOM:
+                       status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+                       break;
+
                case Tabular::SET_LINE_LEFT:
                case Tabular::SET_LINE_RIGHT:
-                       status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+                       status.setEnabled(!tabular.use_booktabs
+                                         && !tabular.ltCaption(tabular.cellRow(cur.idx())));
                        break;
 
                case Tabular::TOGGLE_LINE_TOP:
@@ -4625,12 +4633,14 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::TOGGLE_LINE_LEFT:
-                       status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+                       status.setEnabled(!tabular.use_booktabs
+                                         && !tabular.ltCaption(tabular.cellRow(cur.idx())));
                        status.setOnOff(tabular.leftLine(cur.idx()));
                        break;
 
                case Tabular::TOGGLE_LINE_RIGHT:
-                       status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
+                       status.setEnabled(!tabular.use_booktabs
+                                         && !tabular.ltCaption(tabular.cellRow(cur.idx())));
                        status.setOnOff(tabular.rightLine(cur.idx()));
                        break;
 
@@ -4699,6 +4709,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::SET_LONGTABULAR:
+               case Tabular::TOGGLE_LONGTABULAR:
                        // setting as longtable is not allowed when table is inside a float
                        if (cur.innerInsetOfType(FLOAT_CODE) != 0
                                || cur.innerInsetOfType(WRAP_CODE) != 0)
@@ -4847,6 +4858,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        status.setOnOff(tabular.ltCaption(sel_row_start));
                        break;
 
+               case Tabular::TOGGLE_BOOKTABS:
                case Tabular::SET_BOOKTABS:
                        status.setOnOff(tabular.use_booktabs);
                        break;
@@ -4861,6 +4873,39 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
                }
                return true;
+}
+
+
+// function sets an object as defined in FuncStatus.h:
+// states OK, Unknown, Disabled, On, Off.
+bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
+                             FuncStatus & status) const
+{
+       switch (cmd.action()) {
+       case LFUN_INSET_MODIFY:
+               if (cmd.getArg(0) != "tabular")
+                       break;
+               if (cmd.getArg(1) == "for-dialog") {
+                       // The dialog is asking the status of a command
+                       if (&cur.inset() != this)
+                               break;
+                       string action = cmd.getArg(2);
+                       string arg = cmd.getLongArg(3);
+                       return getFeatureStatus(cur, action, arg, status);
+               } else {
+                       // We always enable the lfun if it is coming from the dialog
+                       // because the dialog makes sure all the settings are valid,
+                       // even though the first argument might not be valid now.
+                       status.setEnabled(true);
+                       return true;
+               }
+
+       case LFUN_TABULAR_FEATURE: {
+               if (&cur.inset() != this)
+                       break;
+               string action = cmd.getArg(0);
+               string arg = cmd.getLongArg(1); 
+               return getFeatureStatus(cur, action, arg, status);
        }
 
        case LFUN_CAPTION_INSERT: {
@@ -4934,6 +4979,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        status.setEnabled(false);
                        return true;
                }
+               // Fall back
        case LFUN_NEWLINE_INSERT: {
                if (tabular.getPWidth(cur.idx()).zero()) {
                        status.setEnabled(false);
@@ -5083,7 +5129,6 @@ void InsetTabular::cursorPos(BufferView const & bv,
        x += cellXPos(sl.idx());
        x += tabular.textHOffset(sl.idx());
        x += ADD_TO_TABULAR_WIDTH;
-       x += scx_;
 }
 
 
@@ -5124,7 +5169,6 @@ Inset * InsetTabular::editXY(Cursor & cur, int x, int y)
        cur.setSelection(false);
        cur.push(*this);
        cur.idx() = getNearestCell(cur.bv(), x, y);
-       resetPos(cur);
        return cur.bv().textMetrics(&cell(cur.idx())->text()).editXY(cur, x, y);
 }
 
@@ -5174,36 +5218,6 @@ int InsetTabular::cellXPos(idx_type const cell) const
 }
 
 
-void InsetTabular::resetPos(Cursor & cur) const
-{
-       BufferView & bv = cur.bv();
-       int const maxwidth = bv.workWidth();
-
-       int const scx_old = scx_;
-       int const i = cur.find(this);
-       if (i == -1) {
-               scx_ = 0;
-       } else {
-               int const X1 = 0;
-               int const X2 = maxwidth;
-               int const offset = ADD_TO_TABULAR_WIDTH + 2;
-               int const x1 = xo(cur.bv()) + cellXPos(cur[i].idx()) + offset;
-               int const x2 = x1 + tabular.cellWidth(cur[i].idx());
-
-               if (x1 < X1)
-                       scx_ = X1 + 20 - x1;
-               else if (x2 > X2)
-                       scx_ = X2 - 20 - x2;
-               else
-                       scx_ = 0;
-       }
-
-       // only update if offset changed
-       if (scx_ != scx_old)
-               cur.screenUpdateFlags(Update::Force | Update::FitCursor);
-}
-
-
 void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from)
 {
        row_type const row = tabular.cellRow(cur.idx());
@@ -5238,7 +5252,6 @@ void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from)
        if (cur.selIsMultiCell()) {
                cur.pit() = cur.lastpit();
                cur.pos() = cur.lastpos();
-               resetPos(cur);
                return;
        }
 
@@ -5261,7 +5274,6 @@ void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from)
 
        }
        cur.setCurrentFont();
-       resetPos(cur);
 }
 
 
@@ -5296,7 +5308,6 @@ void InsetTabular::movePrevCell(Cursor & cur, EntryDirection entry_from)
        if (cur.selIsMultiCell()) {
                cur.pit() = cur.lastpit();
                cur.pos() = cur.lastpos();
-               resetPos(cur);
                return;
        }
 
@@ -5319,27 +5330,24 @@ void InsetTabular::movePrevCell(Cursor & cur, EntryDirection entry_from)
 
        }
        cur.setCurrentFont();
-       resetPos(cur);
 }
 
 
-bool InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
+void InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
 {
+       cur.recordUndoInset(this);
+
        istringstream is(argument);
        string s;
-       is >> s;
-       if (insetCode(s) != TABULAR_CODE)
-               return false;
-
        // Safe guard.
        size_t safe_guard = 0;
        for (;;) {
                if (is.eof())
-                       break;
+                       return;
                safe_guard++;
                if (safe_guard > 1000) {
                        LYXERR0("parameter max count reached!");
-                       break;
+                       return;
                }
                is >> s;
                Tabular::Feature action = Tabular::LAST_ACTION;
@@ -5361,7 +5369,6 @@ bool InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
                LYXERR(Debug::DEBUG, "Feature: " << s << "\t\tvalue: " << val);
                tabularFeatures(cur, action, val);
        }
-       return true;
 }
 
 
@@ -5434,10 +5441,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                break;
 
        case Tabular::ALIGN_DECIMAL:
-               if (tabular.column_info[tabular.cellColumn(cur.idx())].alignment == LYX_ALIGN_DECIMAL)
-                       setAlign = LYX_ALIGN_CENTER;
-               else
-                       setAlign = LYX_ALIGN_DECIMAL;
+               setAlign = LYX_ALIGN_DECIMAL;
                break;
 
        case Tabular::M_VALIGN_TOP:
@@ -5459,8 +5463,6 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                break;
        }
 
-       cur.recordUndoInset(ATOMIC_UNDO, this);
-
        getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
        row_type const row = tabular.cellRow(cur.idx());
        col_type const column = tabular.cellColumn(cur.idx());
@@ -5780,6 +5782,13 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                }
                break;
 
+       case Tabular::TOGGLE_LONGTABULAR:
+               if (tabular.is_long_tabular)
+                       tabularFeatures(cur, Tabular::UNSET_LONGTABULAR);
+               else
+                       tabular.is_long_tabular = true;
+               break;
+
        case Tabular::SET_LONGTABULAR:
                tabular.is_long_tabular = true;
                break;
@@ -5920,7 +5929,9 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                cur.setSelection(false);
                // If a row is set as caption, then also insert
                // a caption. Otherwise the LaTeX output is broken.
-               lyx::dispatch(FuncRequest(LFUN_INSET_SELECT_ALL));
+               // Select cell if it is non-empty
+               if (cur.lastpos() > 0 || cur.lastpit() > 0)
+                       lyx::dispatch(FuncRequest(LFUN_INSET_SELECT_ALL));
                lyx::dispatch(FuncRequest(LFUN_CAPTION_INSERT));
                break;
        }
@@ -5946,6 +5957,10 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                break;
        }
 
+       case Tabular::TOGGLE_BOOKTABS:
+               tabular.use_booktabs = !tabular.use_booktabs;
+               break;
+
        case Tabular::SET_BOOKTABS:
                tabular.use_booktabs = true;
                break;
@@ -6262,7 +6277,6 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
        if (usePaste) {
                paste_tabular.reset(new Tabular(buffer_, rows, maxCols));
                loctab = paste_tabular.get();
-               cols = 0;
                dirtyTabularStack(true);
        } else {
                loctab = &tabular;
@@ -6442,4 +6456,22 @@ string InsetTabular::params2string(InsetTabular const & inset)
 }
 
 
+void InsetTabular::setLayoutForHiddenCells(DocumentClass const & dc)
+{
+       for (Tabular::col_type c = 0; c < tabular.ncols(); ++c) {
+               for (Tabular::row_type r = 0; r < tabular.nrows(); ++r) {
+                       if (!tabular.isPartOfMultiColumn(r,c) &&
+                           !tabular.isPartOfMultiRow(r,c))
+                               continue;
+
+                       ParagraphList & parlist = tabular.cellInset(r,c)->paragraphs();
+                       ParagraphList::iterator it = parlist.begin();
+                       ParagraphList::iterator const en = parlist.end();
+                       for (; it != en; ++it)
+                                       it->setLayout(dc.plainLayout());
+               }
+       }
+}
+
+
 } // namespace lyx