]> git.lyx.org Git - lyx.git/blobdiff - src/tabular.C
cleanup after svn hang-up, #undef CursorShape. Should be compilable ganin now.
[lyx.git] / src / tabular.C
index acbdae6fc535cb9adefb409dcee026dd43dfa15a..60c20f9d55c6b5973153283f58d26c10a9912bd6 100644 (file)
@@ -64,6 +64,8 @@ using std::strlen;
 namespace {
 
 int const WIDTH_OF_LINE = 5;
+int const default_line_space = 10;
+
 
 template <class T>
 string const write_attribute(string const & name, T const & t)
@@ -299,6 +301,21 @@ bool getTokenValue(string const & str, char const * token, LyXLength & len)
 }
 
 
+bool getTokenValue(string const & str, char const * token, LyXLength & len, bool & flag)
+{
+       len = LyXLength();
+       flag = false;
+       string tmp;
+       if (!getTokenValue(str, token, tmp))
+               return false;
+       if (tmp == "default") {
+               flag = true;
+               return  true;
+       }
+       return isValidLength(tmp, &len);
+}
+
+
 void l_getline(istream & is, string & str)
 {
        str.erase();
@@ -380,6 +397,9 @@ LyXTabular::rowstruct::rowstruct()
          descent_of_row(0),
          top_line(true),
          bottom_line(false),
+         top_space_default(false),
+         bottom_space_default(false),
+         interline_space_default(false),
          endhead(false),
          endfirsthead(false),
          endfoot(false),
@@ -406,7 +426,7 @@ LyXTabular::ltType::ltType()
 
 
 LyXTabular::LyXTabular(BufferParams const & bp, row_type rows_arg,
-                       col_type columns_arg)
+                      col_type columns_arg)
 {
        init(bp, rows_arg, columns_arg);
 }
@@ -414,7 +434,7 @@ LyXTabular::LyXTabular(BufferParams const & bp, row_type rows_arg,
 
 // activates all lines and sets all widths to 0
 void LyXTabular::init(BufferParams const & bp, row_type rows_arg,
-                      col_type columns_arg)
+                     col_type columns_arg)
 {
        rows_    = rows_arg;
        columns_ = columns_arg;
@@ -432,6 +452,7 @@ void LyXTabular::init(BufferParams const & bp, row_type rows_arg,
        column_info.back().right_line = true;
        is_long_tabular = false;
        rotate = false;
+       use_booktabs = false;
 }
 
 
@@ -607,10 +628,10 @@ LyXTabular::idx_type LyXTabular::numberOfCellsInRow(idx_type const cell) const
 }
 
 
-// returns 1 if there is a topline, returns 0 if not
 bool LyXTabular::topLine(idx_type const cell, bool const onlycolumn) const
 {
-       if (!onlycolumn && isMultiColumn(cell))
+       if (!onlycolumn && isMultiColumn(cell) &&
+           !(use_booktabs && row_of_cell(cell) == 0))
                return cellinfo_of_cell(cell).top_line;
        return row_info[row_of_cell(cell)].top_line;
 }
@@ -618,7 +639,8 @@ bool LyXTabular::topLine(idx_type const cell, bool const onlycolumn) const
 
 bool LyXTabular::bottomLine(idx_type const cell, bool onlycolumn) const
 {
-       if (!onlycolumn && isMultiColumn(cell))
+       if (!onlycolumn && isMultiColumn(cell) &&
+           !(use_booktabs && isLastRow(cell)))
                return cellinfo_of_cell(cell).bottom_line;
        return row_info[row_of_cell(cell)].bottom_line;
 }
