]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
Show corners of mathed with mouse hover, details see bug 3825
[lyx.git] / src / insets / InsetTabular.cpp
index 2b6d38f4dcfcdb0c4ec939f3f2161fdd4bd217c3..5d14a54eafae45de495623b54347475c597718ca 100644 (file)
@@ -23,7 +23,7 @@
 #include "Buffer.h"
 #include "BufferParams.h"
 #include "BufferView.h"
-#include "LCursor.h"
+#include "Cursor.h"
 #include "CutAndPaste.h"
 #include "CoordCache.h"
 #include "debug.h"
@@ -33,8 +33,8 @@
 #include "gettext.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
-#include "LColor.h"
-#include "lyx_cb.h"
+#include "Color.h"
+#include "callback.h"
 #include "Lexer.h"
 #include "MetricsInfo.h"
 #include "OutputParams.h"
@@ -46,7 +46,7 @@
 #include "support/convert.h"
 #include "support/lstrings.h"
 
-#include "frontends/Alert.h"
+#include "frontends/alert.h"
 #include "frontends/Clipboard.h"
 #include "frontends/Painter.h"
 #include "frontends/Selection.h"
@@ -151,8 +151,10 @@ TabularFeature tabularFeature[] =
        { Tabular::SET_MPWIDTH, "set-mpwidth" },
        { Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular" },
        { Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" },
+       { Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular" },
        { Tabular::SET_ROTATE_CELL, "set-rotate-cell" },
        { Tabular::UNSET_ROTATE_CELL, "unset-rotate-cell" },
+       { Tabular::TOGGLE_ROTATE_CELL, "toggle-rotate-cell" },
        { Tabular::SET_USEBOX, "set-usebox" },
        { Tabular::SET_LTHEAD, "set-lthead" },
        { Tabular::UNSET_LTHEAD, "unset-lthead" },
@@ -186,17 +188,6 @@ private:
 };
 
 
-string const featureAsString(Tabular::Feature feature)
-{
-       TabularFeature * end = tabularFeature +
-               sizeof(tabularFeature) / sizeof(TabularFeature);
-       TabularFeature * it = std::find_if(tabularFeature, end,
-                                          FeatureEqual(feature));
-       return (it == end) ? string() : it->feature;
-}
-
-
-
 template <class T>
 string const write_attribute(string const & name, T const & t)
 {
@@ -246,7 +237,7 @@ string const write_attribute(string const & name, Tabular::idx_type const & i)
 
 
 template <>
-string const write_attribute(string const & name, LyXLength const & value)
+string const write_attribute(string const & name, Length const & value)
 {
        // we write only the value if we really have one same reson as above.
        return value.zero() ? string() : write_attribute(name, value.asString());
@@ -437,19 +428,19 @@ bool getTokenValue(string const & str, char const * token, bool & flag)
 }
 
 
-bool getTokenValue(string const & str, char const * token, LyXLength & len)
+bool getTokenValue(string const & str, char const * token, Length & len)
 {
        // set the lenght to be zero() as default as this it should be if not
        // in the file format.
-       len = LyXLength();
+       len = Length();
        string tmp;
        return getTokenValue(str, token, tmp) && isValidLength(tmp, &len);
 }
 
 
-bool getTokenValue(string const & str, char const * token, LyXLength & len, bool & flag)
+bool getTokenValue(string const & str, char const * token, Length & len, bool & flag)
 {
-       len = LyXLength();
+       len = Length();
        flag = false;
        string tmp;
        if (!getTokenValue(str, token, tmp))
@@ -475,6 +466,17 @@ void l_getline(istream & is, string & str)
 } // namespace
 
 
+string const featureAsString(Tabular::Feature feature)
+{
+       TabularFeature * end = tabularFeature +
+               sizeof(tabularFeature) / sizeof(TabularFeature);
+       TabularFeature * it = std::find_if(tabularFeature, end,
+                                          FeatureEqual(feature));
+       return (it == end) ? string() : it->feature;
+}
+
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // Tabular
@@ -835,14 +837,8 @@ bool Tabular::leftLine(idx_type cell, bool wholecolumn) const
                return false;
        if (!wholecolumn && isMultiColumn(cell) &&
                (isFirstCellInRow(cell) || isMultiColumn(cell-1)))
-       {
-               if (cellinfo_of_cell(cell).align_special.empty())
-                       return cellinfo_of_cell(cell).left_line;
-               return prefixIs(ltrim(cellinfo_of_cell(cell).align_special), '|');
-       }
-       if (column_info[column_of_cell(cell)].align_special.empty())
-               return column_info[column_of_cell(cell)].left_line;
-       return prefixIs(ltrim(column_info[column_of_cell(cell)].align_special), '|');
+               return cellinfo_of_cell(cell).left_line;
+       return column_info[column_of_cell(cell)].left_line;
 }
 
 
@@ -852,14 +848,8 @@ bool Tabular::rightLine(idx_type cell, bool wholecolumn) const
                return false;
        if (!wholecolumn && isMultiColumn(cell) &&
                (isLastCellInRow(cell) || isMultiColumn(cell + 1)))
-       {
-               if (cellinfo_of_cell(cell).align_special.empty())
-                       return cellinfo_of_cell(cell).right_line;
-               return suffixIs(rtrim(cellinfo_of_cell(cell).align_special), '|');
-       }
-       if (column_info[column_of_cell(cell)].align_special.empty())
-               return column_info[right_column_of_cell(cell)].right_line;
-       return suffixIs(rtrim(column_info[column_of_cell(cell)].align_special), '|');
+               return cellinfo_of_cell(cell).right_line;
+       return column_info[right_column_of_cell(cell)].right_line;
 }
 
 
@@ -1094,7 +1084,7 @@ namespace {
  * merge cell paragraphs and reset layout to standard for variable width
  * cells.
  */
-void toggleFixedWidth(LCursor & cur, InsetText * inset, bool fixedWidth)
+void toggleFixedWidth(Cursor & cur, InsetText * inset, bool fixedWidth)
 {
        inset->setAutoBreakRows(fixedWidth);
        if (fixedWidth)
@@ -1109,15 +1099,15 @@ void toggleFixedWidth(LCursor & cur, InsetText * inset, bool fixedWidth)
        cur.push(*inset);
        // undo information has already been recorded
        inset->getText(0)->setLayout(*cur.bv().buffer(), 0, cur.lastpit() + 1,
-                       bp.getLyXTextClass().defaultLayoutName());
+                       bp.getTextClass().defaultLayoutName());
        cur.pop();
 }
 
 }
 
 
