]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
Comments.
[lyx.git] / src / insets / InsetTabular.cpp
index 132a3ee656e6f04c6eb5b0406fa8aeff9deecce2..3cd8213b3a130d7d3501213015c488a3e008d432 100644 (file)
@@ -188,62 +188,6 @@ TabularFeature tabularFeature[] =
 };
 
 
-template <class T>
-string const write_attribute(string const & name, T const & t)
-{
-       string const s = tostr(t);
-       return s.empty() ? s : " " + name + "=\"" + s + "\"";
-}
-
-template <>
-string const write_attribute(string const & name, string const & t)
-{
-       return t.empty() ? t : " " + name + "=\"" + t + "\"";
-}
-
-
-template <>
-string const write_attribute(string const & name, docstring const & t)
-{
-       return t.empty() ? string() : " " + name + "=\"" + to_utf8(t) + "\"";
-}
-
-
-template <>
-string const write_attribute(string const & name, bool const & b)
-{
-       // we write only true attribute values so we remove a bit of the
-       // file format bloat for tabulars.
-       return b ? write_attribute(name, convert<string>(b)) : string();
-}
-
-
-template <>
-string const write_attribute(string const & name, int const & i)
-{
-       // we write only true attribute values so we remove a bit of the
-       // file format bloat for tabulars.
-       return i ? write_attribute(name, convert<string>(i)) : string();
-}
-
-
-template <>
-string const write_attribute(string const & name, Tabular::idx_type const & i)
-{
-       // we write only true attribute values so we remove a bit of the
-       // file format bloat for tabulars.
-       return i ? write_attribute(name, convert<string>(i)) : string();
-}
-
-
-template <>
-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());
-}
-
-
 string const tostr(LyXAlignment const & num)
 {
        switch (num) {
@@ -503,6 +447,61 @@ void l_getline(istream & is, string & str)
        }
 }
 
+template <class T>
+string const write_attribute(string const & name, T const & t)
+{
+       string const s = tostr(t);
+       return s.empty() ? s : " " + name + "=\"" + s + "\"";
+}
+
+template <>
+string const write_attribute(string const & name, string const & t)
+{
+       return t.empty() ? t : " " + name + "=\"" + t + "\"";
+}
+
+
+template <>
+string const write_attribute(string const & name, docstring const & t)
+{
+       return t.empty() ? string() : " " + name + "=\"" + to_utf8(t) + "\"";
+}
+
+
+template <>
+string const write_attribute(string const & name, bool const & b)
+{
+       // we write only true attribute values so we remove a bit of the
+       // file format bloat for tabulars.
+       return b ? write_attribute(name, convert<string>(b)) : string();
+}
+
+
+template <>
+string const write_attribute(string const & name, int const & i)
+{
+       // we write only true attribute values so we remove a bit of the
+       // file format bloat for tabulars.
+       return i ? write_attribute(name, convert<string>(i)) : string();
+}
+
+
+template <>
+string const write_attribute(string const & name, Tabular::idx_type const & i)
+{
+       // we write only true attribute values so we remove a bit of the
+       // file format bloat for tabulars.
+       return i ? write_attribute(name, convert<string>(i)) : string();
+}
+
+
+template <>
+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());
+}
+
 } // namespace
 
 
@@ -1615,7 +1614,8 @@ Tabular::CellData & Tabular::cellInfo(idx_type cell) const
 }
 
 
-Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number)
+Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
+                                         bool const right_border)
 {
        idx_type const col = cellColumn(cell);
        idx_type const row = cellRow(cell);
@@ -1629,7 +1629,7 @@ Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number)
        if (column_info[col].alignment != LYX_ALIGN_DECIMAL)
                cs.alignment = column_info[col].alignment;
        if (col > 0)
-               setRightLine(cell, rightLine(cellIndex(row, col - 1)));
+               setRightLine(cell, right_border);
 
        for (idx_type i = 1; i < number; ++i) {
                CellData & cs1 = cellInfo(cell + i);
@@ -1649,7 +1649,8 @@ bool Tabular::isMultiRow(idx_type cell) const
 }
 
 
-Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number)
+Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number,
+                                      bool const bottom_border)
 {
        idx_type const col = cellColumn(cell);
        idx_type const row = cellRow(cell);
@@ -1668,10 +1669,10 @@ Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number)
        // this feature would be a fileformat change
        // until LyX supports this, use the deault alignment of multirow
        // cells: left
-       cs.alignment = LYX_ALIGN_LEFT; 
+       cs.alignment = LYX_ALIGN_LEFT;
 
-       // set the bottom row of the last selected cell
-       setBottomLine(cell, bottomLine(cell + (number - 1)*ncols()));
+       // set the bottom line of the last selected cell
+       setBottomLine(cell, bottom_border);
 
        for (idx_type i = 1; i < number; ++i) {
                CellData & cs1 = cell_info[row + i][col];
@@ -1953,7 +1954,7 @@ Tabular::idx_type Tabular::setLTCaption(row_type row, bool what)
 {
        idx_type i = getFirstCellInRow(row);
        if (what) {
-               setMultiColumn(i, numberOfCellsInRow(row));
+               setMultiColumn(i, numberOfCellsInRow(row), false);
                setTopLine(i, false);
                setBottomLine(i, false);
                setLeftLine(i, false);
@@ -2057,8 +2058,8 @@ void Tabular::TeXTopHLine(otexstream & os, row_type row, string const lang) cons
                // multirow, no line must be drawn.
                if (row != 0)
                        if (isMultiRow(cellIndex(row, c))
-                               && isMultiRow(cellIndex(row - 1, c)))
-                                       topline[c] = false;
+                           && cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW)
+                               topline[c] = false;
                if (topline[c])
                        ++nset;
        }
@@ -2117,13 +2118,14 @@ void Tabular::TeXBottomHLine(otexstream & os, row_type row, string const lang) c
        for (col_type c = 0; c < ncols(); ++c) {
                bottomline.push_back(bottomLine(cellIndex(row, c)));
                topline.push_back(!lastrow && topLine(cellIndex(row + 1, c)));
-               // If cell is part of a multirow and not the last or first cell of the
+               // If cell is part of a multirow and not the last cell of the
                // multirow, no line must be drawn.
                if (!lastrow)
                        if (isMultiRow(cellIndex(row, c))
-                               && isMultiRow(cellIndex(row + 1, c))) {
-                                       bottomline[c] = false;
-                                       topline[c] = false;
+                           && isMultiRow(cellIndex(row + 1, c))
+                           && cell_info[row + 1][c].multirow != CELL_BEGIN_OF_MULTIROW) {
+                               bottomline[c] = false;
+                               topline[c] = false;
                                }
                nextrowset &= topline[c];
        }
@@ -3397,7 +3399,7 @@ void InsetTabular::write(ostream & os) const
 }
 
 
-docstring InsetTabular::contextMenu(BufferView const &, int, int) const
+string InsetTabular::contextMenu(BufferView const &, int, int) const
 {
        // FIXME: depending on the selection state,
        // we could offer a different menu.
@@ -3405,9 +3407,9 @@ docstring InsetTabular::contextMenu(BufferView const &, int, int) const
 }
 
 
-docstring InsetTabular::contextMenuName() const
+string InsetTabular::contextMenuName() const
 {
-       return from_ascii("context-tabular");
+       return "context-tabular";
 }
 
 
@@ -5362,7 +5364,8 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                        // just multicol for one single cell
                        // check whether we are completely in a multicol
                        if (!tabular.isMultiColumn(cur.idx()))
-                               tabular.setMultiColumn(cur.idx(), 1);
+                               tabular.setMultiColumn(cur.idx(), 1,
+                                       tabular.rightLine(cur.idx()));
                        break;
                }
                // we have a selection so this means we just add all this
