]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
Fix GRAPHICS_EDIT of InsetGraphics
[lyx.git] / src / insets / InsetTabular.cpp
index 6a5ae84361a2a83e7f7cd5ae3df39d78bf3c73d4..aeb3e7eb4c371be8785c5dec033969c791114e07 100644 (file)
@@ -3,7 +3,6 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author Jürgen Vigna
  * \author Lars Gullik Bjønnes
  * \author Matthias Ettrich
  * \author José Matos
@@ -157,6 +156,7 @@ TabularFeature tabularFeature[] =
        { Tabular::SET_TOP_SPACE, "set-top-space" },
        { Tabular::SET_BOTTOM_SPACE, "set-bottom-space" },
        { Tabular::SET_INTERLINE_SPACE, "set-interline-space" },
+       { Tabular::SET_BORDER_LINES, "set-border-lines" },
        { Tabular::LAST_ACTION, "" }
 };
 
@@ -469,7 +469,7 @@ string const featureAsString(Tabular::Feature feature)
 /////////////////////////////////////////////////////////////////////
 
 
-Tabular::CellData::CellData(Buffer const & buf)
+Tabular::CellData::CellData(Buffer const & buf, Tabular const & table)
        : cellno(0),
          width(0),
          multicolumn(Tabular::CELL_NORMAL),
@@ -481,7 +481,7 @@ Tabular::CellData::CellData(Buffer const & buf)
          right_line(false),
          usebox(BOX_NONE),
          rotate(false),
