This fixes a crash when changing font for a whole table cell and brings a bit of selection by mouse back. Not perfect, though...
Andre' --
Index: BufferView_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v retrieving revision 1.536 diff -u -p -r1.536 BufferView_pimpl.C --- BufferView_pimpl.C 5 Apr 2004 09:36:16 -0000 1.536 +++ BufferView_pimpl.C 7 Apr 2004 07:59:54 -0000 @@ -861,7 +861,6 @@ bool BufferView::Pimpl::workAreaDispatch //lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl; LCursor cur(*bv_); cur.push(bv_->buffer()->inset()); - cur.resetAnchor(); cur.selection() = bv_->cursor().selection(); // Doesn't go through lyxfunc, so we need to update @@ -873,14 +872,17 @@ bool BufferView::Pimpl::workAreaDispatch screen().hideCursor(); - // either the inset under the cursor or the + // Either the inset under the cursor or the // surrounding LyXText will handle this event. - // built temporary path to inset + // Build temporary cursor. InsetBase * inset = bv_->text()->editXY(cur, cmd.x, cmd.y); lyxerr << "hit inset at tip: " << inset << endl; lyxerr << "created temp cursor:\n" << cur << endl; + // Put anchor at the same position. + cur.resetAnchor(); + // Try to dispatch to an non-editable inset near this position // via the temp cursor. If the inset wishes to change the real // cursor it has to do so explicitly by using @@ -889,15 +891,10 @@ bool BufferView::Pimpl::workAreaDispatch if (inset) inset->dispatch(cur, cmd); - // Now dispatch to the real cursor. Any change to the cursor - // is immediate. + // Now dispatch to the temporary cursor. If the real cursor should + // be modified, the inset's dispatch has to do so explicitly. if (!res.dispatched()) res = cur.dispatch(cmd); - - // If the request was dispatched the temp cursor should have been - // in a way to be used as new 'real' cursor. - if (res.dispatched()) - bv_->cursor() = cur; // Redraw if requested or necessary. if (res.update()) Index: cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v retrieving revision 1.90 diff -u -p -r1.90 cursor.C --- cursor.C 5 Apr 2004 16:44:09 -0000 1.90 +++ cursor.C 7 Apr 2004 08:00:05 -0000 @@ -316,15 +316,27 @@ bool LCursor::posRight() CursorSlice & LCursor::anchor() { + if (anchor_.size() < size()) { + lyxerr << "anchor_.size() < cursor_.size() " + "should not happen when accessing the anchor" << endl; + BOOST_ASSERT(false); + } BOOST_ASSERT(!anchor_.empty()); - return anchor_.back(); + // this size is cursor_.size() + return anchor_[size() - 1]; } CursorSlice const & LCursor::anchor() const { + if (anchor_.size() < size()) { + lyxerr << "anchor_.size() < cursor_.size() " + "should not happen when accessing the anchor" << endl; + BOOST_ASSERT(false); + } + // this size is cursor_.size() BOOST_ASSERT(!anchor_.empty()); - return anchor_.back(); + return anchor_[size() - 1]; } @@ -364,6 +376,7 @@ void LCursor::setSelection() { selection() = true; // a selection with no contents is not a selection +#warning doesnt look ok if (par() == anchor().par() && pos() == anchor().pos()) selection() = false; } @@ -493,13 +506,6 @@ string LCursor::grabAndEraseSelection() eraseSelection(); selection() = false; return res; -} - - -void LCursor::selClear() -{ - resetAnchor(); - clearSelection(); } Index: cursor.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.h,v retrieving revision 1.57 diff -u -p -r1.57 cursor.h --- cursor.h 5 Apr 2004 16:44:10 -0000 1.57 +++ cursor.h 7 Apr 2004 08:00:07 -0000 @@ -96,10 +96,6 @@ public: void selPaste(size_t n); /// void selHandle(bool selecting); - /// start selection - void selStart(); - /// clear selection - void selClear(); /// clears or deletes selection depending on lyxrc setting void selClearOrDel(); // Index: cursor_slice.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor_slice.C,v retrieving revision 1.23 diff -u -p -r1.23 cursor_slice.C --- cursor_slice.C 25 Mar 2004 09:16:15 -0000 1.23 +++ cursor_slice.C 7 Apr 2004 08:00:07 -0000 @@ -150,7 +150,7 @@ bool operator<(CursorSlice const & p, Cu if (&p.inset() != &q.inset()) { lyxerr << "can't compare cursor and anchor in different insets\n" << "p: " << p << '\n' << "q: " << q << endl; - return true; + BOOST_ASSERT(false); } if (p.idx() != q.idx()) return p.idx() < q.idx(); Index: dociterator.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/dociterator.C,v retrieving revision 1.13 diff -u -p -r1.13 dociterator.C --- dociterator.C 3 Apr 2004 08:36:56 -0000 1.13 +++ dociterator.C 7 Apr 2004 08:00:11 -0000 @@ -103,6 +103,7 @@ MathAtom & DocIterator::prevAtom() MathAtom const & DocIterator::nextAtom() const { BOOST_ASSERT(!empty()); + lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } @@ -111,6 +112,7 @@ MathAtom const & DocIterator::nextAtom() MathAtom & DocIterator::nextAtom() { BOOST_ASSERT(!empty()); + lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } Index: lyxfunc.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxfunc.C,v retrieving revision 1.610 diff -u -p -r1.610 lyxfunc.C --- lyxfunc.C 5 Apr 2004 18:34:33 -0000 1.610 +++ lyxfunc.C 7 Apr 2004 08:00:24 -0000 @@ -511,6 +511,7 @@ FuncStatus LyXFunc::getStatus(FuncReques flag.enabled(false); } + //lyxerr << "LyXFunc::getStatus: got: " << flag.enabled() << endl; return flag; } @@ -1254,13 +1255,6 @@ void LyXFunc::dispatch(FuncRequest const case LFUN_EXTERNAL_EDIT: { FuncRequest fr(action, argument); InsetExternal().dispatch(view()->cursor(), fr); - break; - } - - case LFUN_BREAKLINE: { -#ifdef WITH_WARNINGS -#warning swallow 'Return' if the minibuffer is focused. But how? -#endif break; } Index: paragraph.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v retrieving revision 1.361 diff -u -p -r1.361 paragraph.C --- paragraph.C 5 Apr 2004 09:36:20 -0000 1.361 +++ paragraph.C 7 Apr 2004 08:00:40 -0000 @@ -1671,14 +1671,14 @@ void Paragraph::cleanChanges() Change::Type Paragraph::lookupChange(lyx::pos_type pos) const { - BOOST_ASSERT(!size() || pos < size()); + BOOST_ASSERT(empty() || pos < size()); return pimpl_->lookupChange(pos); } Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const { - BOOST_ASSERT(!size() || pos < size()); + BOOST_ASSERT(empty() || pos < size()); return pimpl_->lookupChangeFull(pos); } Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.567 diff -u -p -r1.567 text2.C --- text2.C 5 Apr 2004 09:36:22 -0000 1.567 +++ text2.C 7 Apr 2004 08:00:50 -0000 @@ -417,12 +417,18 @@ void LyXText::setFont(LCursor & cur, LyX DocIterator pos = cur.selectionBegin(); DocIterator posend = cur.selectionEnd(); + lyxerr << "pos: " << pos << " posend: " << posend << endl; + BufferParams const & params = bv()->buffer()->params(); - for (; pos != posend; pos.forwardChar()) { - LyXFont f = getFont(pos.par(), pos.pos()); - f.update(font, params.language, toggleall); - setCharFont(pos.par(), pos.pos(), f); + // Don't use forwardChar here as posend might have + // pos() == lastpos() and forwardChar would miss it. + for (; pos != posend; pos.forwardPos()) { + if (pos.pos() != pos.lastpos()) { + LyXFont f = getFont(pos.par(), pos.pos()); + f.update(font, params.language, toggleall); + setCharFont(pos.par(), pos.pos(), f); + } } redoParagraphs(beg, end + 1); Index: text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.244 diff -u -p -r1.244 text3.C --- text3.C 5 Apr 2004 09:36:23 -0000 1.244 +++ text3.C 7 Apr 2004 08:01:06 -0000 @@ -138,7 +138,7 @@ namespace { if (sel.empty()) { cur.insert(new MathHullInset); - cur.dispatch(FuncRequest(LFUN_RIGHT)); + cur.nextInset()->edit(cur, true); cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); // don't do that also for LFUN_MATH_MODE unless you want end up with // always changing to mathrm when opening an inlined inset @@ -1079,6 +1079,12 @@ void LyXText::dispatch(LCursor & cur, Fu lyxerr << "BufferView::Pimpl::dispatch: no selection possible\n"; break; } + + // ignore motions deeper nested than the real anchor + LCursor & bvcur = cur.bv().cursor(); + if (bvcur.selection() && bvcur.anchor_.size() < cur.size()) + break; + CursorSlice old = cur.top(); setCursorFromCoordinates(cur, cmd.x, cmd.y); @@ -1140,6 +1146,10 @@ void LyXText::dispatch(LCursor & cur, Fu finishUndo(); cur.x_target() = cursorX(cur.top()); + // Set cursor here. + bv->cursor() = cur; + + // Don't allow selection after a big jump. if (bv->fitCursor()) selection_possible = false; @@ -1153,6 +1163,7 @@ void LyXText::dispatch(LCursor & cur, Fu bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph")); selection_possible = false; } + break; } Index: mathed/math_hullinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_hullinset.C,v retrieving revision 1.127 diff -u -p -r1.127 math_hullinset.C --- mathed/math_hullinset.C 6 Apr 2004 19:25:39 -0000 1.127 +++ mathed/math_hullinset.C 7 Apr 2004 08:01:16 -0000 @@ -783,7 +783,7 @@ void MathHullInset::doExtern(LCursor & c void MathHullInset::priv_dispatch(LCursor & cur, FuncRequest & cmd) { - lyxerr << "*** MathHullInset: request: " << cmd << endl; + //lyxerr << "*** MathHullInset: request: " << cmd << endl; switch (cmd.action) { case LFUN_BREAKLINE: Index: mathed/math_nestinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_nestinset.C,v retrieving revision 1.111 diff -u -p -r1.111 math_nestinset.C --- mathed/math_nestinset.C 6 Apr 2004 19:25:39 -0000 1.111 +++ mathed/math_nestinset.C 7 Apr 2004 08:01:24 -0000 @@ -571,7 +571,7 @@ void MathNestInset::priv_dispatch(LCurso case LFUN_ESCAPE: if (cur.selection()) - cur.selClear(); + cur.clearSelection(); else cmd = FuncRequest(LFUN_FINISHED_LEFT); break; @@ -964,7 +964,7 @@ void MathNestInset::lfunMouseRelease(LCu if (cmd.button() == mouse_button::button2) { MathArray ar; asArray(cur.bv().getClipboard(), ar); - cur.selClear(); + cur.clearSelection(); cur.setScreenPos(cmd.x, cmd.y); cur.insert(ar); cur.bv().update(); @@ -987,9 +987,9 @@ void MathNestInset::lfunMousePress(LCurs if (cmd.button() == mouse_button::button1) { first_x = cmd.x; first_y = cmd.y; - cur.selClear(); //cur.setScreenPos(cmd.x + xo_, cmd.y + yo_); lyxerr << "lfunMousePress: setting cursor to: " << cur << endl; + cur.resetAnchor(); cur.bv().cursor() = cur; } @@ -1011,10 +1011,6 @@ void MathNestInset::lfunMouseMotion(LCur first_x = cmd.x; first_y = cmd.y; - if (!cur.selection()) - cur.selBegin(); - - //cur.setScreenPos(cmd.x + xo_, cmd.y + yo_); cur.bv().cursor().setCursor(cur, true); } Index: insets/insettabular.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettabular.C,v retrieving revision 1.416 diff -u -p -r1.416 insettabular.C --- insets/insettabular.C 5 Apr 2004 09:36:27 -0000 1.416 +++ insets/insettabular.C 7 Apr 2004 08:01:43 -0000 @@ -410,6 +410,7 @@ void InsetTabular::priv_dispatch(LCursor lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl; //lyxerr << " cur:\n" << cur << endl; CursorSlice sl = cur.top(); + LCursor & bvcur = cur.bv().cursor(); switch (cmd.action) { @@ -420,7 +421,7 @@ void InsetTabular::priv_dispatch(LCursor cur.selection() = false; setPos(cur, cmd.x, cmd.y); cur.resetAnchor(); - cur.bv().cursor().setCursor(cur, false); + bvcur = cur; //if (cmd.button() == mouse_button::button2) // dispatch(cur, FuncRequest(LFUN_PASTESELECTION, "paragraph")); //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; @@ -429,13 +430,16 @@ void InsetTabular::priv_dispatch(LCursor case LFUN_MOUSE_MOTION: if (cmd.button() != mouse_button::button1) break; + // ignore motions deeper nested than the real anchor + if (bvcur.selection() && bvcur.anchor_.size() < cur.size()) + break; setPos(cur, cmd.x, cmd.y); - cur.bv().cursor().setCursor(cur, true); - //lyxerr << "# InsetTabular::MouseMotion\n" << cur.bv().cursor() << endl; + bvcur.setCursor(cur, true); + //lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl; break; case LFUN_MOUSE_RELEASE: - //lyxerr << "# InsetTabular::MouseRelease\n" << cur.bv().cursor() << endl; + //lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl; if (cmd.button() == mouse_button::button3) InsetTabularMailer(*this).showDialog(&cur.bv()); break; @@ -1725,7 +1729,7 @@ void InsetTabular::addPreview(PreviewLoa bool InsetTabular::tablemode(LCursor & cur) const { - return cur.selBegin().idx() != cur.selEnd().idx(); + return cur.selection() && cur.selBegin().idx() != cur.selEnd().idx(); }