-void Tabular::setColumnPWidth(LCursor & cur, idx_type cell,
-               LyXLength const & width)
+void Tabular::setColumnPWidth(Cursor & cur, idx_type cell,
+               Length const & width)
 {
        col_type const j = column_of_cell(cell);
 
@@ -1137,8 +1127,8 @@ void Tabular::setColumnPWidth(LCursor & cur, idx_type cell,
 }
 
 
-bool Tabular::setMColumnPWidth(LCursor & cur, idx_type cell,
-               LyXLength const & width)
+bool Tabular::setMColumnPWidth(Cursor & cur, idx_type cell,
+               Length const & width)
 {
        if (!isMultiColumn(cell))
                return false;
@@ -1228,7 +1218,7 @@ Tabular::getVAlignment(idx_type cell, bool onlycolumn) const
 }
 
 
-LyXLength const Tabular::getPWidth(idx_type cell) const
+Length const Tabular::getPWidth(idx_type cell) const
 {
        if (isMultiColumn(cell))
                return cellinfo_of_cell(cell).p_width;
@@ -1236,17 +1226,17 @@ LyXLength const Tabular::getPWidth(idx_type cell) const
 }
 
 
-LyXLength const Tabular::getColumnPWidth(idx_type cell) const
+Length const Tabular::getColumnPWidth(idx_type cell) const
 {
        return column_info[column_of_cell(cell)].p_width;
 }
 
 
-LyXLength const Tabular::getMColumnPWidth(idx_type cell) const
+Length const Tabular::getMColumnPWidth(idx_type cell) const
 {
        if (isMultiColumn(cell))
                return cellinfo_of_cell(cell).p_width;
-       return LyXLength();
+       return Length();
 }
 
 
@@ -1544,11 +1534,11 @@ void Tabular::read(Buffer const & buf, Lexer & lex)
                getTokenValue(line, "topline", row_info[i].top_line);
                getTokenValue(line, "bottomline", row_info[i].bottom_line);
                getTokenValue(line, "topspace", row_info[i].top_space,
-                             row_info[i].top_space_default);
+                             row_info[i].top_space_default);
                getTokenValue(line, "bottomspace", row_info[i].bottom_space,
-                             row_info[i].bottom_space_default);
+                             row_info[i].bottom_space_default);
                getTokenValue(line, "interlinespace", row_info[i].interline_space,
-                             row_info[i].interline_space_default);
+                             row_info[i].interline_space_default);
                getTokenValue(line, "endfirsthead", row_info[i].endfirsthead);
                getTokenValue(line, "endhead", row_info[i].endhead);
                getTokenValue(line, "endfoot", row_info[i].endfoot);
