Asger Alstrup wrote:
> Martin Vermeer wrote:
>> See attached patch, which has been on the list for a few days.
>
> Technically, you posted the first version of this before the freeze was
> announced, so I think it's fair to put it in, also considering the number
> of revisions you have made.
Please use this version instead. I completed the getStatus method and
changed the type of lines_ to unsigned int. Then we have a guarantee that
lines_ is always > 0. I also replaced col(cur.idx()) with cur.col() to make
it symmetric to cur.row().
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 14 Feb 2005 08:34:00 -0000
@@ -1,3 +1,12 @@
+2005-02-13 Georg Baum <[EMAIL PROTECTED]>
+
+ * ui/stdmenus.ui: add more facilities for drawing/deleting partition
+ lines in matrix
+
+2005-02-10 Martin Vermeer <[EMAIL PROTECTED]>
+
+ * bind/math.bind: provide key bindings for lines in matrix
+
2005-02-09 Martin Vermeer <[EMAIL PROTECTED]>
* ui/stdmenus.ui: add facilities for drawing/deleting partition
Index: lib/bind/math.bind
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/bind/math.bind,v
retrieving revision 1.25
diff -u -p -r1.25 math.bind
--- lib/bind/math.bind 19 May 2004 16:27:43 -0000 1.25
+++ lib/bind/math.bind 14 Feb 2005 08:34:01 -0000
@@ -77,11 +77,19 @@
\bind "M-m c d" "tabular-feature delete-column"
\bind "M-m c c" "tabular-feature copy-column"
\bind "M-m c s" "tabular-feature swap-column"
+\bind "M-m c a" "tabular-feature add-vline-left"
+\bind "M-m c e" "tabular-feature delete-vline-left"
+\bind "M-m c z" "tabular-feature add-vline-right"
+\bind "M-m c x" "tabular-feature delete-vline-right"
\bind "M-m w i" "tabular-feature append-row"
\bind "M-m w d" "tabular-feature delete-row"
\bind "M-m w c" "tabular-feature copy-row"
\bind "M-m w s" "tabular-feature swap-row"
+\bind "M-m w a" "tabular-feature add-hline-above"
+\bind "M-m w e" "tabular-feature delete-hline-above"
+\bind "M-m w z" "tabular-feature add-hline-below"
+\bind "M-m w x" "tabular-feature delete-hline-below"
\bind "M-m w t" "tabular-feature valign-top"
\bind "M-m w m" "tabular-feature valign-middle"
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 14 Feb 2005 08:34:02 -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"
Index: src/mathed/ChangeLog
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ChangeLog,v
retrieving revision 1.471
diff -u -p -r1.471 ChangeLog
--- src/mathed/ChangeLog 12 Feb 2005 15:46:22 -0000 1.471
+++ src/mathed/ChangeLog 14 Feb 2005 08:34:21 -0000
@@ -1,3 +1,22 @@
+2005-02-12 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.[Ch]: change type of lines_ to unsigned int to
+ prevent check for <= 0
+ * 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()
+ * math_hullinset.C (getStatus): remove now superflous tests
+
+2005-02-10 Martin Vermeer <[EMAIL PROTECTED]>
+
+ * math_gridinset.C: implement getStatus for tabular-features.
+
2005-02-12 Jürgen Spitzmüller <[EMAIL PROTECTED]>
* math_nestinset.C (doDispatch): normalize() cursor after moving up/down
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 14 Feb 2005 08:34:21 -0000
@@ -22,14 +22,19 @@
#include "cursor.h"
#include "debug.h"
#include "funcrequest.h"
+#include "gettext.h"
#include "undo.h"
#include "frontends/Painter.h"
#include "insets/mailinset.h"
+#include "support/lstrings.h"
+
#include <sstream>
+using lyx::support::bformat;
+
using std::endl;
using std::max;
using std::min;
@@ -124,7 +129,7 @@ int MathGridInset::RowInfo::skipPixels()
MathGridInset::ColInfo::ColInfo()
- : align_('c'), leftline_(false), rightline_(false), lines_(0)
+ : align_('c'), lines_(0)
{}
@@ -215,11 +220,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;
@@ -477,7 +520,7 @@ void MathGridInset::draw(PainterInfo & p
cell(idx).draw(pi, x + cellXOffset(idx), y + cellYOffset(idx));
for (row_type row = 0; row <= nrows(); ++row)
- for (int i = 0; i < rowinfo_[row].lines_; ++i) {
+ for (unsigned int i = 0; i < rowinfo_[row].lines_; ++i) {
int yy = y + rowinfo_[row].offset_ - rowinfo_[row].ascent_
- i * hlinesep() - hlinesep()/2 - rowsep()/2;
pi.pain.line(x + 1, yy,
@@ -486,7 +529,7 @@ void MathGridInset::draw(PainterInfo & p
}
for (col_type col = 0; col <= ncols(); ++col)
- for (int i = 0; i < colinfo_[col].lines_; ++i) {
+ for (unsigned int i = 0; i < colinfo_[col].lines_; ++i) {
int xx = x + colinfo_[col].offset_
- i * vlinesep() - vlinesep()/2 - colsep()/2;
pi.pain.line(xx, y - dim_.ascent() + 1,
@@ -1081,11 +1124,11 @@ void MathGridInset::doDispatch(LCursor &
else if (s == "valign-bottom")
valign('b');
else if (s == "align-left")
- halign('l', col(cur.idx()));
+ halign('l', cur.col());
else if (s == "align-right")
- halign('r', col(cur.idx()));
+ halign('r', cur.col());
else if (s == "align-center")
- halign('c', col(cur.idx()));
+ halign('c', cur.col());
else if (s == "append-row")
for (int i = 0, n = extractInt(is); i < n; ++i)
addRow(cur.row());
@@ -1102,32 +1145,40 @@ 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();
- col_type c = col(cur.idx());
+ row_type const r = cur.row();
+ col_type const c = cur.col();
addCol(c);
cur.idx() = index(r, c);
}
else if (s == "delete-column")
for (int i = 0, n = extractInt(is); i < n; ++i) {
- row_type r = cur.row();
- col_type c = col(cur.idx());
+ row_type const r = cur.row();
+ col_type const c = cur.col();
delCol(col(cur.idx()));
cur.idx() = index(r, c);
if (cur.idx() > nargs())
cur.idx() -= ncols();
}
else if (s == "copy-column")
- copyCol(col(cur.idx()));
+ copyCol(cur.col());
else if (s == "swap-column")
- swapCol(col(cur.idx()));
+ swapCol(cur.col());
else if (s == "add-vline-left")
- colinfo_[col(cur.idx())].lines_++;
+ colinfo_[cur.col()].lines_++;
+ else if (s == "add-vline-right")
+ colinfo_[cur.col()+1].lines_++;
else if (s == "delete-vline-left")
- colinfo_[col(cur.idx())].lines_ = 0;
+ colinfo_[cur.col()].lines_--;
+ else if (s == "delete-vline-right")
+ colinfo_[cur.col()+1].lines_--;
else {
cur.undispatched();
break;
@@ -1221,10 +1272,59 @@ void MathGridInset::doDispatch(LCursor &
bool MathGridInset::getStatus(LCursor & cur, FuncRequest const & cmd,
FuncStatus & flag) const
{
- bool ret = true;
switch (cmd.action) {
- case LFUN_TABULAR_FEATURE:
+ case LFUN_TABULAR_FEATURE: {
+ istringstream is(cmd.argument);
+ string s;
+ is >> s;
+ if (nrows() <= 1 && (s == "delete-row" || s == "swap-row")) {
+ flag.enabled(false);
+ flag.message(N_("Only one row"));
+ return true;
+ }
+ if (ncols() <= 1 &&
+ (s == "delete-column" || s == "swap-column")) {
+ flag.enabled(false);
+ flag.message(N_("Only one column"));
+ return true;
+ }
+ if ((rowinfo_[cur.row()].lines_ == 0 &&
+ s == "delete-hline-above") ||
+ (rowinfo_[cur.row() + 1].lines_ == 0 &&
+ s == "delete-hline-below")) {
+ flag.enabled(false);
+ flag.message(N_("No hline to delete"));
+ return true;
+ }
+
+ if ((colinfo_[cur.col()].lines_ == 0 &&
+ s == "delete-vline-left") ||
+ (colinfo_[cur.col() + 1].lines_ == 0 &&
+ s == "delete-vline-right")) {
+ flag.enabled(false);
+ flag.message(N_("No vline to delete"));
+ return true;
+ }
+ 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" ||
+ s == "copy-row" || s == "swap-row" ||
+ s == "add-hline-above" || s == "add-hline-below" ||
+ s == "delete-hline-above" || s == "delete-hline-below" ||
+ s == "append-column" || s == "delete-column" ||
+ s == "copy-column" || s == "swap-column" ||
+ s == "add-vline-left" || s == "add-vline-right" ||
+ s == "delete-vline-left" || s == "delete-vline-right")
+ flag.enabled(true);
+ else {
+ flag.enabled(false);
+ flag.message(bformat(
+ N_("Unknown tabular feature '%1$s'"), s));
+ }
#if 0
+ // FIXME: What did this code do?
+ // Please check wether it is still needed!
// should be more precise
if (v_align_ == '\0') {
flag.enable(true);
@@ -1234,17 +1334,16 @@ 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);
- break;
+#endif
+ return true;
+ }
default:
- ret = MathNestInset::getStatus(cur, cmd, flag);
- break;
+ return MathNestInset::getStatus(cur, cmd, flag);
}
- return ret;
}
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 14 Feb 2005 08:34:21 -0000
@@ -54,7 +54,7 @@ public:
/// cached offset
mutable int offset_;
/// how many hlines above this row?
- int lines_;
+ unsigned int lines_;
/// parameter to the line break
LyXLength crskip_;
/// extra distance between lines
@@ -74,12 +74,8 @@ 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_;
+ unsigned int lines_;
/// additional amount to be skipped when drawing
int skip_;
};
@@ -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_hullinset.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_hullinset.C,v
retrieving revision 1.160
diff -u -p -r1.160 math_hullinset.C
--- src/mathed/math_hullinset.C 26 Nov 2004 13:56:22 -0000 1.160
+++ src/mathed/math_hullinset.C 14 Feb 2005 08:34:21 -0000
@@ -1096,6 +1096,7 @@ bool MathHullInset::getStatus(LCursor &
case LFUN_MATH_MUTATE:
case LFUN_MATH_DISPLAY:
// we handle these
+ flag.enabled(true);
return true;
case LFUN_TABULAR_FEATURE: {
istringstream is(cmd.argument);
@@ -1111,12 +1112,6 @@ bool MathHullInset::getStatus(LCursor &
flag.enabled(false);
return true;
}
- if (nrows() <= 1
- && (s == "delete-row" || s == "swap-row")) {
- flag.message(N_("Only one row"));
- flag.enabled(false);
- return true;
- }
if (!colChangeOK()
&& (s == "append-column"
|| s == "delete-column"
@@ -1124,12 +1119,6 @@ bool MathHullInset::getStatus(LCursor &
flag.message(bformat(
N_("Can't change number of columns in '%1$s'"),
type_));
- flag.enabled(false);
- return true;
- }
- if (ncols() <= 1
- && (s == "delete-column" || s == "swap-column")) {
- flag.message(N_("Only one column"));
flag.enabled(false);
return true;
}
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 14 Feb 2005 08:34:22 -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';