Martin Vermeer wrote:
> If I may summarize what I think it _should_ do:
>
> 1) If you want to swap two rows, make sure you're not on the last row.
No. If you are on the last row, it is swapped with the second to last one.
This is consistent with the tabular inset, so we should not change it.
> 2) If you want to swap two columns, make sure you're not in the
> rightmost column.
Same as above.
> 3) If you want to delete a horizontal or vertical line, make sure there
> is one (or more) in the place (above row, left to column) to delete.
> (adding or deleting rows or columns is always possible, so no conditions
> there; right?)
No. Adding is always possible, but the code depends on the fact that we have
at least one row and one column.
> Disable if any of these conditions is violated, otherwise enable. All
> three require cursor (cur) and rowinfo_/colinfo_ knowledge... but we
> have that in getStatus, don't we?
Yes.
> (Item 3 is optional; a silent fail is unelegant, however. Strictly
> speaking all three are optional if one accepts silent failure)
It is not optional IMO.
In the meantime I had a look at vlines to the right and hlines at the
bottom. It turned out that both are already supported: MathGridInset stores
a dummy row and dummy column for this purpose. There were only two little
bugs:
1. The rightmost '|' was not handled correctly in MathGridInset::halign()
2. The following code
\begin{array}{|c|c|}
\hline
1 & 2 \\ \hline
3 & 4 \\ \hline
\end{array}
produced one additional empty row because of the last '\\'. I changed the
math parser to delete this line and implemented one FIXME as a side effect.
It would be nice if you could merge the attached patch with yours and commit
it, because I don't have time to work on that right now.
Georg
Index: lib//ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ChangeLog,v
retrieving revision 1.672
diff -u -p -r1.672 ChangeLog
--- lib//ChangeLog 9 Feb 2005 18:56:00 -0000 1.672
+++ lib//ChangeLog 10 Feb 2005 08:16:19 -0000
@@ -1,3 +1,8 @@
+2005-02-10 Georg Baum <[EMAIL PROTECTED]>
+
+ * ui/stdmenus.ui: add more facilities for drawing/deleting partition
+ lines in matrix
+
2005-02-09 Martin Vermeer <[EMAIL PROTECTED]>
* ui/stdmenus.ui: add facilities for drawing/deleting partition
Index: lib//ui/stdmenus.ui
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ui/stdmenus.ui,v
retrieving revision 1.40
diff -u -p -r1.40 stdmenus.ui
--- lib//ui/stdmenus.ui 9 Feb 2005 18:56:01 -0000 1.40
+++ lib//ui/stdmenus.ui 10 Feb 2005 08:16:21 -0000
@@ -159,14 +159,18 @@ Menuset
Item "Copy Row" "tabular-feature copy-row"
Item "Swap Rows" "tabular-feature swap-row"
Item "Add Line Above" "tabular-feature add-hline-above"
+ Item "Add Line Below" "tabular-feature add-hline-below"
Item "Delete Line Above" "tabular-feature delete-hline-above"
+ Item "Delete Line Below" "tabular-feature delete-hline-below"
Separator
Item "Add Column|C" "tabular-feature append-column"
Item "Delete Column|e" "tabular-feature delete-column"
Item "Copy Column" "tabular-feature copy-column"
Item "Swap Columns" "tabular-feature swap-column"
Item "Add Line to Left" "tabular-feature add-vline-left"
+ Item "Add Line to Right" "tabular-feature add-vline-right"
Item "Delete Line to Left" "tabular-feature delete-vline-left"
+ Item "Delete Line to Right" "tabular-feature delete-vline-right"
End
Menu "edit_math_limits"
? src/mathed/math_intertextinset.C
? src/mathed/math_intertextinset.h
Index: src/mathed/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ChangeLog,v
retrieving revision 1.470
diff -u -p -r1.470 ChangeLog
--- src/mathed/ChangeLog 9 Feb 2005 18:56:00 -0000 1.470
+++ src/mathed/ChangeLog 10 Feb 2005 08:18:16 -0000
@@ -1,4 +1,15 @@
-<<<<<<< ChangeLog
+2005-02-10 Georg Baum <[EMAIL PROTECTED]>
+
+ * math_gridinset.C (halign): fix '|' to the right of the last column
+ * math_gridinset.[Ch]: remove unused leftline_ and rightline_
+ * math_gridinset.C: add more facilities for adding/deleting
+ partition lines in matrix.
+ * math_gridinset.C (getStatus): implement missing LFUN_TABULAR_FEATURE
+ * math_parser.C (delEmptyLastRow): new
+ * math_parser.C (parse1): Store active environment and use it to
+ detect nonmatching \end{} and removing superflous rows with
+ delEmptyLastRow()
+
2005-02-09 Martin Vermeer <[EMAIL PROTECTED]>
* math_gridinset.[hC]: add facilities for drawing/deleting partition
Index: src/mathed/math_gridinset.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_gridinset.C,v
retrieving revision 1.155
diff -u -p -r1.155 math_gridinset.C
--- src/mathed/math_gridinset.C 9 Feb 2005 18:56:00 -0000 1.155
+++ src/mathed/math_gridinset.C 10 Feb 2005 08:18:17 -0000
@@ -124,7 +124,7 @@ int MathGridInset::RowInfo::skipPixels()
MathGridInset::ColInfo::ColInfo()
- : align_('c'), leftline_(false), rightline_(false), lines_(0)
+ : align_('c'), lines_(0)
{}
@@ -215,11 +215,12 @@ void MathGridInset::halign(string const
{
col_type col = 0;
for (string::const_iterator it = hh.begin(); it != hh.end(); ++it) {
- if (col >= ncols())
- break;
char c = *it;
if (c == '|') {
colinfo_[col].lines_++;
+ } else if (col >= ncols()) {
+ // Only '|' is allowed in the last dummy column
+ break;
} else if (c == 'c' || c == 'l' || c == 'r') {
colinfo_[col].align_ = c;
++col;
@@ -1102,8 +1140,12 @@ void MathGridInset::doDispatch(LCursor &
swapRow(cur.row());
else if (s == "add-hline-above")
rowinfo_[cur.row()].lines_++;
+ else if (s == "add-hline-below")
+ rowinfo_[cur.row()+1].lines_++;
else if (s == "delete-hline-above")
- rowinfo_[cur.row()].lines_ = 0;
+ rowinfo_[cur.row()].lines_--;
+ else if (s == "delete-hline-below")
+ rowinfo_[cur.row()+1].lines_--;
else if (s == "append-column")
for (int i = 0, n = extractInt(is); i < n; ++i) {
row_type r = cur.row();
@@ -1126,8 +1168,12 @@ void MathGridInset::doDispatch(LCursor &
swapCol(col(cur.idx()));
else if (s == "add-vline-left")
colinfo_[col(cur.idx())].lines_++;
+ else if (s == "add-vline-right")
+ colinfo_[col(cur.idx())+1].lines_++;
else if (s == "delete-vline-left")
- colinfo_[col(cur.idx())].lines_ = 0;
+ colinfo_[col(cur.idx())].lines_--;
+ else if (s == "delete-vline-right")
+ colinfo_[col(cur.idx())+1].lines_--;
else {
cur.undispatched();
break;
@@ -1223,7 +1269,36 @@ bool MathGridInset::getStatus(LCursor &
{
bool ret = true;
switch (cmd.action) {
- case LFUN_TABULAR_FEATURE:
+ case LFUN_TABULAR_FEATURE: {
+ flag.enabled(false);
+ string const s = cmd.argument;
+ if (s == "valign-top" ||
+ s == "valign-middle" ||
+ s == "valign-bottom" ||
+ s == "align-left" ||
+ s == "align-right" ||
+ s == "align-center" ||
+ s == "append-row" ||
+ (s == "delete-row" && nrows() > 1) ||
+ s == "copy-row" ||
+ (s == "swap-row" && nrows() > 1) ||
+ s == "add-hline-above" ||
+ s == "add-hline-below" ||
+ (s == "delete-hline-above" &&
+ rowinfo_[cur.row()].lines_ > 0) ||
+ (s == "delete-hline-below" &&
+ rowinfo_[cur.row()+1].lines_ > 0) ||
+ s == "append-column" ||
+ (s == "delete-column" && ncols() > 1) ||
+ s == "copy-column" ||
+ (s == "swap-column" && ncols() > 1) ||
+ s == "add-vline-left" ||
+ s == "add-vline-right" ||
+ (s == "delete-vline-left" &&
+ colinfo_[col(cur.idx())].lines_ > 0) ||
+ (s == "delete-vline-right" &&
+ colinfo_[col(cur.idx())+1].lines_ > 0))
+ flag.enabled(true);
#if 0
// should be more precise
if (v_align_ == '\0') {
@@ -1234,14 +1309,15 @@ bool MathGridInset::getStatus(LCursor &
flag.enable(false);
break;
}
- if (!contains("tcb", cmd.argument[0])) {
+ if (!lyx::support::contains("tcb", cmd.argument[0])) {
flag.enable(false);
break;
}
flag.setOnOff(cmd.argument[0] == v_align_);
-#endif
flag.enabled(true);
+#endif
break;
+ }
default:
ret = MathNestInset::getStatus(cur, cmd, flag);
break;
Index: src/mathed/math_gridinset.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_gridinset.h,v
retrieving revision 1.85
diff -u -p -r1.85 math_gridinset.h
--- src/mathed/math_gridinset.h 19 Jan 2005 15:03:31 -0000 1.85
+++ src/mathed/math_gridinset.h 10 Feb 2005 08:18:17 -0000
@@ -74,10 +74,6 @@ public:
mutable int width_;
/// cached offset
mutable int offset_;
- /// do we need a line to the left?
- bool leftline_;
- /// do we need a line to the right?
- bool rightline_;
/// how many lines to the left of this column?
int lines_;
/// additional amount to be skipped when drawing
@@ -159,21 +155,21 @@ public:
/// pulls cell after pressing erase
void idxGlue(idx_type idx);
- ///
+ /// add a row
virtual void addRow(row_type r);
- ///
+ /// delete a row
virtual void delRow(row_type r);
- ///
+ /// copy a row
virtual void copyRow(row_type r);
- ///
+ /// swap two rows
virtual void swapRow(row_type r);
- ///
+ /// add a column
virtual void addCol(col_type c);
- ///
+ /// delete a column
virtual void delCol(col_type c);
- ///
+ /// copy a column
virtual void copyCol(col_type c);
- ///
+ /// swap two columns
virtual void swapCol(col_type c);
///
virtual void appendRow();
@@ -229,9 +225,11 @@ protected:
void splitCell(LCursor & cur);
public:
- /// row info
+ /// row info.
+ /// rowinfo_[nrows()] is a dummy row used only for hlines.
std::vector<RowInfo> rowinfo_;
- /// column info
+ /// column info.
+ /// colinfo_[ncols()] is a dummy column used only for vlines.
std::vector<ColInfo> colinfo_;
/// cell info
std::vector<CellInfo> cellinfo_;
Index: src/mathed/math_parser.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_parser.C,v
retrieving revision 1.310
diff -u -p -r1.310 math_parser.C
--- src/mathed/math_parser.C 27 Jan 2005 21:05:43 -0000 1.310
+++ src/mathed/math_parser.C 10 Feb 2005 08:18:17 -0000
@@ -160,6 +160,30 @@ bool addCol(MathGridInset & grid, MathGr
}
+/*!
+ * Check wether the last row is empty and remove it if yes.
+ * Otherwise the following code
+ * \verbatim
+\begin{array}{|c|c|}
+\hline
+1 & 2 \\ \hline
+3 & 4 \\ \hline
+\end{array}
+ * \endverbatim
+ * will result in a grid with 3 rows (+ the dummy row that is always present),
+ * because the last '\\' opens a new row.
+ */
+void delEmptyLastRow(MathGridInset & grid)
+{
+ MathGridInset::row_type const row = grid.nrows() - 1;
+ for (MathGridInset::col_type col = 0; col < grid.ncols(); ++col) {
+ if (!grid.cell(grid.index(row, col)).empty())
+ return;
+ }
+ grid.delRow(row + 1);
+}
+
+
// These are TeX's catcodes
enum CatCode {
catEscape, // 0 backslash
@@ -317,6 +341,8 @@ private:
vector<Token> tokens_;
///
unsigned pos_;
+ /// Stack of active environments
+ vector<string> environments_;
};
@@ -897,12 +923,24 @@ void Parser::parse1(MathGridInset & grid
else if (t.cs() == "end") {
if (flags & FLAG_END) {
// eat environment name
- //string const name =
- getArg('{', '}');
- // FIXME: check that we ended the correct environment
- return;
- }
- error("found 'end' unexpectedly");
+ string const name = getArg('{', '}');
+ if (environments_.empty())
+ error("'found \\end{" + name +
+ "}' without matching '\\begin{" +
+ name + "}'");
+ else if (name != environments_.back())
+ error("'\\end{" + name +
+ "}' does not match '\\begin{" +
+ environments_.back() + "}'");
+ else {
+ environments_.pop_back();
+ if (name == "array" ||
+ name == "subarray")
+ delEmptyLastRow(grid);
+ return;
+ }
+ } else
+ error("found 'end' unexpectedly");
}
else if (t.cs() == ")") {
@@ -1028,6 +1066,7 @@ void Parser::parse1(MathGridInset & grid
else if (t.cs() == "begin") {
string const name = getArg('{', '}');
+ environments_.push_back(name);
if (name == "array" || name == "subarray") {
string const valign = parse_verbatim_option() + 'c';