This path is the previous + - fixed an abolute/relative coords wicked bug in rowPainter that is present at least from oct 23, that makes selection on insets [not on the first page of text] to lose the intermediate part of the selection, i.e. to show as selected only the first and last line of selection.
- dispatch to BufferView after dispatching to the cursor (as discussed) The main idea needed to make LyXText handle MOUSE_* events coming from insets is that now these events (that are the only ones having meaningful coordinates, btw) are sent to LyXText in the LyXText's own coordinates (and no more in screen coordinates). There are two known remaining bugs, that I recall: - LFUN_MOUSE_RELEASE events get dispatched to the pointer position, and so when selecting inside an inset and finishing the selection with the pointer outside we get funny behaviour (for instance, if you finish over a button, the button dialog pops) - selections are not cleared out when the cursor gets out of an inset by clicking (I suppose that was done in insetUnlock or something). As a workaround, I've patched the painting code to not paint a selection if the cursor is not in that inset (trivial). It would remain to clear the selection when the cursor enters the inset: I've not done this because I don't know if this is the way to go. It would be very nice if someone else could give it a test. Regards, Alfredo
Index: BufferView_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v retrieving revision 1.463 diff -u -p -u -r1.463 BufferView_pimpl.C --- BufferView_pimpl.C 13 Nov 2003 20:16:33 -0000 1.463 +++ BufferView_pimpl.C 14 Nov 2003 17:45:20 -0000 @@ -891,8 +891,28 @@ namespace { bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd) { switch (cmd.action) { + case LFUN_MOUSE_MOTION: { + FuncRequest cmd1(cmd, bv_); + UpdatableInset * inset = bv_->cursor().innerInset(); + DispatchResult res; + if (inset) { + cmd1.x -= inset->x(); + cmd1.y -= inset->y(); + res = inset->dispatch(cmd1); + } else { + cmd1.y += bv_->top_y(); + res = bv_->cursor().innerText()->dispatch(cmd1); + } + + if (bv_->fitCursor() || res.update()) { + bv_->update(); + bv_->cursor().updatePos(); + } + + return true; + } + case LFUN_MOUSE_PRESS: - case LFUN_MOUSE_MOTION: case LFUN_MOUSE_RELEASE: case LFUN_MOUSE_DOUBLE: case LFUN_MOUSE_TRIPLE: { @@ -920,7 +940,7 @@ bool BufferView::Pimpl::workAreaDispatch if (inset) { FuncRequest cmd2 = cmd1; lyxerr << "dispatching action " << cmd2.action - << " to inset " << inset << endl; + << " to inset " << inset << endl; cmd2.x -= inset->x(); cmd2.y -= inset->y(); res = inset->dispatch(cmd2); @@ -953,6 +973,7 @@ bool BufferView::Pimpl::workAreaDispatch << " to surrounding LyXText " << theTempCursor.innerText() << endl; bv_->cursor() = theTempCursor; + cmd1.y += bv_->top_y(); res = bv_->cursor().innerText()->dispatch(cmd1); if (bv_->fitCursor() || res.update()) bv_->update(); Index: cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v retrieving revision 1.21 diff -u -p -u -r1.21 cursor.C --- cursor.C 13 Nov 2003 13:43:38 -0000 1.21 +++ cursor.C 14 Nov 2003 17:45:20 -0000 @@ -104,6 +104,14 @@ DispatchResult LCursor::dispatch(FuncReq lyxerr << "trying to dispatch to main text " << bv_->text << endl; DispatchResult res = bv_->text->dispatch(cmd); lyxerr << " result: " << res.val() << endl; + + if (!res.dispatched()) { + lyxerr << "trying to dispatch to bv " << bv_ << endl; + bool sucess = bv_->dispatch(cmd); + lyxerr << " result: " << sucess << endl; + res.dispatched(sucess); + } + return res; } Index: rowpainter.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/rowpainter.C,v retrieving revision 1.89 diff -u -p -u -r1.89 rowpainter.C --- rowpainter.C 13 Nov 2003 13:43:39 -0000 1.89 +++ rowpainter.C 14 Nov 2003 17:45:22 -0000 @@ -14,6 +14,7 @@ #include "rowpainter.h" #include "buffer.h" +#include "cursor.h" #include "debug.h" #include "bufferparams.h" #include "BufferView.h" @@ -389,11 +390,12 @@ void RowPainter::paintSelection() RowList::iterator endrow = endpit->getRow(text_.selection.end.pos()); int const h = row_.height(); + int const row_y = pit_->y + row_.y_offset(); + if (text_.bidi.same_direction()) { int x; int y = yo_; int w; - if (startrow == rit_ && endrow == rit_) { if (startx < endx) { x = int(xo_) + startx; @@ -411,7 +413,8 @@ void RowPainter::paintSelection() int const x = is_rtl ? int(xo_ + endx) : int(xo_); int const w = is_rtl ? (width_ - endx) : endx; pain_.fillRectangle(x, y, w, h, LColor::selection); - } else if (y_ > starty && y_ < endy) { + } else if (row_y > starty && row_y < endy) { + pain_.fillRectangle(int(xo_), y, width_, h, LColor::selection); } return; @@ -945,7 +948,7 @@ void RowPainter::paint() paintBackground(); // paint the selection background - if (text_.selection.set()) + if (text_.selection.set() && &text_ == bv_.cursor().innerText()) paintSelection(); // vertical lines for appendix Index: text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.180 diff -u -p -u -r1.180 text3.C --- text3.C 13 Nov 2003 20:16:34 -0000 1.180 +++ text3.C 14 Nov 2003 17:45:29 -0000 @@ -1327,55 +1327,26 @@ DispatchResult LyXText::dispatch(FuncReq if (!bv->buffer()) break; - - // Check for inset locking -#ifdef LOCK - if (bv->innerInset()) { - InsetOld * tli = bv->innerInset(); - LyXCursor cursor = bv->text->cursor; - LyXFont font = bv->text->getFont(bv->text->cursorPar(), cursor.pos()); - int width = tli->width(); - int inset_x = font.isVisibleRightToLeft() - ? cursor.x() - width : cursor.x(); - int start_x = inset_x + tli->scroll(); - FuncRequest cmd1 = cmd; - cmd1.x = cmd.x - start_x; - cmd1.y = cmd.y - cursor.y() + bv->top_y(); - tli->dispatch(cmd1); - break; - } -#endif - - // The test for not selection possible is needed, that only motion - // events are used, where the bottom press event was on - // the drawing area too + // The test for not selection possible is needed, that + // only motion events are used, where the bottom press + // event was on the drawing area too if (!selection_possible) { - lyxerr[Debug::ACTION] - << "BufferView::Pimpl::Dispatch: no selection possible\n"; + lyxerr[Debug::ACTION] << "BufferView::Pimpl::" + "Dispatch: no selection possible\n"; break; } + RowList::iterator cursorrow = cursorRow(); + + setCursorFromCoordinates(cmd.x, cmd.y); - RowList::iterator cursorrow = bv->text->cursorRow(); - bv->text->setCursorFromCoordinates(cmd.x, cmd.y + bv->top_y()); - #if 0 - // sorry for this but I have a strange error that the y value jumps at - // a certain point. This seems like an error in my xforms library or - // in some other local environment, but I would like to leave this here - // for the moment until I can remove this (Jug 20020418) - if (y_before < bv->text->cursor.y()) - lyxerr << y_before << ':' - << bv->text->cursor.y() << endl; - #endif // This is to allow jumping over large insets - if (cursorrow == cursorRow()) { - if (cmd.y >= bv->workHeight()) + if (cursorrow == cursorRow() && !in_inset_) { + if (cmd.y - bv->top_y() >= bv->workHeight()) cursorDown(false); - else if (cmd.y < 0) + else if (cmd.y - bv->top_y() < 0) cursorUp(false); } - - bv->text->setSelection(); -// bv->update(); + setSelection(); break; } @@ -1407,24 +1378,21 @@ DispatchResult LyXText::dispatch(FuncReq paste_internally = true; } - int const screen_first = bv->top_y(); selection_possible = true; // Clear the selection - bv->text->clearSelection(); - bv->update(); - bv->updateScrollbar(); - + clearSelection(); + // Right click on a footnote flag opens float menu if (cmd.button() == mouse_button::button3) { selection_possible = false; break; } - bv->text->setCursorFromCoordinates(cmd.x, cmd.y + screen_first); + setCursorFromCoordinates(cmd.x, cmd.y); + selection.cursor = cursor; finishUndo(); - bv->text->selection.cursor = bv->text->cursor; - bv->x_target(bv->text->cursor.x()); + bv->x_target(cursor.x()); if (bv->fitCursor()) selection_possible = false; @@ -1452,7 +1420,7 @@ DispatchResult LyXText::dispatch(FuncReq return DispatchResult(true, false); selection_possible = false; - + if (cmd.button() == mouse_button::button2) break; Index: textcursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/textcursor.C,v retrieving revision 1.9 diff -u -p -u -r1.9 textcursor.C --- textcursor.C 9 Oct 2003 10:52:10 -0000 1.9 +++ textcursor.C 14 Nov 2003 17:45:29 -0000 @@ -13,6 +13,7 @@ #include "textcursor.h" #include "paragraph.h" #include "ParagraphList_fwd.h" +#include "debug.h" #include <string> @@ -37,9 +38,9 @@ void TextCursor::setSelection() selection.end = selection.cursor; selection.start = cursor; } - else if (selection.cursor.y() < cursor.y() || - (selection.cursor.y() == cursor.y() - && selection.cursor.x() < cursor.x())) { + else if (selection.cursor.par() < cursor.par() || + (selection.cursor.par() == cursor.par() + && selection.cursor.pos() < cursor.pos())) { selection.end = cursor; selection.start = selection.cursor; } Index: insets/insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.208 diff -u -p -u -r1.208 insetcollapsable.C --- insets/insetcollapsable.C 13 Nov 2003 13:43:42 -0000 1.208 +++ insets/insetcollapsable.C 14 Nov 2003 17:45:32 -0000 @@ -185,7 +185,7 @@ InsetOld::EDITABLE InsetCollapsable::edi FuncRequest InsetCollapsable::adjustCommand(FuncRequest const & cmd) { FuncRequest cmd1 = cmd; - cmd1.y = ascent() + cmd.y - height_collapsed() - inset.ascent(); + cmd1.y += ascent() - height_collapsed() - inset.ascent(); return cmd1; } @@ -299,7 +299,7 @@ InsetCollapsable::priv_dispatch(FuncRequ return DispatchResult(true, true); case LFUN_MOUSE_MOTION: - if (!collapsed_ && cmd.y > button_dim.y2) + if (!collapsed_) inset.dispatch(adjustCommand(cmd)); return DispatchResult(true, true); @@ -311,7 +311,7 @@ InsetCollapsable::priv_dispatch(FuncRequ return DispatchResult(true, true); default: - return inset.dispatch(cmd); + return inset.dispatch(adjustCommand(cmd)); } lyxerr << "InsetCollapsable::priv_dispatch (end)" << endl; } Index: insets/insettext.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v retrieving revision 1.541 diff -u -p -u -r1.541 insettext.C --- insets/insettext.C 13 Nov 2003 13:43:44 -0000 1.541 +++ insets/insettext.C 14 Nov 2003 17:45:33 -0000 @@ -114,11 +114,8 @@ void InsetText::init() for (; pit != end; ++pit) pit->setInsetOwner(this); text_.paragraphs_ = ¶graphs; - no_selection = true; old_par = -1; in_insetAllowed = false; - mouse_x = 0; - mouse_y = 0; } @@ -320,49 +317,6 @@ void InsetText::sanitizeEmptyText(Buffer extern LCursor theTempCursor; -void InsetText::lfunMousePress(FuncRequest const & cmd) -{ - lyxerr << "InsetText::lfunMousePress, inset: " << this << endl; - no_selection = true; - - // use this to check mouse motion for selection - mouse_x = cmd.x; - mouse_y = cmd.y; - - BufferView * bv = cmd.view(); - no_selection = false; - text_.clearSelection(); - - // set global cursor - bv->cursor() = theTempCursor; - lyxerr << "new global cursor: \n" << bv->cursor() << endl; - text_.setCursorFromCoordinates(cmd.x, cmd.y); -} - - -void InsetText::lfunMouseMotion(FuncRequest const & cmd) -{ - lyxerr << "InsetText::lfunMouseMotion, inset: " << this << endl; - if (no_selection || (mouse_x == cmd.x && mouse_y == cmd.y)) - return; - - BufferView * bv = cmd.view(); - LyXCursor cur = text_.cursor; - text_.setCursorFromCoordinates(cmd.x, cmd.y + dim_.asc); - bv->x_target(text_.cursor.x()); - if (cur != text_.cursor) { - text_.setSelection(); - updateLocal(bv, false); - } -} - - -void InsetText::lfunMouseRelease(FuncRequest const &) -{ - lyxerr << "InsetText::lfunMouseRelease, inset: " << this << endl; - no_selection = true; -} - void InsetText::edit(BufferView * bv, bool left) { @@ -399,38 +353,30 @@ void InsetText::edit(BufferView * bv, in } -DispatchResult InsetText::priv_dispatch(FuncRequest const & cmd, +DispatchResult InsetText::priv_dispatch(FuncRequest const & cmd1, idx_type &, pos_type &) { lyxerr << "InsetText::priv_dispatch (begin), act: " - << cmd.action << " " << endl; - BufferView * bv = cmd.view(); + << cmd1.action << " " << endl; + + BufferView * bv = cmd1.view(); setViewCache(bv); + + //events using coordinates will be handled by the LyXText, so we can + //simply adjust them here + FuncRequest cmd = cmd1; + cmd.y += ascent(); + DispatchResult result; result.dispatched(true); bool was_empty = paragraphs.begin()->empty() && paragraphs.size() == 1; - if (cmd.action != LFUN_MOUSE_PRESS - && cmd.action != LFUN_MOUSE_MOTION - && cmd.action != LFUN_MOUSE_RELEASE) - no_selection = false; switch (cmd.action) { case LFUN_MOUSE_PRESS: - lfunMousePress(cmd); - result = DispatchResult(true, true); - break; - - case LFUN_MOUSE_MOTION: - lfunMouseMotion(cmd); - result = DispatchResult(true, true); - break; - - case LFUN_MOUSE_RELEASE: - lfunMouseRelease(cmd); - result = DispatchResult(true, true); + bv->cursor() = theTempCursor; + result = text_.dispatch(cmd); break; - case LFUN_SELFINSERT: if (bv->buffer()->isReadonly()) { // setErrorMessage(N_("Document is read only")); @@ -626,8 +572,9 @@ DispatchResult InsetText::priv_dispatch( break; } - /// If the action has deleted all text in the inset, we need to change the - // language to the language of the surronding text. + // If the action has deleted all text in the inset, we need + // to change the language to the language of the surronding + // text. if (!was_empty && paragraphs.begin()->empty() && paragraphs.size() == 1) { LyXFont font(LyXFont::ALL_IGNORE); @@ -770,7 +717,6 @@ bool InsetText::insertInset(BufferView * { inset->setOwner(this); text_.insertInset(inset); -// bv->fitCursor(); updateLocal(bv, true); return true; } @@ -837,7 +783,6 @@ void InsetText::setFont(BufferView * bv, if (selectall) text_.clearSelection(); -// bv->fitCursor(); updateLocal(bv, true); } Index: insets/insettext.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.h,v retrieving revision 1.229 diff -u -p -u -r1.229 insettext.h --- insets/insettext.h 13 Nov 2003 13:43:44 -0000 1.229 +++ insets/insettext.h 14 Nov 2003 17:45:33 -0000 @@ -177,12 +177,6 @@ protected: private: /// void init(); - /// - void lfunMousePress(FuncRequest const &); - /// - void lfunMouseMotion(FuncRequest const &); - /// - void lfunMouseRelease(FuncRequest const &); // If the inset is empty set the language of the current font to the // language to the surronding text (if different). void sanitizeEmptyText(BufferView *); @@ -243,15 +237,10 @@ private: /// mutable lyx::paroffset_type old_par; - /// - // to remember old painted frame dimensions to clear it on the right spot! - /// + /** to remember old painted frame dimensions to clear it on + * the right spot! + */ mutable bool in_insetAllowed; - /// - // these are used to check for mouse movement in Motion selection code - /// - int mouse_x; - int mouse_y; public: /// mutable LyXText text_;