@@ -2055,16 +2045,14 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell) const
        }
        if (isMultiColumn(cell)) {
                os << "\\multicolumn{" << cells_in_multicolumn(cell) << "}{";
+               if (leftLine(cell) &&
+                       (isFirstCellInRow(cell) ||
+                        (!isMultiColumn(cell - 1) && !leftLine(cell, true) &&
+                         !rightLine(cell - 1, true))))
+                       os << '|';
                if (!cellinfo_of_cell(cell).align_special.empty()) {
-                       os << cellinfo_of_cell(cell).align_special << "}{";
+                       os << cellinfo_of_cell(cell).align_special;
                } else {
-                       if (leftLine(cell) &&
-                               (isFirstCellInRow(cell) ||
-                                (!isMultiColumn(cell - 1) && !leftLine(cell, true) &&
-                                 !rightLine(cell - 1, true))))
-                       {
-                               os << '|';
-                       }
                        if (!getPWidth(cell).zero()) {
                                switch (getVAlignment(cell)) {
                                case LYX_VALIGN_TOP:
@@ -2092,15 +2080,15 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell) const
                                        os << 'c';
                                        break;
                                }
-                       }
-                       if (rightLine(cell))
-                               os << '|';
-                       if (((cell + 1) < numberofcells) && !isFirstCellInRow(cell+1) &&
-                               leftLine(cell+1))
-                               os << '|';
-                       os << "}{";
+                       } // end if else !getPWidth
+               } // end if else !cellinfo_of_cell
+               if (rightLine(cell))
+                       os << '|';
+               if (((cell + 1) < numberofcells) && !isFirstCellInRow(cell+1) &&
+                       leftLine(cell+1))
+                       os << '|';
+               os << "}{";
                }
