Hi lyx-devel,

   Attaching patch and lyx test-case file for the following functionality 
(accessed using "inset-modify tabular ...")

1. split-above-row [n]
2. split-below-row [n]
3. split-before-column [n]
4. split-after-column [n]

Here, [n] is an optional row/col index. So you don't have to be in a 
particular row/col to split at another but you do have to be in the table.

The patch was created from within src/insets

I think I have covered all corner cases but I could use help testing. Please 
see the attached .lyx file.

Please consider this patch for inclusion into svn. I hereby grant permission 
to license my contributions to LyX under the GNU General Public License, 
version 2 or later.

The code update is still within InsetTabular::tabularFeatures(). Vincent 
raised a valid issue about an inset creating new insets but here are my 
thoughts:

1. This inset is only creating and inserting a subset of itself. It also 
correctly pops the cursor and places it between the two parts. All this using 
standard API calls so it is "safe".
2. The logic to achieve these functions elsewhere in the code may become 
convoluted since many more checks have to be performed before this case 
becomes applicable. In its current location, this code leverages the 
infrastructure already in place.

   I didn't hear back from any other developer so I went ahead with my 
implementation.

   Please correct me: the lyx code currently doesn't have any place where 
insets, in general, can be split. It could. For example, split a paragraph. 
Seems extraneous till you see that it can be bundled with split-table or 
split-equation into a common LFUN_INSET_SPLIT (say). It would then be simpler 
to insert the table-split code here and maintain Vincent's argument.

Thanks,
Manoj Rajagopalan
Index: InsetTabular.h
===================================================================
--- InsetTabular.h	(revision 33622)
+++ InsetTabular.h	(working copy)
@@ -190,6 +190,14 @@
 		///
 		LONGTABULAR_ALIGN_RIGHT,
 		///
+		SPLIT_ABOVE_ROW,
+		///
+		SPLIT_BELOW_ROW,
+		///
+		SPLIT_BEFORE_COLUMN,
+		///
+		SPLIT_AFTER_COLUMN,
+		///
 		LAST_ACTION
 	};
 	///
Index: InsetTabular.cpp
===================================================================
--- InsetTabular.cpp	(revision 33622)
+++ InsetTabular.cpp	(working copy)
@@ -175,6 +175,10 @@
 	{ Tabular::LONGTABULAR_ALIGN_LEFT, "longtabular-align-left", false },
 	{ Tabular::LONGTABULAR_ALIGN_CENTER, "longtabular-align-center", false },
 	{ Tabular::LONGTABULAR_ALIGN_RIGHT, "longtabular-align-right", false },
+	{ Tabular::SPLIT_ABOVE_ROW, "split-above-row", true },
+	{ Tabular::SPLIT_BELOW_ROW, "split-below-row", true },
+	{ Tabular::SPLIT_BEFORE_COLUMN, "split-before-column", true },
+	{ Tabular::SPLIT_AFTER_COLUMN, "split-after-column", true },
 	{ Tabular::LAST_ACTION, "", false }
 };
 
@@ -4285,6 +4289,50 @@
 			status.setOnOff(!tabular.use_booktabs);
 			break;
 
+		case Tabular::SPLIT_ABOVE_ROW: {
+			string row_arg("");
+			is >> row_arg;
+			int const row = ((row_arg != "" ) ?
+			                 (convert<int>(row_arg)-1) :
+			                 int(tabular.cellRow(cur.idx())));
+			int const lastrow = int(tabular.row_info.size()) - 1;
+			status.setEnabled(row > 0 && row <= lastrow);
+			break;
+		}
+
+		case Tabular::SPLIT_BELOW_ROW: {
+			string row_arg("");
+			is >> row_arg;
+			int const row = ((row_arg != "" ) ?
+			                 (convert<int>(row_arg)-1) :
+			                 int(tabular.cellRow(cur.idx())));
+			int const lastrow = int(tabular.row_info.size()) - 1;
+			status.setEnabled(row >= 0 && row < lastrow);
+			break;
+		}
+		
+		case Tabular::SPLIT_BEFORE_COLUMN: {
+			string col_arg("");
+			is >> col_arg;
+			int const col = ((col_arg != "" ) ?
+			                 (convert<int>(col_arg)-1) :
+			                 int(tabular.cellColumn(cur.idx())));
+			int const lastcol = int(tabular.column_info.size()) - 1;
+			status.setEnabled(col > 0 && col <= lastcol);
+			break;
+		}
+			
+		case Tabular::SPLIT_AFTER_COLUMN: {
+			string col_arg("");
+			is >> col_arg;
+			int const col = ((col_arg != "" ) ?
+			                 (convert<int>(col_arg)-1) :
+			                 int(tabular.cellColumn(cur.idx())));
+			int const lastcol = int(tabular.column_info.size()) - 1;
+			status.setEnabled(col >= 0 && col < lastcol);
+			break;
+		}
+			
 		default:
 			status.clear();
 			status.setEnabled(false);