@@ -626,6 +648,8 @@ bool LyXTabular::bottomLine(idx_type const cell, bool onlycolumn) const
 
 bool LyXTabular::leftLine(idx_type cell, bool onlycolumn) const
 {
+       if (use_booktabs)
+               return false;
        if (!onlycolumn && isMultiColumn(cell) &&
                (isFirstCellInRow(cell) || isMultiColumn(cell-1)))
        {
@@ -641,6 +665,8 @@ bool LyXTabular::leftLine(idx_type cell, bool onlycolumn) const
 
 bool LyXTabular::rightLine(idx_type cell, bool onlycolumn) const
 {
+       if (use_booktabs)
+               return false;
        if (!onlycolumn && isMultiColumn(cell) &&
                (isLastCellInRow(cell) || isMultiColumn(cell + 1)))
        {
@@ -721,9 +747,12 @@ int LyXTabular::getAdditionalHeight(row_type row) const
                        top = row_info[row].top_line;
                }
        }
+       int const interline_space = row_info[row - 1].interline_space_default ?
+               default_line_space :
+               row_info[row - 1].interline_space.inPixels(width_of_tabular);
        if (top && bottom)
-               return WIDTH_OF_LINE;
-       return 0;
+               return interline_space + WIDTH_OF_LINE;
+       return interline_space;
 }
 
 
@@ -856,7 +885,7 @@ void LyXTabular::setWidthOfCell(idx_type cell, int new_width)
 
 
 void LyXTabular::setAlignment(idx_type cell, LyXAlignment align,
-                              bool onlycolumn)
+                             bool onlycolumn)
 {
        if (!isMultiColumn(cell) || onlycolumn)
                column_info[column_of_cell(cell)].alignment = align;
@@ -866,7 +895,7 @@ void LyXTabular::setAlignment(idx_type cell, LyXAlignment align,
 
 
 void LyXTabular::setVAlignment(idx_type cell, VAlignment align,
-                               bool onlycolumn)
+                              bool onlycolumn)
 {
        if (!isMultiColumn(cell) || onlycolumn)
                column_info[column_of_cell(cell)].valignment = align;
@@ -896,7 +925,9 @@ void toggleFixedWidth(LCursor & cur, InsetText * inset, bool fixedWidth)
 
        // reset layout
        cur.push(*inset);
-       inset->getText(0)->setLayout(0, cur.lastpit() + 1, "Standard");
+       // undo information has already been recorded
+       inset->getText(0)->setLayout(0, cur.lastpit() + 1,
+                       bp.getLyXTextClass().defaultLayoutName());
        cur.pop();
 }
 
@@ -913,7 +944,7 @@ void LyXTabular::setColumnPWidth(LCursor & cur, idx_type cell,
                idx_type const cell = getCellNumber(i, j);
                // because of multicolumns
                toggleFixedWidth(cur, getCellInset(cell).get(),
-                                !getPWidth(cell).zero());
+                                !getPWidth(cell).zero());
        }
        // cur paragraph can become invalid after paragraphs were merged
        if (cur.pit() > cur.lastpit())
@@ -1191,6 +1222,7 @@ void LyXTabular::write(Buffer const & buf, ostream & os) const
        // global longtable options
        os << "<features"
           << write_attribute("rotate", rotate)
+          << write_attribute("booktabs", use_booktabs)
           << write_attribute("islongtable", is_long_tabular)
           << write_attribute("firstHeadTopDL", endfirsthead.topDL)
           << write_attribute("firstHeadBottomDL", endfirsthead.bottomDL)
@@ -1216,8 +1248,21 @@ void LyXTabular::write(Buffer const & buf, ostream & os) const
        for (row_type i = 0; i < rows_; ++i) {
                os << "<row"
                   << write_attribute("topline", row_info[i].top_line)
-                  << write_attribute("bottomline", row_info[i].bottom_line)
-                  << write_attribute("endhead", row_info[i].endhead)
+                  << write_attribute("bottomline", row_info[i].bottom_line);
+               static const string def("default");
+               if (row_info[i].top_space_default)
+                       os << write_attribute("topspace", def);
+               else
+                       os << write_attribute("topspace", row_info[i].top_space);
+               if (row_info[i].bottom_space_default)
+                       os << write_attribute("bottomspace", def);
+               else
+                       os << write_attribute("bottomspace", row_info[i].bottom_space);
+               if (row_info[i].interline_space_default)
+                       os << write_attribute("interlinespace", def);
+               else
+                       os << write_attribute("interlinespace", row_info[i].interline_space);
+               os << write_attribute("endhead", row_info[i].endhead)
                   << write_attribute("endfirsthead", row_info[i].endfirsthead)
                   << write_attribute("endfoot", row_info[i].endfoot)
                   << write_attribute("endlastfoot", row_info[i].endlastfoot)
@@ -1279,6 +1324,7 @@ void LyXTabular::read(Buffer const & buf, LyXLex & lex)
                return;
        }
        getTokenValue(line, "rotate", rotate);
+       getTokenValue(line, "booktabs", use_booktabs);
        getTokenValue(line, "islongtable", is_long_tabular);
        getTokenValue(line, "firstHeadTopDL", endfirsthead.topDL);
        getTokenValue(line, "firstHeadBottomDL", endfirsthead.bottomDL);
