From b922cfd3b351683fa452eeec4830258d72d47ab8 Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Fri, 21 Mar 2008 17:45:14 +0000 Subject: [PATCH] Another attempt at 2178. This is a "minimal" patch designed to fix the bug with the minimum amount of new code. A better fix, suggested by Andre, would merge InsetTableCell and CellData into one class, in which case InsetTableCell::cell_data_ can be removed. A definite plus. I'll do that later if this works. But let's get it right first. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23879 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Paragraph.cpp | 29 ++----------- src/insets/Inset.cpp | 1 + src/insets/InsetCode.h | 2 + src/insets/InsetTabular.cpp | 82 ++++++++++++++++++++++++++++++++----- src/insets/InsetTabular.h | 52 +++++++++++++++++++---- src/insets/InsetText.cpp | 16 -------- src/insets/InsetText.h | 4 -- 7 files changed, 120 insertions(+), 66 deletions(-) diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 18b73346b9..6aeab1aa7d 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -48,8 +48,6 @@ #include "insets/InsetBibitem.h" #include "insets/InsetLabel.h" -// needed only for inTableCell() -#include "insets/InsetText.h" #include "support/convert.h" #include "support/debug.h" @@ -1621,7 +1619,6 @@ bool Paragraph::forceEmptyLayout() const Inset const * const inset = inInset(); if (!inset) return true; - // FIXME At present, this is wrong for table cells return inset->forceEmptyLayout(); } @@ -1631,36 +1628,16 @@ bool Paragraph::allowParagraphCustomization() const Inset const * const inset = inInset(); if (!inset) return true; - // FIXME At present, this is wrong for table cells return inset->allowParagraphCustomization(); } -namespace { - // FIXME - // This is a hack based upon one in InsetText::neverIndent(). - // When we have a real InsetTableCell, then we won't need this - // method, because InsetTableCell will return the right values, - // viz: InsetTableCell::useEmptyLayout() should return true, and - // InsetTableCell::forceEmptyLayout() should still return true - // unless the width has been set. - // - // The #include "insets/InsetText.h" can also be removed then. - bool inTableCell(Inset const * inset) - { - InsetText const * txt = inset->asInsetText(); - if (!txt) - return false; - return txt->isTableCell(); - } -} - - bool Paragraph::useEmptyLayout() const { Inset const * const inset = inInset(); - return inset && - (inTableCell(inset) || inset->useEmptyLayout()); + if (!inset) + return false; + return inset->useEmptyLayout(); } diff --git a/src/insets/Inset.cpp b/src/insets/Inset.cpp index 96466d32d9..cb689077e4 100644 --- a/src/insets/Inset.cpp +++ b/src/insets/Inset.cpp @@ -105,6 +105,7 @@ static TranslatorMap const build_translator() InsetName("info", INFO_CODE), InsetName("collapsable", COLLAPSABLE_CODE), InsetName("newpage", NEWPAGE_CODE), + InsetName("tablecell", CELL_CODE) }; size_t const insetnames_size = diff --git a/src/insets/InsetCode.h b/src/insets/InsetCode.h index a2f5afd977..95543f9d7b 100644 --- a/src/insets/InsetCode.h +++ b/src/insets/InsetCode.h @@ -112,6 +112,8 @@ enum InsetCode { INFO_CODE, // 45 /// COLLAPSABLE_CODE, + /// + CELL_CODE, #if 0 /// THEOREM_CODE, diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 2115fbb94b..aeb3e7eb4c 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -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 @@ -470,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), @@ -482,7 +481,7 @@ Tabular::CellData::CellData(Buffer const & buf) right_line(false), usebox(BOX_NONE), rotate(false), - inset(new InsetTableCell(buf)) + inset(new InsetTableCell(buf, this, &table)) { inset->setBuffer(const_cast(buf)); inset->paragraphs().back().setLayout(buf.params().documentClass().emptyLayout()); @@ -503,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(cs.inset->clone())) -{} + inset(dynamic_cast(cs.inset->clone())) +{ + inset->setCellData(this); +} Tabular::CellData & Tabular::CellData::operator=(CellData cs) @@ -581,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); @@ -628,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]); @@ -678,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) { @@ -760,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; @@ -2739,7 +2740,11 @@ shared_ptr Tabular::getCellInset(row_type row, void Tabular::setCellInset(row_type row, col_type column, shared_ptr 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); } @@ -2801,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 @@ -4534,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'); @@ -4575,6 +4633,8 @@ bool InsetTabular::pasteClipboard(Cursor & cur) } shared_ptr 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 ? diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index 9f7ed5bb23..f71a9e5985 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -4,7 +4,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 André Pönitz @@ -49,14 +48,15 @@ namespace lyx { -class FuncStatus; -class Lexer; -class BufferView; class Buffer; class BufferParams; -class Paragraph; +class BufferView; class CompletionList; class CursorSlice; +class InsetTableCell; +class FuncStatus; +class Lexer; +class Paragraph; namespace frontend { class Painter; } @@ -65,8 +65,6 @@ class InsetTabular; class Cursor; class OutputParams; -typedef InsetText InsetTableCell; - // // A helper struct for tables // @@ -463,7 +461,7 @@ public: class CellData { public: /// - CellData(Buffer const &); + CellData(Buffer const &, Tabular const &); /// CellData(CellData const &); /// @@ -658,9 +656,45 @@ private: /// renumber cells after structural changes void fixCellNums(); -}; +}; // Tabular +/// +class InsetTableCell : public InsetText { +public: + /// + explicit InsetTableCell(Buffer const & buf, + Tabular::CellData const * cd, Tabular const * t); + /// + virtual InsetCode lyxCode() const { return CELL_CODE; } + /// + Inset * clone() { return new InsetTableCell(*this); } + /// + virtual bool useEmptyLayout() const { return true; } + /// + virtual bool forceEmptyLayout(idx_type = 0) const; + /// + virtual bool allowParagraphCustomization(idx_type = 0) const; + /// + bool getStatus(Cursor & cur, FuncRequest const & cmd, + FuncStatus & status) const; + /// + virtual bool neverIndent() { return true; } + /// + void setCellData(Tabular::CellData const * cd) { cell_data_ = cd; } + /// + void setTabular(Tabular const * t) { table_ = t; } +private: + /// + Tabular::CellData const * cell_data_; + /// + Tabular const * table_; + /// unimplemented + InsetTableCell(); + /// unimplemented + void operator=(InsetTableCell const &); +}; + class InsetTabular : public Inset { public: diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index d556b2898d..06105c83e5 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -412,22 +412,6 @@ void InsetText::addPreview(PreviewLoader & loader) const } -// FIXME: instead of this hack, which only works by chance, -// cells should have their own insetcell type, which returns CELL_CODE! -bool InsetText::isTableCell() const -{ - // this is only true for tabular cells - return !text_.isMainText(buffer()) && lyxCode() == TEXT_CODE; -} - - - -bool InsetText::neverIndent() const -{ - return isTableCell(); -} - - ParagraphList const & InsetText::paragraphs() const { return text_.paragraphs(); diff --git a/src/insets/InsetText.h b/src/insets/InsetText.h index 8168a71f5d..afb874a442 100644 --- a/src/insets/InsetText.h +++ b/src/insets/InsetText.h @@ -130,10 +130,6 @@ public: /// bool allowSpellCheck() const { return true; } /// - bool isTableCell() const; - /// should paragraph indendation be ommitted in any case? - bool neverIndent() const; - /// virtual bool isMacroScope() const { return false; } /// virtual bool allowMultiPar() const { return true; }