OK, here's my attempt once again to fix bug 2178. I've tested this a bit, but I'm not an extensive user of tables, so I'm sure there are bugs here. But the general idea seems to work.

Note that this is intended to be a "minimal patch", involving as few changes as possible to the existing code. It may well be that there are better ways to do this, longer term, but I am NOT about to start messing with the InsetTabular code in any serious way. The list of names at the start of InsetTabular.cpp is enough to scare me off for good. ;-)

Comments welcome.

rh

Index: src/insets/InsetTableCell.h
===================================================================
--- src/insets/InsetTableCell.h	(revision 0)
+++ src/insets/InsetTableCell.h	(revision 0)
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+/**
+ * \file InsetTableCell.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef INSETTABLECELL_H
+#define INSETTABLECELL_H
+
+#include "InsetTabular.h"
+#include "InsetText.h"
+#include <boost/assert.hpp>
+
+namespace lyx {
+
+
+///
+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 &);
+};
+
+} // namespace lyx
+
+#endif
Index: src/insets/InsetTableCell.cpp
===================================================================
--- src/insets/InsetTableCell.cpp	(revision 0)
+++ src/insets/InsetTableCell.cpp	(revision 0)
@@ -0,0 +1,61 @@
+/**
+ * \file InsetTableCell.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "InsetTableCell.h"
+
+#include "FuncRequest.h"
+#include "FuncStatus.h"
+#include "InsetTabular.h"
+
+#include <boost/assert.hpp>
+
+namespace lyx {
+
+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;
+}
+
+} // namespace lyx
Index: src/insets/InsetTabular.h
===================================================================
--- src/insets/InsetTabular.h	(revision 23858)
+++ src/insets/InsetTabular.h	(working copy)
@@ -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 Cursor;
 class OutputParams;
 
-typedef InsetText InsetTableCell;
-
 //
 // A helper struct for tables
 //
@@ -467,7 +465,7 @@
 	class CellData {
 	public:
 		///
-		CellData(Buffer const &);
+		CellData(Buffer const &, Tabular const &);
 		///
 		CellData(CellData const &);
 		///
Index: src/insets/InsetTabular.cpp
===================================================================
--- src/insets/InsetTabular.cpp	(revision 23858)
+++ src/insets/InsetTabular.cpp	(working copy)
@@ -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
@@ -31,6 +30,7 @@
 #include "DispatchResult.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "InsetTableCell.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
@@ -470,7 +470,7 @@
 /////////////////////////////////////////////////////////////////////
 
 
-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 +482,7 @@
 	  right_line(false),
 	  usebox(BOX_NONE),
 	  rotate(false),
-	  inset(new InsetTableCell(buf))
+	  inset(new InsetTableCell(buf, this, &table))
 {
 	inset->setBuffer(const_cast<Buffer &>(buf));
 	inset->paragraphs().back().setLayout(buf.params().documentClass().emptyLayout());
@@ -503,8 +503,10 @@
 	  rotate(cs.rotate),
 	  align_special(cs.align_special),
 	  p_width(cs.p_width),
-	  inset(dynamic_cast<InsetTableCell*>(cs.inset->clone()))
-{}
+	  inset(dynamic_cast<InsetTableCell *>(cs.inset->clone()))
+{
+	inset->setCellData(this);
+}
 
 
 Tabular::CellData & Tabular::CellData::operator=(CellData cs)
@@ -581,7 +583,7 @@
 	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 +630,7 @@
 	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 +680,7 @@
 	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 +762,8 @@
 		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;
@@ -2759,7 +2761,11 @@
 void Tabular::setCellInset(row_type row, col_type column,
 			      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);
 }
 
 
@@ -4554,6 +4560,15 @@
 	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');
@@ -4595,6 +4610,8 @@
 			}
 			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 ?
Index: src/insets/InsetCode.h
===================================================================
--- src/insets/InsetCode.h	(revision 23858)
+++ src/insets/InsetCode.h	(working copy)
@@ -112,6 +112,8 @@
 	INFO_CODE, // 45
 	///
 	COLLAPSABLE_CODE,
+	///
+	CELL_CODE,
 #if 0
 	///
 	THEOREM_CODE,
Index: src/insets/InsetText.h
===================================================================
--- src/insets/InsetText.h	(revision 23858)
+++ src/insets/InsetText.h	(working copy)
@@ -130,10 +130,6 @@
 	///
 	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; }
Index: src/insets/InsetText.cpp
===================================================================
--- src/insets/InsetText.cpp	(revision 23858)
+++ src/insets/InsetText.cpp	(working copy)
@@ -412,22 +412,6 @@
 }
 
 
-// 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();
Index: src/insets/Inset.cpp
===================================================================
--- src/insets/Inset.cpp	(revision 23858)
+++ src/insets/Inset.cpp	(working copy)
@@ -105,6 +105,7 @@
 		InsetName("info", INFO_CODE),
 		InsetName("collapsable", COLLAPSABLE_CODE),
 		InsetName("newpage", NEWPAGE_CODE),
+		InsetName("tablecell", CELL_CODE)
 	};
 
 	size_t const insetnames_size =
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp	(revision 23858)
+++ src/Paragraph.cpp	(working copy)
@@ -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 @@
 	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 @@
 	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();
 }
 
 
Index: src/DocIterator.cpp
===================================================================
--- src/DocIterator.cpp	(revision 23858)
+++ src/DocIterator.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "mathed/InsetMath.h"
 
 #include "insets/InsetTabular.h"
+#include "insets/InsetTableCell.h"
 
 #include "support/debug.h"
 
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 23858)
+++ src/Makefile.am	(working copy)
@@ -522,6 +522,7 @@
 	insets/InsetRef.cpp \
 	insets/InsetSpace.cpp \
 	insets/InsetSpecialChar.cpp \
+	insets/InsetTableCell.cpp \
 	insets/InsetTabular.cpp \
 	insets/InsetText.cpp \
 	insets/InsetTOC.cpp \
@@ -577,6 +578,7 @@
 	insets/InsetRef.h \
 	insets/InsetSpace.h \
 	insets/InsetSpecialChar.h \
+	insets/InsetTableCell.h \
 	insets/InsetTabular.h \
 	insets/InsetText.h \
 	insets/InsetTOC.h \

Reply via email to