7 #include "math_matrixinset.h"
10 #include "support/LOstream.h"
12 #include "LaTeXFeatures.h"
17 string getAlign(MathInsetTypes type, int cols)
22 for (int i = 0; i < cols; ++i)
27 for (int i = 0; i < cols; ++i)
43 string const star(bool n)
49 int getCols(short int type)
68 // returns position of first relation operator in the array
69 // used for "intelligent splitting"
70 int firstRelOp(MathArray const & array)
72 for (MathArray::const_iterator it = array.begin(); it != array.end(); ++it)
74 return it - array.begin();
81 MathMatrixInset::MathMatrixInset()
82 : MathGridInset(1, 1), objtype_(LM_OT_SIMPLE), nonum_(1), label_(1)
86 MathMatrixInset::MathMatrixInset(MathInsetTypes t)
87 : MathGridInset(getCols(t), 1), objtype_(t), nonum_(1), label_(1)
89 halign(getAlign(t, ncols()));
93 MathMatrixInset::MathMatrixInset(MathInsetTypes t, int cols)
94 : MathGridInset(cols, 1), objtype_(t), nonum_(1), label_(1)
96 halign(getAlign(t, ncols()));
100 MathInset * MathMatrixInset::clone() const
102 return new MathMatrixInset(*this);
106 void MathMatrixInset::metrics(MathStyles) const
108 size_ = (getType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY;
110 // let the cells adjust themselves
111 MathGridInset::metrics(size_);
118 if (numberedType()) {
120 for (int row = 0; row < nrows(); ++row)
121 l = std::max(l, mathed_string_width(LM_TC_BF, size(), nicelabel(row)));
127 // make it at least as high as the current font
130 math_font_max_dim(LM_TC_TEXTRM, LM_ST_TEXT, asc, des);
131 ascent_ = std::max(ascent_, asc);
132 descent_ = std::max(descent_, des);
136 void MathMatrixInset::draw(Painter & pain, int x, int y) const
141 MathGridInset::draw(pain, x, y);
143 if (numberedType()) {
144 int xx = x + colinfo_.back().offset_ + colinfo_.back().width_ + 20;
145 for (int row = 0; row < nrows(); ++row) {
146 int yy = y + rowinfo_[row].offset_;
147 drawStr(pain, LM_TC_BF, size(), xx, yy, nicelabel(row));
153 void MathMatrixInset::write(std::ostream & os, bool fragile) const
157 bool n = numberedType();
159 for (int row = 0; row < nrows(); ++row) {
160 for (int col = 0; col < ncols(); ++col) {
161 cell(index(row, col)).write(os, fragile);
162 os << eocString(col);
165 if (!label_[row].empty())
166 os << "\\label{" << label_[row] << "}";
170 os << eolString(row);
177 string MathMatrixInset::label(int row) const
183 void MathMatrixInset::label(int row, string const & label)
189 void MathMatrixInset::numbered(int row, bool num)
195 bool MathMatrixInset::numbered(int row) const
201 bool MathMatrixInset::ams() const
207 bool MathMatrixInset::display() const
209 return getType() != LM_OT_SIMPLE;
213 std::vector<string> const MathMatrixInset::getLabelList() const
215 std::vector<string> res;
216 for (int row = 0; row < nrows(); ++row)
217 if (!label_[row].empty() && nonum_[row] != 1)
218 res.push_back(label_[row]);
223 bool MathMatrixInset::numberedType() const
225 if (getType() == LM_OT_SIMPLE)
227 for (int row = 0; row < nrows(); ++row)
234 void MathMatrixInset::validate(LaTeXFeatures & features) const
236 features.amsstyle = ams();
238 // Validation is necessary only if not using AMS math.
239 // To be safe, we will always run mathedvalidate.
240 //if (features.amsstyle)
243 features.boldsymbol = true;
244 //features.binom = true;
246 MathNestInset::validate(features);
250 void MathMatrixInset::header_write(std::ostream & os) const
252 bool n = numberedType();
263 os << "\\begin{equation" << star(n) << "}\n";
269 os << "\\begin{eqnarray" << star(n) << "}\n";
273 os << "\\begin{align" << star(n) << "}";
277 os << "\\begin{alignat" << star(n) << "}"
278 << "{" << ncols()/2 << "}\n";
281 os << "\\begin{unknown" << star(n) << "}";
286 void MathMatrixInset::footer_write(std::ostream & os) const
288 bool n = numberedType();
297 os << "\\end{equation" << star(n) << "}\n";
303 os << "\\end{eqnarray" << star(n) << "}\n";
307 os << "\\end{align" << star(n) << "}\n";
311 os << "\\end{alignat" << star(n) << "}\n";
315 os << "\\end{unknown" << star(n) << "}";
320 void MathMatrixInset::addRow(int row)
322 nonum_.insert(nonum_.begin() + row + 1, !numberedType());
323 label_.insert(label_.begin() + row + 1, string());
324 MathGridInset::addRow(row);
327 void MathMatrixInset::appendRow()
329 nonum_.push_back(!numberedType());
330 label_.push_back(string());
331 MathGridInset::appendRow();
335 void MathMatrixInset::delRow(int row)
337 MathGridInset::delRow(row);
338 nonum_.erase(nonum_.begin() + row);
339 label_.erase(label_.begin() + row);
342 void MathMatrixInset::addCol(int col)
346 mutate(LM_OT_EQNARRAY);
356 MathGridInset::addCol(col);
358 MathGridInset::addCol(col);
367 void MathMatrixInset::delCol(int col)
371 MathGridInset::delCol(col);
380 string MathMatrixInset::nicelabel(int row) const
384 if (label_[row].empty())
385 return string("(#)");
386 return "(" + label_[row] + ")";
391 short typecode(string const & s)
394 return LM_OT_EQUATION;
396 return LM_OT_EQUATION;
398 return LM_OT_EQNARRAY;
404 return LM_OT_XXALIGN;
406 return LM_OT_MULTLINE;
411 void MathMatrixInset::mutate(string const & newtype)
413 if (newtype == "dump") {
417 //lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n";
418 mutate(typecode(newtype));
421 void MathMatrixInset::glueall()
424 for (int i = 0; i < nargs(); ++i)
425 ar.push_back(cell(i));
426 *this = MathMatrixInset(LM_OT_SIMPLE);
431 MathInsetTypes MathMatrixInset::getType() const
437 void MathMatrixInset::setType(MathInsetTypes t)
444 void MathMatrixInset::mutate(short newtype)
446 //lyxerr << "mutating from '" << getType() << "' to '" << newtype << "'\n";
448 if (newtype == getType())
453 setType(LM_OT_EQUATION);
461 setType(LM_OT_SIMPLE);
465 MathGridInset::addCol(1);
468 int pos = firstRelOp(cell(0));
470 cell(0).erase(pos, cell(0).size());
471 cell(1).erase(0, pos);
474 setType(LM_OT_ALIGN);
480 MathGridInset::addCol(1);
481 MathGridInset::addCol(1);
483 // split it "nicely" on the firest relop
484 int pos = firstRelOp(cell(0));
486 cell(0).erase(pos, cell(0).size());
487 cell(1).erase(0, pos);
489 if (cell(1).size()) {
491 cell(1).erase(1, cell(1).size());
496 setType(LM_OT_EQNARRAY);
505 case LM_OT_EQUATION: {
506 // set correct (no)numbering
507 bool allnonum = true;
508 for (int r = 0; r < nrows(); ++r) {
513 // set first non-empty label
515 for (int r = 0; r < nrows(); ++r) {
516 if (!label_[r].empty()) {
524 nonum_[0] = allnonum;
532 for (int row = 0; row < nrows(); ++row) {
534 cell(c).push_back(cell(c + 1));
536 MathGridInset::delCol(2);
537 setType(LM_OT_ALIGN);
550 MathGridInset::addCol(1);
551 setType(LM_OT_EQNARRAY);
557 lyxerr << "mutation from '" << getType()
558 << "' to '" << newtype << "' not implemented\n";
564 lyxerr << "mutation from '" << getType()
565 << "' to '" << newtype << "' not implemented\n";