@@ -1315,6 +1361,12 @@ void LyXTabular::read(Buffer const & buf, LyXLex & 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);
+               getTokenValue(line, "bottomspace", row_info[i].bottom_space,
+                             row_info[i].bottom_space_default);
+               getTokenValue(line, "interlinespace", row_info[i].interline_space,
+                             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);
@@ -1383,7 +1435,7 @@ LyXTabular::cellstruct & LyXTabular::cellinfo_of_cell(idx_type cell) const
 
 
 void LyXTabular::setMultiColumn(Buffer * buffer, idx_type cell,
-                                idx_type number)
+                               idx_type number)
 {
        cellstruct & cs = cellinfo_of_cell(cell);
        cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
@@ -1441,6 +1493,18 @@ LyXTabular::idx_type LyXTabular::unsetMultiColumn(idx_type cell)
 }
 
 
+void LyXTabular::setBookTabs(bool what)
+{
+       use_booktabs = what;
+}
+
+
+bool LyXTabular::useBookTabs() const
+{
+       return use_booktabs;
+}
+
+
 void LyXTabular::setLongTabular(bool what)
 {
        is_long_tabular = what;
@@ -1534,10 +1598,10 @@ LyXTabular::idx_type LyXTabular::getLastCellBelow(idx_type cell) const
 
 
 LyXTabular::idx_type LyXTabular::getCellNumber(row_type row,
-                                               col_type column) const
+                                              col_type column) const
 {
        BOOST_ASSERT(column != npos && column < columns_ &&
-                    row    != npos && row    < rows_);
+                    row    != npos && row    < rows_);
        return cell_info[row][column].cellno;
 }
 