-         inset(new InsetText(buf))
+         inset(new InsetTableCell(buf, this, &table))
 {
        inset->setBuffer(const_cast<Buffer &>(buf));
        inset->paragraphs().back().setLayout(buf.params().documentClass().emptyLayout());
@@ -502,8 +502,10 @@ Tabular::CellData::CellData(CellData const & cs)
          rotate(cs.rotate),
          align_special(cs.align_special),
          p_width(cs.p_width),
-         inset(dynamic_cast<InsetText*>(cs.inset->clone()))
-{}
+         inset(dynamic_cast<InsetTableCell *>(cs.inset->clone()))
+{
+       inset->setCellData(this);
+}
 
 
 Tabular::CellData & Tabular::CellData::operator=(CellData cs)
@@ -580,7 +582,7 @@ void Tabular::init(Buffer const & buf, row_type rows_arg,
        buffer_ = &buf;
        row_info = row_vector(rows_arg);
        column_info = column_vector(columns_arg);
-       cell_info = cell_vvector(rows_arg, cell_vector(columns_arg, CellData(buf)));
+       cell_info = cell_vvector(rows_arg, cell_vector(columns_arg, CellData(buf, *this)));
        row_info.reserve(10);
        column_info.reserve(10);
        cell_info.reserve(100);
@@ -627,7 +629,7 @@ void Tabular::appendRow(idx_type const cell)
        for (row_type i = 0; i < nrows - 1; ++i)
                swap(cell_info[i], old[i]);
 
-       cell_info = cell_vvector(nrows, cell_vector(ncols, CellData(buffer())));
+       cell_info = cell_vvector(nrows, cell_vector(ncols, CellData(buffer(), *this)));
 
        for (row_type i = 0; i <= row; ++i)
                swap(cell_info[i], old[i]);
@@ -677,7 +679,7 @@ void Tabular::appendColumn(idx_type const cell)
        column_info[column + 1] = column_info[column];
 
        for (row_type i = 0; i < rowCount(); ++i) {
-               cell_info[i].insert(cell_info[i].begin() + column + 1, CellData(buffer()));
+               cell_info[i].insert(cell_info[i].begin() + column + 1, CellData(buffer(), *this));
                col_type c = column + 2;
                while (c < ncols 
                        && cell_info[i][c].multicolumn == CELL_PART_OF_MULTICOLUMN) {
@@ -759,8 +761,8 @@ void Tabular::updateIndexes()
                do {
                        ++column;
                } while (column < columnCount() &&
-                                cell_info[row][column].multicolumn
-                                == Tabular::CELL_PART_OF_MULTICOLUMN);
+                               cell_info[row][column].multicolumn
+                                               == Tabular::CELL_PART_OF_MULTICOLUMN);
 
                if (column == columnCount()) {
                        column = 0;
@@ -1017,7 +1019,7 @@ namespace {
  * merge cell paragraphs and reset layout to standard for variable width
  * cells.
  */
-void toggleFixedWidth(Cursor & cur, InsetText * inset, bool fixedWidth)
+void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
 {
        inset->setAutoBreakRows(fixedWidth);
        if (fixedWidth)
@@ -1695,26 +1697,6 @@ Tabular::idx_type Tabular::getCellBelow(idx_type cell) const
 }
 
 
-Tabular::idx_type Tabular::getLastCellAbove(idx_type cell) const
-{
-       if (cellRow(cell) == 0)
-               return cell;
-       if (!isMultiColumn(cell))
-               return getCellAbove(cell);
-       return cell_info[cellRow(cell) - 1][cellRightColumn(cell)].cellno;
-}
-
-
-Tabular::idx_type Tabular::getLastCellBelow(idx_type cell) const
-{
-       if (cellRow(cell) + 1 >= rowCount())
-               return cell;
-       if (!isMultiColumn(cell))
-               return getCellBelow(cell);
-       return cell_info[cellRow(cell) + 1][cellRightColumn(cell)].cellno;
-}
-
-
 Tabular::idx_type Tabular::cellIndex(row_type row,
                                               col_type column) const
 {
@@ -2225,7 +2207,7 @@ int Tabular::TeXRow(odocstream & os, row_type i,
                if (isPartOfMultiColumn(i, j))
                        continue;
                ret += TeXCellPreamble(os, cell);
-               shared_ptr<InsetText> inset = getCellInset(cell);
+               shared_ptr<InsetTableCell> inset = getCellInset(cell);
 
                Paragraph const & par = inset->paragraphs().front();
                bool rtl = par.isRTL(buffer().params())
@@ -2742,13 +2724,13 @@ void Tabular::plaintext(odocstream & os,
 }
 
 
-shared_ptr<InsetText> Tabular::getCellInset(idx_type cell) const
+shared_ptr<InsetTableCell> Tabular::getCellInset(idx_type cell) const
 {
        return cell_info[cellRow(cell)][cellColumn(cell)].inset;
 }
 
 
-shared_ptr<InsetText> Tabular::getCellInset(row_type row,
+shared_ptr<InsetTableCell> Tabular::getCellInset(row_type row,
                                               col_type column) const
 {
        return cell_info[row][column].inset;
@@ -2756,9 +2738,13 @@ shared_ptr<InsetText> Tabular::getCellInset(row_type row,
 
 
 void Tabular::setCellInset(row_type row, col_type column,
-                             shared_ptr<InsetText> ins) const
+                             shared_ptr<InsetTableCell> ins) const
 {
-       cell_info[row][column].inset = ins;
+       CellData & cd = cell_info[row][column];
+       cd.inset = ins;
+       // reset the InsetTableCell's pointers
+       ins->setCellData(&cd);
+       ins->setTabular(this);
 }
 
 
@@ -2820,6 +2806,50 @@ Tabular::BoxType Tabular::useParbox(idx_type cell) const
 }
 
 
+/////////////////////////////////////////////////////////////////////
+//
+// InsetTableCell
+//
+/////////////////////////////////////////////////////////////////////
+
+InsetTableCell::InsetTableCell(Buffer const & buf,
+       Tabular::CellData const * cell, Tabular const * table)
+       : InsetText(buf), cell_data_(cell), table_(table)
+{}
+
+
+bool InsetTableCell::forceEmptyLayout(idx_type) const
+{
+       BOOST_ASSERT(table_);
+       BOOST_ASSERT(cell_data_);
+       return table_->getPWidth(cell_data_->cellno).zero();
+}
+
+bool InsetTableCell::allowParagraphCustomization(idx_type) const
+{
+       BOOST_ASSERT(table_);
+       BOOST_ASSERT(cell_data_);
+       return !table_->getPWidth(cell_data_->cellno).zero();
+}
+
+bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
+       FuncStatus & status) const
+{
+       bool enabled;
+       switch (cmd.action) {
+       case LFUN_LAYOUT:
+               enabled = !forceEmptyLayout();
+               break;
+       case LFUN_LAYOUT_PARAGRAPH:
+               enabled = allowParagraphCustomization();
+               break;
+       default:
+               return InsetText::getStatus(cur, cmd, status);
+       }
+       status.enabled(enabled);
+       return true;
+}
+
 /////////////////////////////////////////////////////////////////////
 //
 // InsetTabular
@@ -3221,7 +3251,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                    && tablemode(bvcur)) 
                        ;
                else
-                       // Let InsetText do it
+                       // Let InsetTableCell do it
                        cell(cur.idx())->dispatch(cur, cmd);
                break;
        }
@@ -3607,6 +3637,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                case Tabular::SET_TOP_SPACE:
                case Tabular::SET_BOTTOM_SPACE:
                case Tabular::SET_INTERLINE_SPACE:
+               case Tabular::SET_BORDER_LINES:
                        status.clear();
                        return true;
 
@@ -3869,13 +3900,13 @@ void InsetTabular::validate(LaTeXFeatures & features) const
 }
 
 
-shared_ptr<InsetText const> InsetTabular::cell(idx_type idx) const
+shared_ptr<InsetTableCell const> InsetTabular::cell(idx_type idx) const
 {
        return tabular.getCellInset(idx);
 }
 
 
-shared_ptr<InsetText> InsetTabular::cell(idx_type idx)
+shared_ptr<InsetTableCell> InsetTabular::cell(idx_type idx)
 {
        return tabular.getCellInset(idx);
 }
@@ -4343,6 +4374,17 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                                        tabular.cellIndex(i,j), setLines);
                break;
 
+       case Tabular::SET_BORDER_LINES:
+               for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+                       tabular.setLeftLine(tabular.cellIndex(i, sel_col_start), true);
+                       tabular.setRightLine(tabular.cellIndex(i, sel_col_end), true);
+               }
+               for (col_type j = sel_col_start; j <= sel_col_end; ++j) {
+                       tabular.setTopLine(tabular.cellIndex(sel_row_start, j), true);
+                       tabular.setBottomLine(tabular.cellIndex(sel_row_end, j), true);
+               }
+               break;
+
        case Tabular::SET_LONGTABULAR:
                tabular.setLongTabular(true);
                break;
@@ -4541,6 +4583,15 @@ bool InsetTabular::copySelection(Cursor & cur)
        while (paste_tabular->columnCount() > columns)
                paste_tabular->deleteColumn(columns);
 
+       // We clear all the InsetTableCell pointers, since they
+       // might now become invalid and there is no point in having
+       // them point to temporary things in paste_tabular.
+       for (row_type i = 0; i < paste_tabular->rowCount(); ++i)
+               for (col_type j = 0; j < paste_tabular->columnCount(); ++j) {
+                       paste_tabular->getCellInset(i,j)->setCellData(0);
+                       paste_tabular->getCellInset(i,j)->setTabular(0);
+               }
+
        odocstringstream os;
        OutputParams const runparams(0);
        paste_tabular->plaintext(os, runparams, 0, true, '\t');
@@ -4580,8 +4631,10 @@ bool InsetTabular::pasteClipboard(Cursor & cur)
                                --c1;
                                continue;
                        }
-                       shared_ptr<InsetText> inset(
-                               new InsetText(*paste_tabular->getCellInset(r1, c1)));
+                       shared_ptr<InsetTableCell> inset(
+                               new InsetTableCell(*paste_tabular->getCellInset(r1, c1)));
+                       // note that setCellInset will call InsetTableCell::setCellData()
+                       // and InsetTableCell::setTabular()
                        tabular.setCellInset(r2, c2, inset);
                        // FIXME: change tracking (MG)
                        inset->setChange(Change(cur.buffer().params().trackChanges ?
@@ -4603,7 +4656,7 @@ void InsetTabular::cutSelection(Cursor & cur)
        getSelection(cur, rs, re, cs, ce);
        for (row_type i = rs; i <= re; ++i) {
                for (col_type j = cs; j <= ce; ++j) {
-                       shared_ptr<InsetText> t
+                       shared_ptr<InsetTableCell> t
                                = cell(tabular.cellIndex(i, j));
                        if (cur.buffer().params().trackChanges)
                                // FIXME: Change tracking (MG)
@@ -4752,7 +4805,7 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
                case '\t':
                        // we can only set this if we are not too far right
                        if (cols < columns) {
-                               shared_ptr<InsetText> inset = loctab->getCellInset(cell);
+                               shared_ptr<InsetTableCell> inset = loctab->getCellInset(cell);
                                Font const font = bv.textMetrics(&inset->text_).
                                        displayFont(0, 0);
                                inset->setText(buf.substr(op, p - op), font,
@@ -4764,7 +4817,7 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
                case '\n':
                        // we can only set this if we are not too far right
                        if (cols < columns) {
-                               shared_ptr<InsetText> inset = tabular.getCellInset(cell);
+                               shared_ptr<InsetTableCell> inset = tabular.getCellInset(cell);
                                Font const font = bv.textMetrics(&inset->text_).
                                        displayFont(0, 0);
                                inset->setText(buf.substr(op, p - op), font,
@@ -4781,7 +4834,7 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
        }
        // check for the last cell if there is no trailing '\n'
        if (cell < cells && op < len) {
-               shared_ptr<InsetText> inset = loctab->getCellInset(cell);
+               shared_ptr<InsetTableCell> inset = loctab->getCellInset(cell);
                Font const font = bv.textMetrics(&inset->text_).displayFont(0, 0);
                inset->setText(buf.substr(op, len - op), font,
                        buffer().params().trackChanges);