@@ -5269,6 +5317,75 @@
 		break;
 	}
 
+	case Tabular::SPLIT_ABOVE_ROW: {
+		row_type const row = ((value != "") ?
+		                      row_type(convert<int>(value)-1) :
+		                      tabular.cellRow(cur.idx()));
+		row_type const lastrow = tabular.row_info.size() - 1;
+		InsetTabular *topPart = new InsetTabular(*this);
+		// *this keeps all the bottom rows
+		for(row_type r = 0; r < row; ++r)
+			tabular.deleteRow(0);
+		for(row_type r = row; r <= lastrow; ++r)
+			topPart->tabular.deleteRow(row);
+		cur.pop();
+		cur.insert(topPart);
+		cur.posForward();
+		cur.text()->breakParagraph(cur);
+		break;
+	}
+
+	case Tabular::SPLIT_BELOW_ROW: {
+		row_type const row = ((value != "") ?
+		                      row_type(convert<int>(value)-1) :
+		                      tabular.cellRow(cur.idx()));
+		row_type const lastrow = tabular.row_info.size() - 1;
+		InsetTabular *topPart = new InsetTabular(*this);
+		// *this keeps all the bottom rows
+		for(row_type r = 0; r <= row; ++r)
+			tabular.deleteRow(0);
+		for(row_type r = row+1; r <= lastrow; ++r)
+			topPart->tabular.deleteRow(row+1);
+		cur.pop();
+		cur.insert(topPart);
+		cur.posForward();
+		cur.text()->breakParagraph(cur);
+		break;
+	}
+
+	case Tabular::SPLIT_BEFORE_COLUMN: {
+		col_type const col = ((value != "") ?
+		                      col_type(convert<int>(value)-1) :
+		                      tabular.cellColumn(cur.idx()));
+		col_type const lastcol = tabular.column_info.size() - 1;
+		InsetTabular *leftPart = new InsetTabular(*this);
+		// *this keeps all the right rows
+		for(col_type c = 0; c < col; ++c)
+			tabular.deleteColumn(0);
+		for(col_type c = col; c <= lastcol; ++c)
+			leftPart->tabular.deleteColumn(col);
+		cur.pop();
+		cur.insert(leftPart);
+		cur.posForward();
+		break;
+	}
+
+	case Tabular::SPLIT_AFTER_COLUMN: {
+		col_type const col = ((value != "") ?
+		                      col_type(convert<int>(value)-1) :
+		                      tabular.cellColumn(cur.idx()));
+		col_type const lastcol = tabular.column_info.size() - 1;
+		InsetTabular *leftPart = new InsetTabular(*this);
+		// *this keeps all the right rows
+		for(col_type c = 0; c <= col; ++c)
+			tabular.deleteColumn(0);
+		for(col_type c = col+1; c <= lastcol; ++c)
+			leftPart->tabular.deleteColumn(col+1);
+		cur.pop();
+		cur.insert(leftPart);
+		cur.posForward();
+		break;
+	}
 	// dummy stuff just to avoid warnings
 	case Tabular::LAST_ACTION:
 		break;

Attachment: table-duplicate.lyx
Description: application/lyx

Reply via email to