@@ -5370,7 +5373,8 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                idx_type const s_start = cur.selBegin().idx();
                row_type const col_start = tabular.cellColumn(s_start);
                row_type const col_end = tabular.cellColumn(cur.selEnd().idx());
-               cur.idx() = tabular.setMultiColumn(s_start, col_end - col_start + 1);
+               cur.idx() = tabular.setMultiColumn(s_start, col_end - col_start + 1,
+                                                  tabular.rightLine(cur.selEnd().idx()));
                cur.pit() = 0;
                cur.pos() = 0;
                cur.setSelection(false);
@@ -5386,10 +5390,27 @@ void InsetTabular::tabularFeatures(Cursor & cur,
        }
 
        case Tabular::MULTICOLUMN: {
-               if (tabular.isMultiColumn(cur.idx()))
-                       tabularFeatures(cur, Tabular::UNSET_MULTICOLUMN);
-               else
+               if (!cur.selection()) {
+                       if (tabular.isMultiColumn(cur.idx()))
+                               tabularFeatures(cur, Tabular::UNSET_MULTICOLUMN);
+                       else
+                               tabularFeatures(cur, Tabular::SET_MULTICOLUMN);
+                       break;
+               }
+               bool merge = false;
+               for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
+                       row_type const r = sel_row_start;
+                       if (!tabular.isMultiColumn(tabular.cellIndex(r, c))
+                           || (r > sel_row_start && !tabular.isPartOfMultiColumn(r, c)))
+                               merge = true;
+               }
+               // If the selection contains at least one singlecol cell
+               // or multiple multicol cells,
+               // we assume the user will merge is to a single multicol
+               if (merge)
                        tabularFeatures(cur, Tabular::SET_MULTICOLUMN);
+               else
+                       tabularFeatures(cur, Tabular::UNSET_MULTICOLUMN);
                break;
        }
 
@@ -5398,7 +5419,8 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                        // just multirow for one single cell
                        // check whether we are completely in a multirow
                        if (!tabular.isMultiRow(cur.idx()))
-                               tabular.setMultiRow(cur.idx(), 1);
+                               tabular.setMultiRow(cur.idx(), 1,
+                                                   tabular.bottomLine(cur.idx()));
                        break;
                }
                // we have a selection so this means we just add all this
@@ -5406,7 +5428,8 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                idx_type const s_start = cur.selBegin().idx();
                row_type const row_start = tabular.cellRow(s_start);
                row_type const row_end = tabular.cellRow(cur.selEnd().idx());
-               cur.idx() = tabular.setMultiRow(s_start, row_end - row_start + 1);
+               cur.idx() = tabular.setMultiRow(s_start, row_end - row_start + 1,
+                                               tabular.bottomLine(cur.selEnd().idx()));
                cur.pit() = 0;
                cur.pos() = 0;
                cur.setSelection(false);
@@ -5422,10 +5445,27 @@ void InsetTabular::tabularFeatures(Cursor & cur,
        }
 
        case Tabular::MULTIROW: {
-               if (tabular.isMultiRow(cur.idx()))
-                       tabularFeatures(cur, Tabular::UNSET_MULTIROW);
-               else
+               if (!cur.selection()) {
+                       if (tabular.isMultiRow(cur.idx()))
+                               tabularFeatures(cur, Tabular::UNSET_MULTIROW);
+                       else
+                               tabularFeatures(cur, Tabular::SET_MULTIROW);
+                       break;
+               }
+               bool merge = false;
+               for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
+                       col_type const c = sel_col_start;
+                       if (!tabular.isMultiRow(tabular.cellIndex(r, c))
+                           || (r > sel_row_start && !tabular.isPartOfMultiRow(r, c)))
+                               merge = true;
+               }
+               // If the selection contains at least one singlerow cell
+               // or multiple multirow cells,
+               // we assume the user will merge is to a single multirow
+               if (merge)
                        tabularFeatures(cur, Tabular::SET_MULTIROW);
+               else
+                       tabularFeatures(cur, Tabular::UNSET_MULTIROW);
                break;
        }