-       }
        if (getUsebox(cell) == BOX_PARBOX) {
                os << "\\parbox[";
                switch (getVAlignment(cell)) {
@@ -2282,7 +2270,7 @@ int Tabular::TeXRow(odocstream & os, row_type i, Buffer const & buf,
                }
                ++ret;
        }
-       
+
        for (col_type j = 0; j < columns_; ++j) {
                if (isPartOfMultiColumn(i, j))
                        continue;
@@ -2294,8 +2282,13 @@ int Tabular::TeXRow(odocstream & os, row_type i, Buffer const & buf,
                        && !par.empty()
                        && getPWidth(cell).zero();
 
-               if (rtl)
-                       os << "\\R{";
+               if (rtl) {
+                       if (par.getParLanguage(buf.params())->lang() ==
+                       "farsi")
+                               os << "\\textFR{";
+                       else
+                               os << "\\R{";
+               }
                ret += inset->latex(buf, os, runparams);
                if (rtl)
                        os << '}';
@@ -2361,11 +2354,11 @@ int Tabular::latex(Buffer const & buf, odocstream & os,
        else
                os << "\\begin{tabular}{";
        for (col_type i = 0; i < columns_; ++i) {
+               if (!use_booktabs && column_info[i].left_line)
+                       os << '|';
                if (!column_info[i].align_special.empty()) {
                        os << column_info[i].align_special;
                } else {
-                       if (!use_booktabs && column_info[i].left_line)
-                               os << '|';
                        if (!column_info[i].p_width.zero()) {
                                switch (column_info[i].alignment) {
                                case LYX_ALIGN_LEFT:
@@ -2410,10 +2403,10 @@ int Tabular::latex(Buffer const & buf, odocstream & os,
                                        os << 'c';
                                        break;
                                }
-                       }
-                       if (!use_booktabs && column_info[i].right_line)
-                               os << '|';
-               }
+                       } // end if else !column_info[i].p_width
+               } // end if else !column_info[i].align_special
+               if (!use_booktabs && column_info[i].right_line)
+                       os << '|';
        }
        os << "}\n";
        ++ret;
@@ -2589,7 +2582,7 @@ int Tabular::docbook(Buffer const & buf, odocstream & os,
 
 
 bool Tabular::plaintextTopHLine(odocstream & os, row_type row,
-                                   vector<unsigned int> const & clen) const
+                                  vector<unsigned int> const & clen) const
 {
        idx_type const fcell = getFirstCellInRow(row);
        idx_type const n = numberOfCellsInRow(fcell) + fcell;
@@ -2637,7 +2630,7 @@ bool Tabular::plaintextTopHLine(odocstream & os, row_type row,
 
 
 bool Tabular::plaintextBottomHLine(odocstream & os, row_type row,
-                                      vector<unsigned int> const & clen) const
+                                     vector<unsigned int> const & clen) const
 {
        idx_type const fcell = getFirstCellInRow(row);
        idx_type const n = numberOfCellsInRow(fcell) + fcell;
@@ -2736,8 +2729,8 @@ void Tabular::plaintextPrintCell(Buffer const & buf, odocstream & os,
 
 
 void Tabular::plaintext(Buffer const & buf, odocstream & os,
-                           OutputParams const & runparams, int const depth,
-                           bool onlydata, unsigned char delim) const
+                          OutputParams const & runparams, int const depth,
+                          bool onlydata, unsigned char delim) const
 {
        // first calculate the width of the single columns
        vector<unsigned int> clen(columns_);
@@ -2783,7 +2776,7 @@ void Tabular::plaintext(Buffer const & buf, odocstream & os,
                        if (onlydata && j > 0)
                                os << delim;
                        plaintextPrintCell(buf, os, runparams,
-                                          cell, i, j, clen, onlydata);
+                                          cell, i, j, clen, onlydata);
                        ++cell;
                }
                os << endl;
@@ -2817,7 +2810,7 @@ void Tabular::setCellInset(row_type row, col_type column,
 
 
 Tabular::idx_type
-Tabular::getCellFromInset(InsetBase const * inset) const
+Tabular::getCellFromInset(Inset const * inset) const
 {
        // is this inset part of the tabular?
        if (!inset) {
@@ -2888,7 +2881,7 @@ InsetTabular::InsetTabular(Buffer const & buf, row_type rows,
 
 
 InsetTabular::InsetTabular(InsetTabular const & tab)
-       : InsetOld(tab), tabular(tab.tabular),
+       : Inset(tab), tabular(tab.tabular),
                buffer_(tab.buffer_), scx_(0), is_deleted_(false)
 {}
 
@@ -2900,9 +2893,9 @@ InsetTabular::~InsetTabular()
 }
 
 
-auto_ptr<InsetBase> InsetTabular::doClone() const
+auto_ptr<Inset> InsetTabular::doClone() const
 {
-       return auto_ptr<InsetBase>(new InsetTabular(*this));
+       return auto_ptr<Inset>(new InsetTabular(*this));
 }
 
 
@@ -2966,7 +2959,7 @@ bool InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                                continue;
                        Dimension dim;
                        MetricsInfo m = mi;
-                       LyXLength p_width;
+                       Length p_width;
                        if (tabular.cell_info[i][j].multicolumn ==
                            Tabular::CELL_BEGIN_OF_MULTICOLUMN)
                                p_width = tabular.cellinfo_of_cell(cell).p_width;
@@ -3060,7 +3053,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
 {
        setPosCache(pi, x, y);
 
-       LCursor & cur = pi.base.bv->cursor();
+       Cursor & cur = pi.base.bv->cursor();
 
        x += scx_ + ADD_TO_TABULAR_WIDTH;
 
@@ -3096,7 +3089,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
                                int const w = tabular.getWidthOfColumn(cell);
                                if (i >= cs && i <= ce && j >= rs && j <= re)
                                        pi.pain.fillRectangle(xx, y, w, h,
-                                                             LColor::selection);
+                                                             Color::selection);
                                xx += w;
                        }
                        y += h;
@@ -3113,12 +3106,12 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
 {
        int x2 = x + tabular.getWidthOfColumn(cell);
        bool on_off = false;
-       LColor::color col = LColor::tabularline;
-       LColor::color onoffcol = LColor::tabularonoffline;
+       Color::color col = Color::tabularline;
+       Color::color onoffcol = Color::tabularonoffline;
 
        if (erased) {
-               col = LColor::strikeout;
-               onoffcol = LColor::strikeout;
+               col = Color::deletedtext;
+               onoffcol = Color::deletedtext;
        }
 
        if (!tabular.topAlreadyDrawn(cell)) {
@@ -3156,7 +3149,7 @@ docstring const InsetTabular::editMessage() const
 }
 
 
-void InsetTabular::edit(LCursor & cur, bool left)
+void InsetTabular::edit(Cursor & cur, bool left)
 {
        //lyxerr << "InsetTabular::edit: " << this << endl;
        finishUndo();
@@ -3183,20 +3176,20 @@ void InsetTabular::edit(LCursor & cur, bool left)
 }
 
 
-void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
+void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
        LYXERR(Debug::DEBUG) << "# InsetTabular::doDispatch: cmd: " << cmd
                             << "\n  cur:" << cur << endl;
        CursorSlice sl = cur.top();
-       LCursor & bvcur = cur.bv().cursor();
+       Cursor & bvcur = cur.bv().cursor();
 
        switch (cmd.action) {
 
        case LFUN_MOUSE_PRESS:
                //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
 
-               if (cmd.button() == mouse_button::button1 
-                   || (cmd.button() == mouse_button::button3 
+               if (cmd.button() == mouse_button::button1
+                   || (cmd.button() == mouse_button::button3
                        && (&bvcur.selBegin().inset() != this || !tablemode(bvcur)))) {
                        if (!bvcur.selection() && !cur.bv().mouseSetCursor(cur))
                                cur.noUpdate();
@@ -3208,7 +3201,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
 
                if (cmd.button() == mouse_button::button2) {
                        if (cap::selection()) {
-                               // See comment in LyXText::dispatch why we
+                               // See comment in Text::dispatch why we
                                // do this
                                // FIXME This does not use paste_tabular,
                                // another reason why paste_tabular should go.
@@ -3216,9 +3209,11 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                                cmd = FuncRequest(LFUN_PASTE, "0");
                        } else {
                                cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE,
-                                                 "paragraph");
+                                                 "paragraph");
                        }
                        doDispatch(cur, cmd);
+                       cur.bv().buffer()->markDirty();
+                       cur.bv().mouseSetCursor(cur);
                }
                break;
 
@@ -3298,7 +3293,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                cell(cur.idx())->dispatch(cur, cmd);
                cur.dispatched(); // override the cell's decision
                if (sl == cur.top())
-                       // if our LyXText didn't do anything to the cursor
+                       // if our Text didn't do anything to the cursor
                        // then we try to put the cursor into the cell below
                        // setting also the right targetX.
                        if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) {
@@ -3328,13 +3323,13 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                cell(cur.idx())->dispatch(cur, cmd);
                cur.dispatched(); // override the cell's decision
                if (sl == cur.top())
-                       // if our LyXText didn't do anything to the cursor
+                       // if our Text didn't do anything to the cursor
                        // then we try to put the cursor into the cell above
                        // setting also the right targetX.
                        if (tabular.row_of_cell(cur.idx()) != 0) {
                                cur.idx() = tabular.getCellAbove(cur.idx());
                                cur.pit() = cur.lastpit();
-                               LyXText const * text = cell(cur.idx())->getText(0);
+                               Text const * text = cell(cur.idx())->getText(0);
                                TextMetrics const & tm = cur.bv().textMetrics(text);
                                ParagraphMetrics const & pm =
                                        tm.parMetrics(cur.lastpit());
@@ -3348,7 +3343,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                                }
                        }
                if (sl == cur.top()) {
-                       cmd = FuncRequest(LFUN_FINISHED_UP);
+                       cmd = FuncRequest(LFUN_UP);
                        cur.undispatched();
                }
                break;
@@ -3495,7 +3490,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                        row_type rs, re;
                        col_type cs, ce;
                        getSelection(cur, rs, re, cs, ce);
-                       LCursor tmpcur = cur;
+                       Cursor tmpcur = cur;
                        for (row_type i = rs; i <= re; ++i) {
                                for (col_type j = cs; j <= ce; ++j) {
                                        // cursor follows cell:
@@ -3531,7 +3526,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
 
 // function sets an object as defined in func_status.h:
 // states OK, Unknown, Disabled, On, Off.
-bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
+bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
        FuncStatus & status) const
 {
        switch (cmd.action) {
@@ -3556,11 +3551,12 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
 
                row_type sel_row_start = 0;
                row_type sel_row_end = 0;
-               col_type dummy;
+               col_type sel_col_start = 0;
+               col_type sel_col_end = 0;
                Tabular::ltType dummyltt;
                bool flag = true;
 
-               getSelection(cur, sel_row_start, sel_row_end, dummy, dummy);
+               getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
 
                switch (action) {
                case Tabular::SET_PWIDTH:
@@ -3661,6 +3657,7 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
                        status.setOnOff(!tabular.isLongTabular());
                        break;
 
+               case Tabular::TOGGLE_ROTATE_TABULAR:
                case Tabular::SET_ROTATE_TABULAR:
                        status.setOnOff(tabular.getRotateTabular());
                        break;
@@ -3669,12 +3666,15 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
                        status.setOnOff(!tabular.getRotateTabular());
                        break;
 
+               case Tabular::TOGGLE_ROTATE_CELL:
                case Tabular::SET_ROTATE_CELL:
-                       status.setOnOff(tabular.getRotateCell(cur.idx()));
+                       status.setOnOff(!oneCellHasRotationState(false,
+                               sel_row_start, sel_row_end, sel_col_start, sel_col_end));
                        break;
 
                case Tabular::UNSET_ROTATE_CELL:
-                       status.setOnOff(!tabular.getRotateCell(cur.idx()));
+                       status.setOnOff(!oneCellHasRotationState(true,
+                               sel_row_start, sel_row_end, sel_col_start, sel_col_end));
                        break;
 
                case Tabular::SET_USEBOX:
@@ -3798,14 +3798,14 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
 
 
 int InsetTabular::latex(Buffer const & buf, odocstream & os,
-                        OutputParams const & runparams) const
+                       OutputParams const & runparams) const
 {
        return tabular.latex(buf, os, runparams);
 }
 
 
 int InsetTabular::plaintext(Buffer const & buf, odocstream & os,
-                            OutputParams const & runparams) const
+                           OutputParams const & runparams) const
 {
        os << '\n'; // output table on a new line
        int const dp = runparams.linelen > 0 ? runparams.depth : 0;
@@ -3815,10 +3815,10 @@ int InsetTabular::plaintext(Buffer const & buf, odocstream & os,
 
 
 int InsetTabular::docbook(Buffer const & buf, odocstream & os,
-                          OutputParams const & runparams) const
+                         OutputParams const & runparams) const
 {
        int ret = 0;
-       InsetBase * master = 0;
+       Inset * master = 0;
 
 #ifdef WITH_WARNINGS
 #warning Why not pass a proper DocIterator here?
@@ -3827,7 +3827,7 @@ int InsetTabular::docbook(Buffer const & buf, odocstream & os,
        // if the table is inside a float it doesn't need the informaltable
        // wrapper. Search for it.
        for (master = owner(); master; master = master->owner())
-               if (master->lyxCode() == InsetBase::FLOAT_CODE)
+               if (master->lyxCode() == Inset::FLOAT_CODE)
                        break;
 #endif
 
@@ -3897,7 +3897,7 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
 {
        int xx = 0;
        int yy = 0;
-       InsetBase const & inset = *tabular.getCellInset(cell);
+       Inset const & inset = *tabular.getCellInset(cell);
        Point o = bv.coordCache().getInsets().xy(&inset);
        int const xbeg = o.x_ - tabular.getBeginningOfTextInCell(cell);
        int const xend = xbeg + tabular.getWidthOfColumn(cell);
@@ -3924,7 +3924,7 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
 }
 
 
-InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y)
+Inset * InsetTabular::editXY(Cursor & cur, int x, int y)
 {
        //lyxerr << "InsetTabular::editXY: " << this << endl;
        cur.selection() = false;
@@ -3935,7 +3935,7 @@ InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y)
 }
 
 
-void InsetTabular::setCursorFromCoordinates(LCursor & cur, int x, int y) const
+void InsetTabular::setCursorFromCoordinates(Cursor & cur, int x, int y) const
 {
        cur.idx() = getNearestCell(cur.bv(), x, y);
        cell(cur.idx())->text_.setCursorFromCoordinates(cur, x, y);
@@ -3973,7 +3973,7 @@ int InsetTabular::getCellXPos(idx_type const cell) const
 }
 
 
-void InsetTabular::resetPos(LCursor & cur) const
+void InsetTabular::resetPos(Cursor & cur) const
 {
        BufferView & bv = cur.bv();
        int const maxwidth = bv.workWidth();
@@ -3999,7 +3999,7 @@ void InsetTabular::resetPos(LCursor & cur) const
 }
 
 
-void InsetTabular::moveNextCell(LCursor & cur)
+void InsetTabular::moveNextCell(Cursor & cur)
 {
        if (isRightToLeft(cur)) {
                if (tabular.isFirstCellInRow(cur.idx())) {
@@ -4023,7 +4023,7 @@ void InsetTabular::moveNextCell(LCursor & cur)
 }
 
 
-void InsetTabular::movePrevCell(LCursor & cur)
+void InsetTabular::movePrevCell(Cursor & cur)
 {
        if (isRightToLeft(cur)) {
                if (tabular.isLastCellInRow(cur.idx())) {
@@ -4050,7 +4050,7 @@ void InsetTabular::movePrevCell(LCursor & cur)
 }
 
 
-bool InsetTabular::tabularFeatures(LCursor & cur, string const & what)
+bool InsetTabular::tabularFeatures(Cursor & cur, string const & what)
 {
        Tabular::Feature action = Tabular::LAST_ACTION;
 
@@ -4060,7 +4060,7 @@ bool InsetTabular::tabularFeatures(LCursor & cur, string const & what)
 
                if (tmp == what.substr(0, tmp.length())) {
                        //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(),
-                       //tabularFeatures[i].feature.length())) 
+                       //tabularFeatures[i].feature.length()))
                        action = tabularFeature[i].action;
                        break;
                }
@@ -4093,8 +4093,22 @@ static void checkLongtableSpecial(Tabular::ltType & ltt,
        }
 }
 
+bool InsetTabular::oneCellHasRotationState(bool rotated,
+               row_type row_start, row_type row_end,
+               col_type col_start, col_type col_end) const {
+
+       for (row_type i = row_start; i <= row_end; ++i) {
+               for (col_type j = col_start; j <= col_end; ++j) {
+                       if (tabular.getRotateCell(tabular.getCellNumber(i, j))
+                               == rotated) {
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
 
-void InsetTabular::tabularFeatures(LCursor & cur,
+void InsetTabular::tabularFeatures(Cursor & cur,
        Tabular::Feature feature, string const & value)
 {
        BufferView & bv = cur.bv();
@@ -4157,7 +4171,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
        switch (feature) {
 
        case Tabular::SET_PWIDTH: {
-               LyXLength const len(value);
+               Length const len(value);
                tabular.setColumnPWidth(cur, cur.idx(), len);
                if (len.zero()
                    && tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_BLOCK)
@@ -4166,7 +4180,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
        }
 
        case Tabular::SET_MPWIDTH:
-               tabular.setMColumnPWidth(cur, cur.idx(), LyXLength(value));
+               tabular.setMColumnPWidth(cur, cur.idx(), Length(value));
                break;
 
        case Tabular::SET_SPECIAL_COLUMN:
@@ -4353,6 +4367,10 @@ void InsetTabular::tabularFeatures(LCursor & cur,
                tabular.setRotateTabular(false);
                break;
 
+       case Tabular::TOGGLE_ROTATE_TABULAR:
+               tabular.setRotateTabular(!tabular.getRotateTabular());
+               break;
+
        case Tabular::SET_ROTATE_CELL:
                for (row_type i = sel_row_start; i <= sel_row_end; ++i)
                        for (col_type j = sel_col_start; j <= sel_col_end; ++j)
@@ -4367,6 +4385,18 @@ void InsetTabular::tabularFeatures(LCursor & cur,
                                        tabular.getCellNumber(i, j), false);
                break;
 
+       case Tabular::TOGGLE_ROTATE_CELL:
+               {
+               bool oneNotRotated = oneCellHasRotationState(false,
+                       sel_row_start, sel_row_end, sel_col_start, sel_col_end);
+
+               for (row_type i = sel_row_start; i <= sel_row_end; ++i)
+                       for (col_type j = sel_col_start; j <= sel_col_end; ++j)
+                               tabular.setRotateCell(tabular.getCellNumber(i, j),
+                                                                         oneNotRotated);
+               }
+               break;
+
        case Tabular::SET_USEBOX: {
                Tabular::BoxType val = Tabular::BoxType(convert<int>(value));
                if (val == tabular.getUsebox(cur.idx()))
@@ -4422,7 +4452,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
                break;
 
        case Tabular::SET_TOP_SPACE: {
-               LyXLength len;
+               Length len;
                if (value == "default")
                        for (row_type i = sel_row_start; i <= sel_row_end; ++i)
                                tabular.row_info[i].top_space_default = true;
@@ -4440,7 +4470,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
        }
 
        case Tabular::SET_BOTTOM_SPACE: {
-               LyXLength len;
+               Length len;
                if (value == "default")
                        for (row_type i = sel_row_start; i <= sel_row_end; ++i)
                                tabular.row_info[i].bottom_space_default = true;
@@ -4458,7 +4488,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
        }
 
        case Tabular::SET_INTERLINE_SPACE: {
-               LyXLength len;
+               Length len;
                if (value == "default")
                        for (row_type i = sel_row_start; i <= sel_row_end; ++i)
                                tabular.row_info[i].interline_space_default = true;
@@ -4495,7 +4525,7 @@ void InsetTabular::openLayoutDialog(BufferView * bv) const
 }
 
 
-bool InsetTabular::copySelection(LCursor & cur)
+bool InsetTabular::copySelection(Cursor & cur)
 {
        if (!cur.selection())
                return false;
@@ -4544,7 +4574,7 @@ bool InsetTabular::copySelection(LCursor & cur)
 }
 
 
-bool InsetTabular::pasteClipboard(LCursor & cur)
+bool InsetTabular::pasteClipboard(Cursor & cur)
 {
        if (!paste_tabular)
                return false;
@@ -4572,7 +4602,7 @@ bool InsetTabular::pasteClipboard(LCursor & cur)
                        tabular.setCellInset(r2, c2, inset);
                        // FIXME: change tracking (MG)
                        inset->setChange(Change(cur.buffer().params().trackChanges ?
-                                               Change::INSERTED : Change::UNCHANGED));
+                                               Change::INSERTED : Change::UNCHANGED));
                        cur.pos() = 0;
                }
        }
@@ -4580,7 +4610,7 @@ bool InsetTabular::pasteClipboard(LCursor & cur)
 }
 
 
-void InsetTabular::cutSelection(LCursor & cur)
+void InsetTabular::cutSelection(Cursor & cur)
 {
        if (!cur.selection())
                return;
@@ -4610,7 +4640,7 @@ void InsetTabular::cutSelection(LCursor & cur)
 }
 
 
-bool InsetTabular::isRightToLeft(LCursor & cur) const
+bool InsetTabular::isRightToLeft(Cursor & cur) const
 {
        BOOST_ASSERT(cur.depth() > 1);
        Paragraph const & parentpar = cur[cur.depth() - 2].paragraph();
@@ -4620,7 +4650,7 @@ bool InsetTabular::isRightToLeft(LCursor & cur) const
 }
 
 
-void InsetTabular::getSelection(LCursor & cur,
+void InsetTabular::getSelection(Cursor & cur,
        row_type & rs, row_type & re, col_type & cs, col_type & ce) const
 {
        CursorSlice const & beg = cur.selBegin();
@@ -4641,7 +4671,7 @@ void InsetTabular::getSelection(LCursor & cur,
 }
 
 
-LyXText * InsetTabular::getText(int idx) const
+Text * InsetTabular::getText(int idx) const
 {
        return size_t(idx) < nargs() ? cell(idx)->getText(0) : 0;
 }
@@ -4739,9 +4769,9 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
                        if (cols < columns) {
                                shared_ptr<InsetText> inset = loctab->getCellInset(cell);
                                Paragraph & par = inset->text_.getPar(0);
-                               LyXFont const font = inset->text_.getFont(buffer, par, 0);
+                               Font const font = inset->text_.getFont(buffer, par, 0);
                                inset->setText(buf.substr(op, p - op), font,
-                                              buffer.params().trackChanges);
+                                              buffer.params().trackChanges);
                                ++cols;
                                ++cell;
                        }
@@ -4751,9 +4781,9 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
                        if (cols < columns) {
                                shared_ptr<InsetText> inset = tabular.getCellInset(cell);
                                Paragraph & par = inset->text_.getPar(0);
-                               LyXFont const font = inset->text_.getFont(buffer, par, 0);
+                               Font const font = inset->text_.getFont(buffer, par, 0);
                                inset->setText(buf.substr(op, p - op), font,
-                                              buffer.params().trackChanges);
+                                              buffer.params().trackChanges);
                        }
                        cols = ocol;
                        ++row;
@@ -4768,7 +4798,7 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
        if (cell < cells && op < len) {
                shared_ptr<InsetText> inset = loctab->getCellInset(cell);
                Paragraph & par = inset->text_.getPar(0);
-               LyXFont const font = inset->text_.getFont(buffer, par, 0);
+               Font const font = inset->text_.getFont(buffer, par, 0);
                inset->setText(buf.substr(op, len - op), font,
                        buffer.params().trackChanges);
        }
@@ -4787,7 +4817,7 @@ void InsetTabular::addPreview(PreviewLoader & loader) const
 }
 
 
-bool InsetTabular::tablemode(LCursor & cur) const
+bool InsetTabular::tablemode(Cursor & cur) const
 {
        return cur.selection() && cur.selBegin().idx() != cur.selEnd().idx();
 }