@@ -1563,7 +1627,7 @@ LyXTabular::BoxType LyXTabular::getUsebox(idx_type cell) const
 //  This are functions used for the longtable support
 ///
 void LyXTabular::setLTHead(row_type row, bool flag, ltType const & hd,
-                           bool first)
+                          bool first)
 {
        if (first) {
                endfirsthead = hd;
@@ -1594,7 +1658,7 @@ bool LyXTabular::getRowOfLTFirstHead(row_type row, ltType & hd) const
 
 
 void LyXTabular::setLTFoot(row_type row, bool flag, ltType const & fd,
-                           bool last)
+                          bool last)
 {
        if (last) {
                endlastfoot = fd;
@@ -1741,12 +1805,14 @@ int LyXTabular::TeXTopHLine(ostream & os, row_type row) const
                if (topLine(i))
                        ++tmp;
        }
-       if (tmp == n - fcell) {
-               os << "\\hline ";
+       if (use_booktabs && row == 0) {
+               os << "\\toprule ";
+       } else if (tmp == n - fcell) {
+               os << (use_booktabs ? "\\midrule " : "\\hline ");
        } else if (tmp) {
                for (idx_type i = fcell; i < n; ++i) {
                        if (topLine(i)) {
-                               os << "\\cline{"
+                               os << (use_booktabs ? "\\cmidrule{" : "\\cline{")
                                   << column_of_cell(i) + 1
                                   << '-'
                                   << right_column_of_cell(i) + 1
@@ -1775,12 +1841,14 @@ int LyXTabular::TeXBottomHLine(ostream & os, row_type row) const
                if (bottomLine(i))
                        ++tmp;
        }
-       if (tmp == n - fcell) {
-               os << "\\hline";
+       if (use_booktabs && row == rows_ - 1) {
+               os << "\\bottomrule";
+       } else if (tmp == n - fcell) {
+               os << (use_booktabs ? "\\midrule" : "\\hline");
        } else if (tmp) {
                for (idx_type i = fcell; i < n; ++i) {
                        if (bottomLine(i)) {
-                               os << "\\cline{"
+                               os << (use_booktabs ? "\\cmidrule{" : "\\cline{")
                                   << column_of_cell(i) + 1
                                   << '-'
                                   << right_column_of_cell(i) + 1
@@ -2011,8 +2079,23 @@ int LyXTabular::TeXRow(ostream & os, row_type i, Buffer const & buf,
                       OutputParams const & runparams) const
 {
        idx_type cell = getCellNumber(i, 0);
-
        int ret = TeXTopHLine(os, i);
+       if (row_info[i].top_space_default) {
+               if (use_booktabs)
+                       os << "\\addlinespace\n";
+               else
+                       os << "\\noalign{\\vskip\\doublerulesep}\n";
+       } else if(!row_info[i].top_space.zero()) {
+               if (use_booktabs)
+                       os << "\\addlinespace["
+                          << row_info[i].top_space.asLatexString() << "]\n";
+               else {
+                       os << "\\noalign{\\vskip"
+                          << row_info[i].top_space.asLatexString() << "}\n";
+               }
+               ++ret;
+       }
+       
        for (col_type j = 0; j < columns_; ++j) {
                if (isPartOfMultiColumn(i, j))
                        continue;
@@ -2037,9 +2120,36 @@ int LyXTabular::TeXRow(ostream & os, row_type i, Buffer const & buf,
                }
                ++cell;
        }
-       os << "\\tabularnewline\n";
+       os << "\\tabularnewline";
+       if (row_info[i].bottom_space_default) {
+               if (use_booktabs)
+                       os << "\\addlinespace";
+               else
+                       os << "[\\doublerulesep]";
+       } else if (!row_info[i].bottom_space.zero()) {
+               if (use_booktabs)
+                       os << "\\addlinespace";
+               os << '[' << row_info[i].bottom_space.asLatexString() << ']';
+       }
+       os << '\n';
        ++ret;
        ret += TeXBottomHLine(os, i);
+       if (row_info[i].interline_space_default) {
+               if (use_booktabs)
+                       os << "\\addlinespace\n";
+               else
+                       os << "\\noalign{\\vskip\\doublerulesep}\n";
+       } else if (!row_info[i].interline_space.zero()) {
+               if (use_booktabs)
+                       os << "\\addlinespace["
+                          << row_info[i].interline_space.asLatexString()
+                          << "]\n";
+               else
+                       os << "\\noalign{\\vskip"
+                          << row_info[i].interline_space.asLatexString()
+                          << "}\n";
+               ++ret;
+       }
        return ret;
 }
 
@@ -2065,7 +2175,7 @@ int LyXTabular::latex(Buffer const & buf, ostream & os,
                if (!column_info[i].align_special.empty()) {
                        os << column_info[i].align_special;
                } else {
-                       if (column_info[i].left_line)
+                       if (!use_booktabs && column_info[i].left_line)
                                os << '|';
                        if (!column_info[i].p_width.zero()) {
                                switch (column_info[i].alignment) {
@@ -2112,7 +2222,7 @@ int LyXTabular::latex(Buffer const & buf, ostream & os,
                                        break;
                                }
                        }
-                       if (column_info[i].right_line)
+                       if (!use_booktabs && column_info[i].right_line)
                                os << '|';
                }
        }
@@ -2152,48 +2262,6 @@ int LyXTabular::latex(Buffer const & buf, ostream & os,
 }
 
 
-int LyXTabular::linuxdoc(Buffer const & buf, ostream & os,
-                        const OutputParams & runparams) const
-{
-       os << "<tabular ca=\"";
-       for (col_type i = 0; i < columns_; ++i) {
-               switch (column_info[i].alignment) {
-               case LYX_ALIGN_LEFT:
-                       os << 'l';
-                       break;
-               case LYX_ALIGN_RIGHT:
-                       os << 'r';
-                       break;
-               default:
-                       os << 'c';
-                       break;
-               }
-       }
-       os << "\">\n";
-       idx_type cell = 0;
-       int ret = 0;
-       for (row_type i = 0; i < rows_; ++i) {
-               for (col_type j = 0; j < columns_; ++j) {
-                       if (isPartOfMultiColumn(i, j))
-                               continue;
-                       shared_ptr<InsetText> inset = getCellInset(cell);
-
-                       ret += inset->linuxdoc(buf, os, runparams);
-
-                       if (isLastCellInRow(cell)) {
-                               os << "@\n";
-                               ++ret;
-                       } else {
-                               os << "|";
-                       }
-                       ++cell;
-               }
-       }
-       os << "</tabular>\n";
-       return ret;
-}
-
-
 int LyXTabular::docbookRow(Buffer const & buf, ostream & os, row_type row,
                           OutputParams const & runparams) const
 {
@@ -2551,7 +2619,7 @@ shared_ptr<InsetText> LyXTabular::getCellInset(idx_type cell) const
 
 
 shared_ptr<InsetText> LyXTabular::getCellInset(row_type row,
-                                               col_type column) const
+                                              col_type column) const
 {
        return cell_info[row][column].inset;
 }
@@ -2592,6 +2660,8 @@ LyXTabular::getCellFromInset(InsetBase const * inset) const
 void LyXTabular::validate(LaTeXFeatures & features) const
 {
        features.require("NeedTabularnewline");
+       if (useBookTabs())
+               features.require("booktabs");
        if (isLongTabular())
                features.require("longtable");
        if (needRotating())
@@ -2605,15 +2675,6 @@ void LyXTabular::validate(LaTeXFeatures & features) const
 }
 
 
-void LyXTabular::getLabelList(Buffer const & buffer,
-                             std::vector<string> & list) const
-{
-       for (row_type i = 0; i < rows_; ++i)
-               for (col_type j = 0; j < columns_; ++j)
-                       getCellInset(i, j)->getLabelList(buffer, list);
-}
-
-
 LyXTabular::BoxType LyXTabular::useParbox(idx_type cell) const
 {
        ParagraphList const & parlist = getCellInset(cell)->paragraphs();