From fe31e337c13c4db657a267c7a9cf9869a10db696 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Mon, 10 Dec 2001 10:09:00 +0000 Subject: [PATCH] perhaps a fix for the latest crashes git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3174 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/Makefile.am | 2 + src/mathed/formula.C | 4 +- src/mathed/formulamacro.C | 3 +- src/mathed/math_cursor.C | 154 +++++++++++-------------------------- src/mathed/math_cursor.h | 48 +----------- src/mathed/math_data.h | 8 +- src/mathed/math_iterator.C | 61 +++++++++++---- src/mathed/math_iterator.h | 18 +++-- src/mathed/math_pos.C | 98 +++++++++++++++++++++++ src/mathed/math_pos.h | 47 +++++++++++ 10 files changed, 266 insertions(+), 177 deletions(-) create mode 100644 src/mathed/math_pos.C create mode 100644 src/mathed/math_pos.h diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index a3963baff5..ff6bc1a6e5 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -96,6 +96,8 @@ libmathed_la_SOURCES = \ math_notinset.h \ math_parser.C \ math_parser.h \ + math_pos.C \ + math_pos.h \ math_replace.h \ math_rootinset.C \ math_rootinset.h \ diff --git a/src/mathed/formula.C b/src/mathed/formula.C index b0bc0c7621..2cd2e7304a 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -346,7 +346,9 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & font, if (lcolor.getX11Name(LColor::mathbg)!=lcolor.getX11Name(LColor::background)) pain.fillRectangle(x, y - a, w, h, LColor::mathbg); - if (mathcursor && mathcursor->formula() == this) { + if (mathcursor && + const_cast(mathcursor->formula()) == this) + { mathcursor->drawSelection(pain); pain.rectangle(x, y - a, w, h, LColor::mathframe); } diff --git a/src/mathed/formulamacro.C b/src/mathed/formulamacro.C index 4e6739ffb7..01e934b4f4 100644 --- a/src/mathed/formulamacro.C +++ b/src/mathed/formulamacro.C @@ -215,7 +215,8 @@ void InsetFormulaMacro::draw(BufferView * bv, LyXFont const & f, pain.fillRectangle(int(x), a , w, h, LColor::mathmacrobg); pain.rectangle(int(x), a, w, h, LColor::mathframe); - if (mathcursor && mathcursor->formula() == this) + if (mathcursor && + const_cast(mathcursor->formula()) == this) mathcursor->drawSelection(pain); pain.text(int(x + 2), y, prefix(), font); diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 9aeeafba1e..2d7747052c 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -68,7 +68,7 @@ struct Selection data_.push_back(MathArray(i1.cell(), i1.pos_, i2.pos_)); else { std::vector indices = - i1.par_->idxBetween(i1.idx_, i2.idx_); + i1.par_->nucleus()->idxBetween(i1.idx_, i2.idx_); for (MathInset::idx_type i = 0; i < indices.size(); ++i) data_.push_back(i1.cell(indices[i])); } @@ -83,7 +83,7 @@ struct Selection i1.cell().erase(i1.pos_, i2.pos_); else { std::vector indices = - i1.par_->idxBetween(i1.idx_, i2.idx_); + i1.par_->nucleus()->idxBetween(i1.idx_, i2.idx_); for (unsigned i = 0; i < indices.size(); ++i) i1.cell(indices[i]).erase(); } @@ -130,7 +130,11 @@ MathCursor::MathCursor(InsetFormulaBase * formula, bool left) void MathCursor::push(MathAtom & t) { - Cursor_.push_back(MathCursorPos(t.nucleus())); + MathCursorPos p; + p.par_ = &t; + p.idx_ = 0; + p.pos_ = 0; + Cursor_.push_back(p); } @@ -207,7 +211,7 @@ UpdatableInset * MathCursor::asHyperActiveInset() const bool MathCursor::isInside(MathInset const * p) const { for (unsigned i = 0; i < Cursor_.size(); ++i) - if (Cursor_[i].par_ == p) + if (Cursor_[i].par_->nucleus() == p) return true; return false; } @@ -228,7 +232,7 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const // we can't move into anything new during selection if (Cursor_.size() == Anchor_.size()) return false; - if (t.nucleus() != Anchor_[Cursor_.size()].par_) + if (&t != Anchor_[Cursor_.size()].par_) return false; } return true; @@ -323,16 +327,17 @@ void MathCursor::setPos(int x, int y) cursor_type best_cursor; double best_dist = 1e10; - MathIterator it(formula()->par().nucleus()); - MathIterator et; + MathIterator it = ibegin(formula()->par()); + MathIterator et = iend(formula()->par()); for ( ; it != et; ++it) { + //lyxerr << "*it: " << *it << " *et: " << *et << "\n"; if (selection_) { // avoid deeper nested insets when selecting if (it.cursor().size() > Anchor_.size()) continue; // anchor might be deeper! if (it.cursor().size() == Anchor_.size()) - if (it.par() != Anchor_.back().par_) + if (it.par().nucleus() != Anchor_.back().par_->nucleus()) continue; //if (it.par() != Anchor_[it.cursor().size()].par_) // continue; @@ -349,6 +354,7 @@ void MathCursor::setPos(int x, int y) if (best_dist < 1e10) Cursor_ = best_cursor; //lyxerr << "x: " << x << " y: " << y << " dist: " << best_dist << "\n"; + lyx::Assert(Cursor_.size()); dump("setPos 2"); } @@ -723,7 +729,6 @@ void MathCursor::drawSelection(Painter & pain) const MathCursorPos i1; MathCursorPos i2; getSelection(i1, i2); - //lyxerr << "selection from: " << i1 << " to " << i2 << "\n"; if (i1.idx_ == i2.idx_) { MathXArray & c = i1.xcell(); @@ -734,7 +739,7 @@ void MathCursor::drawSelection(Painter & pain) const pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection); } else { std::vector indices - = i1.par_->idxBetween(i1.idx_, i2.idx_); + = (*i1.par_)->idxBetween(i1.idx_, i2.idx_); for (unsigned i = 0; i < indices.size(); ++i) { MathXArray & c = i1.xcell(indices[i]); int x1 = c.xo(); @@ -798,20 +803,18 @@ void MathCursor::getPos(int & x, int & y) #ifdef WITH_WARNINGS #warning This should probably take cellXOffset and cellYOffset into account #endif - dump("getPos 1"); x = xarray().xo() + xarray().pos2x(pos()); y = xarray().yo(); - dump("getPos 2"); } -MathInset * MathCursor::par() const +MathAtom & MathCursor::par() const { - return cursor().par_; + return *cursor().par_; } -InsetFormulaBase const * MathCursor::formula() +InsetFormulaBase * MathCursor::formula() { return formula_; } @@ -856,7 +859,7 @@ bool MathCursor::selection() const MathGridInset * MathCursor::enclosingGrid(MathCursor::idx_type & idx) const { for (int i = Cursor_.size() - 1; i >= 0; --i) { - MathGridInset * p = Cursor_[i].par_->asGridInset(); + MathGridInset * p = (*Cursor_[i].par_)->asGridInset(); if (p) { idx = Cursor_[i].idx_; return p; @@ -987,12 +990,24 @@ MathArray & MathCursor::array() const return dummy; } + if (Cursor_.size() == 0) { + lyxerr << "############ Cursor_.size() == 0 not valid\n"; + return dummy; + } + return cursor().cell(); } MathXArray & MathCursor::xarray() const { + static MathXArray dummy; + + if (Cursor_.size() == 0) { + lyxerr << "############ Cursor_.size() == 0 not valid\n"; + return dummy; + } + return cursor().xcell(); } @@ -1036,19 +1051,18 @@ void MathCursor::breakLine() p->mutate(LM_OT_EQNARRAY); idx() = 0; pos() = size(); - return; - } - - p->addRow(row()); + } else { + p->addRow(row()); - // split line - const row_type r = row(); - for (col_type c = col() + 1; c < p->ncols(); ++c) - p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c))); + // split line + const row_type r = row(); + for (col_type c = col() + 1; c < p->ncols(); ++c) + p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c))); - // split cell - splitCell(); - p->cell(idx()).swap(p->cell(idx() + p->ncols() - 1)); + // split cell + splitCell(); + p->cell(idx()).swap(p->cell(idx() + p->ncols() - 1)); + } } @@ -1091,12 +1105,14 @@ void MathCursor::getSelection(MathCursorPos & i1, MathCursorPos & i2) const MathCursorPos & MathCursor::cursor() { + lyx::Assert(Cursor_.size()); return Cursor_.back(); } MathCursorPos const & MathCursor::cursor() const { + lyx::Assert(Cursor_.size()); return Cursor_.back(); } @@ -1160,8 +1176,8 @@ bool MathCursor::bruteFind(int xlow, int xhigh, int ylow, int yhigh) cursor_type best_cursor; double best_dist = 1e10; - MathIterator it(formula()->par().nucleus()); - MathIterator et; + MathIterator it = ibegin(formula()->par()); + MathIterator et = iend(formula()->par()); for ( ; it != et; ++it) { int xo = it.position().xpos(); int yo = it.position().ypos(); @@ -1395,6 +1411,7 @@ bool MathCursor::interpret(char c) MathCursorPos MathCursor::normalAnchor() const { + lyx::Assert(Anchor_.size() >= Cursor_.size()); // use Anchor on the same level as Cursor MathCursorPos normal = Anchor_[Cursor_.size() - 1]; if (Cursor_.size() < Anchor_.size() && !(normal < cursor())) { @@ -1420,82 +1437,3 @@ void MathCursor::stripFromLastEqualSign() } -//////////////////////////////////////////////////////////////////////// - - -MathCursorPos::MathCursorPos() - : par_(0), idx_(0), pos_(0) -{} - - -MathCursorPos::MathCursorPos(MathInset * p) - : par_(p), idx_(0), pos_(0) -{} - - -MathArray & MathCursorPos::cell(MathCursor::idx_type idx) const -{ - return par_->cell(idx); -} - - -MathArray & MathCursorPos::cell() const -{ - return par_->cell(idx_); -} - - -MathXArray & MathCursorPos::xcell(MathCursor::idx_type idx) const -{ - return par_->xcell(idx); -} - - -MathXArray & MathCursorPos::xcell() const -{ - return par_->xcell(idx_); -} - - -int MathCursorPos::xpos() const -{ - return xcell().xo() + xcell().pos2x(pos_); -} - - -int MathCursorPos::ypos() const -{ - return xcell().yo(); -} - -std::ostream & operator<<(std::ostream & os, MathCursorPos const & p) -{ - os << "(par: " << p.par_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ")"; - return os; -} - - -bool operator==(MathCursorPos const & ti, MathCursorPos const & it) -{ - return ti.par_ == it.par_ && ti.idx_ == it.idx_ && ti.pos_ == it.pos_; -} - - -bool operator!=(MathCursorPos const & ti, MathCursorPos const & it) -{ - return ti.par_ != it.par_ || ti.idx_ != it.idx_ || ti.pos_ != it.pos_; -} - - -bool operator<(MathCursorPos const & ti, MathCursorPos const & it) -{ - if (ti.par_ != it.par_) { - lyxerr << "can't compare cursor and anchor in different insets\n"; - return true; - } - if (ti.idx_ != it.idx_) - return ti.idx_ < it.idx_; - return ti.pos_ < it.pos_; -} - - diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index f0fd8efd12..93f5d05bcf 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -23,6 +23,7 @@ #include "math_defs.h" #include "math_inset.h" +#include "math_pos.h" #include "LString.h" class InsetFormulaBase; @@ -41,47 +42,6 @@ this formula's mathHullInset to the current position. */ -/// Description of a position -class MathCursorPos { -public: - /// - MathCursorPos(); - /// - explicit MathCursorPos(MathInset * p); - - /// returns cell corresponding to this position - MathArray & cell() const; - /// returns cell corresponding to this position - MathArray & cell(MathInset::idx_type idx) const; - /// returns xcell corresponding to this position - MathXArray & xcell() const; - /// returns xcell corresponding to this position - MathXArray & xcell(MathInset::idx_type idx) const; - /// - int xpos() const; - /// - int ypos() const; - -public: - /// pointer to an inset - MathInset * par_; - /// cell index of a position in this inset - MathInset::idx_type idx_; - /// position in this cell - MathInset::pos_type pos_; -}; - -/// test for equality -bool operator==(MathCursorPos const &, MathCursorPos const &); -/// test for inequality -bool operator!=(MathCursorPos const &, MathCursorPos const &); -/// test for order -bool operator<(MathCursorPos const &, MathCursorPos const &); -/// output -std::ostream & operator<<(std::ostream &, MathCursorPos const &); - - -/// see above class MathCursor { public: /// short of anything else reasonable @@ -143,11 +103,11 @@ public: /// in pixels from top of screen void getPos(int & x, int & y); /// - MathInset * par() const; + MathAtom & par() const; /// return the next enclosing grid inset and the cursor's index in it MathGridInset * enclosingGrid(idx_type &) const; /// - InsetFormulaBase const * formula(); + InsetFormulaBase * formula(); /// current offset in the current cell pos_type pos() const; /// current cell @@ -305,7 +265,7 @@ private: idx_type & idx(); /// - InsetFormulaBase * const formula_; + InsetFormulaBase * formula_; /// MathTextCodes lastcode_; // Selection stuff diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index d603337526..b537e51d70 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -13,8 +13,8 @@ * the GNU General Public Licence version 2 or later. */ -#ifndef MATHEDARRAY_H -#define MATHEDARRAY_H +#ifndef MATH_DATA_H +#define MATH_DATA_H #include @@ -49,6 +49,10 @@ public: typedef buffer_type::iterator iterator; /// typedef buffer_type::size_type size_type; + /// + typedef buffer_type::size_type idx_type; + /// + typedef buffer_type::size_type pos_type; public: /// diff --git a/src/mathed/math_iterator.C b/src/mathed/math_iterator.C index 0ea88d5098..c0841de2bd 100644 --- a/src/mathed/math_iterator.C +++ b/src/mathed/math_iterator.C @@ -1,17 +1,18 @@ #include -#include "debug.h" #include "math_iterator.h" +#include "debug.h" +#include "support/LAssert.h" -MathIterator::MathIterator() -{} +//MathIterator::MathIterator() +//{} -MathIterator::MathIterator(MathInset * p) +MathIterator::MathIterator(MathAtom & t) { - push(p); + push(t); } @@ -22,12 +23,14 @@ MathIterator::MathIterator(MathCursor::cursor_type const & c) MathCursorPos const & MathIterator::position() const { + lyx::Assert(cursor_.size()); return cursor_.back(); } MathCursorPos & MathIterator::position() { + lyx::Assert(cursor_.size()); return cursor_.back(); } @@ -38,38 +41,43 @@ MathCursor::cursor_type const & MathIterator::cursor() const } -MathInset * MathIterator::par() const +MathAtom const & MathIterator::par() const +{ + return *(position().par_); +} + + +MathAtom & MathIterator::par() { - return cursor_.size() ? cursor_.back().par_ : 0; + return *(position().par_); } MathXArray const & MathIterator::xcell() const { - if (!par()) - lyxerr << "MathIterator::xcell: no cell\n"; return par()->xcell(position().idx_); } -MathInset * MathIterator::nextInset() const +MathAtom * MathIterator::nextInset() const { if (position().pos_ == xcell().data_.size()) return 0; - return (xcell().begin() + position().pos_)->nucleus(); + return const_cast(xcell().begin() + position().pos_); } -void MathIterator::push(MathInset * p) +void MathIterator::push(MathAtom & t) { //lyxerr << "push: " << p << endl; - cursor_.push_back(MathCursorPos(p)); + cursor_.push_back(MathCursorPos(t)); } void MathIterator::pop() { //lyxerr << "pop: " << endl; + lyx::Assert(cursor_.size()); cursor_.pop_back(); } @@ -86,12 +94,19 @@ MathCursorPos const & MathIterator::operator->() const } +void MathIterator::goEnd() +{ + position().idx_ = par()->nargs() - 1; + position().pos_ = xcell().data_.size(); +} + + void MathIterator::operator++() { // move into the current inset if possible // it is impossible for pos() == size()! - if (nextInset() && nextInset()->isActive()) { - push(nextInset()); + if (nextInset() && nextInset()->nucleus()->isActive()) { + push(*nextInset()); return; } @@ -110,7 +125,7 @@ void MathIterator::operator++() return; } - // otherwise leave array, move on one cell + // otherwise leave array, move on one position // this might yield pos() == size(), but that's a ok. pop(); ++position().pos_; @@ -135,3 +150,17 @@ bool operator!=(MathIterator const & it, MathIterator const & jt) return it.cursor() != jt.cursor(); } + + +MathIterator ibegin(MathAtom & t) +{ + return MathIterator(t); +} + + +MathIterator iend(MathAtom & t) +{ + MathIterator it(t); + it.goEnd(); + return it; +} diff --git a/src/mathed/math_iterator.h b/src/mathed/math_iterator.h index f56911c4d5..e351080906 100644 --- a/src/mathed/math_iterator.h +++ b/src/mathed/math_iterator.h @@ -8,9 +8,9 @@ class MathIterator { public: /// default constructor, used for end of range - MathIterator(); + //MathIterator(); /// start with given formula - explicit MathIterator(MathInset * p); + explicit MathIterator(MathAtom & t); /// start with given position explicit MathIterator(MathCursor::cursor_type const & cursor); /// @@ -26,15 +26,19 @@ public: /// read access to full path MathCursor::cursor_type const & cursor() const; /// read access to top most inset - MathInset * par() const; + MathAtom const & par() const; + /// read access to top most inset + MathAtom & par(); + /// helper for iend + void goEnd(); private: /// write access to top most item MathXArray const & xcell() const; /// write access to top most item - MathInset * nextInset() const; + MathAtom * nextInset() const; /// own level down - void push(MathInset *); + void push(MathAtom &); /// own level up void pop(); @@ -47,5 +51,9 @@ bool operator==(MathIterator const &, MathIterator const &); /// bool operator!=(MathIterator const &, MathIterator const &); +/// +MathIterator ibegin(MathAtom & p); +/// +MathIterator iend(MathAtom & p); #endif diff --git a/src/mathed/math_pos.C b/src/mathed/math_pos.C new file mode 100644 index 0000000000..889f13782a --- /dev/null +++ b/src/mathed/math_pos.C @@ -0,0 +1,98 @@ +#include "config.h" + +#include + +#include "math_pos.h" +#include "math_inset.h" +#include "debug.h" +#include "support/LAssert.h" + + +MathCursorPos::MathCursorPos() + : par_(0), idx_(0), pos_(0) +{} + + +MathCursorPos::MathCursorPos(MathAtom & t) + : par_(&t), idx_(0), pos_(0) +{ + lyx::Assert(par_); + lyx::Assert(par_->nucleus()); +} + + +MathArray & MathCursorPos::cell(MathArray::idx_type idx) const +{ + lyx::Assert(par_); + lyx::Assert(par_->nucleus()); + return par_->nucleus()->cell(idx); +} + + +MathArray & MathCursorPos::cell() const +{ + lyx::Assert(par_); + lyx::Assert(par_->nucleus()); + return par_->nucleus()->cell(idx_); +} + + +MathXArray & MathCursorPos::xcell(MathArray::idx_type idx) const +{ + lyx::Assert(par_); + lyx::Assert(par_->nucleus()); + return par_->nucleus()->xcell(idx); +} + + +MathXArray & MathCursorPos::xcell() const +{ + lyx::Assert(par_); + lyx::Assert(par_->nucleus()); + return par_->nucleus()->xcell(idx_); +} + + +int MathCursorPos::xpos() const +{ + return xcell().xo() + xcell().pos2x(pos_); +} + + +int MathCursorPos::ypos() const +{ + return xcell().yo(); +} + + +std::ostream & operator<<(std::ostream & os, MathCursorPos const & p) +{ + os << "(par: " << p.par_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ")"; + return os; +} + + +bool operator==(MathCursorPos const & p, MathCursorPos const & q) +{ + return p.par_ == q.par_ && p.idx_ == q.idx_ && p.pos_ == q.pos_; +} + + +bool operator!=(MathCursorPos const & p, MathCursorPos const & q) +{ + return p.par_ != q.par_ || p.idx_ != q.idx_ || p.pos_ != q.pos_; +} + + +bool operator<(MathCursorPos const & p, MathCursorPos const & q) +{ + if (p.par_ != q.par_) { + lyxerr << "can't compare cursor and anchor in different insets\n"; + return true; + } + if (p.idx_ != q.idx_) + return p.idx_ < q.idx_; + return p.pos_ < q.pos_; +} + + diff --git a/src/mathed/math_pos.h b/src/mathed/math_pos.h new file mode 100644 index 0000000000..8d8e9e951a --- /dev/null +++ b/src/mathed/math_pos.h @@ -0,0 +1,47 @@ +#ifndef MATH_POS_H +#define MATH_POS_H + +#include +#include "math_xdata.h" + + +/// Description of a position +class MathCursorPos { +public: + /// + MathCursorPos(); + /// + explicit MathCursorPos(MathAtom &); + + /// returns cell corresponding to this position + MathArray & cell() const; + /// returns cell corresponding to this position + MathArray & cell(MathArray::idx_type idx) const; + /// returns xcell corresponding to this position + MathXArray & xcell() const; + /// returns xcell corresponding to this position + MathXArray & xcell(MathArray::idx_type idx) const; + /// + int xpos() const; + /// + int ypos() const; + +public: + /// pointer to an inset + MathAtom * par_; + /// cell index of a position in this inset + MathArray::idx_type idx_; + /// position in this cell + MathArray::pos_type pos_; +}; + +/// test for equality +bool operator==(MathCursorPos const &, MathCursorPos const &); +/// test for inequality +bool operator!=(MathCursorPos const &, MathCursorPos const &); +/// test for order +bool operator<(MathCursorPos const &, MathCursorPos const &); +/// output +std::ostream & operator<<(std::ostream &, MathCursorPos const &); + +#endif -- 2.39.2