+ case LFUN_GOTOERROR:
+ gotoInset(InsetOld::ERROR_CODE, false);
+ break;
+
+ case LFUN_GOTONOTE:
+ gotoInset(InsetOld::NOTE_CODE, false);
+ break;
+
+ case LFUN_REFERENCE_GOTO:
+ {
+ vector<InsetOld::Code> tmp;
+ tmp.push_back(InsetOld::LABEL_CODE);
+ tmp.push_back(InsetOld::REF_CODE);
+ gotoInset(tmp, true);
+ break;
+ }
+
+ case LFUN_QUOTE: {
+ replaceSelection(bv->getLyXText());
+ ParagraphList::iterator pit = cursor.par();
+ lyx::pos_type pos = cursor.pos();
+ char c;
+ if (!pos)
+ c = ' ';
+ else if (pit->isInset(pos - 1) && pit->getInset(pos - 1)->isSpace())
+ c = ' ';
+ else
+ c = pit->getChar(pos - 1);
+
+ LyXLayout_ptr const & style = pit->layout();
+
+ if (style->pass_thru ||
+ pit->getFontSettings(bv->buffer()->params,
+ pos).language()->lang() == "hebrew" ||
+ (!bv->insertInset(new InsetQuotes(c, bv->buffer()->params))))
+ bv->owner()->dispatch(FuncRequest(LFUN_SELFINSERT, "\""));
+ break;
+ }
+
+ case LFUN_DATE_INSERT: {
+ replaceSelection(bv->getLyXText());
+ time_t now_time_t = time(NULL);
+ struct tm * now_tm = localtime(&now_time_t);
+ setlocale(LC_TIME, "");
+ string arg;
+ if (!cmd.argument.empty())
+ arg = cmd.argument;
+ else
+ arg = lyxrc.date_insert_format;
+ char datetmp[32];
+ int const datetmp_len =
+ ::strftime(datetmp, 32, arg.c_str(), now_tm);
+
+ for (int i = 0; i < datetmp_len; i++) {
+ insertChar(datetmp[i]);
+ update();
+ }
+ selection.cursor = cursor;
+ moveCursorUpdate(bv, false);
+ break;
+ }
+
+ case LFUN_MOUSE_TRIPLE:
+ if (!bv->buffer())
+ break;
+ if (!isInInset() && bv->theLockingInset())
+ break;
+ if (cmd.button() == mouse_button::button1) {
+ if (!isInInset()) {
+ bv->screen().toggleSelection(this, bv);
+ }
+ cursorHome();
+ selection.cursor = cursor;
+ cursorEnd();
+ setSelection();
+ if (!isInInset())
+ bv->screen().toggleSelection(this, bv, false);
+ update();
+ bv->haveSelection(selection.set());
+ }
+ break;
+
+ case LFUN_MOUSE_DOUBLE:
+ if (!bv->buffer())
+ break;
+ if (!isInInset() && bv->theLockingInset())
+ break;
+ if (cmd.button() == mouse_button::button1) {
+ if (!isInInset()) {
+ bv->screen().toggleSelection(this, bv);
+ selectWord(lyx::WHOLE_WORD_STRICT);
+ bv->screen().toggleSelection(this, bv, false);
+ } else {
+ selectWord(lyx::WHOLE_WORD_STRICT);
+ }
+ update();
+ bv->haveSelection(selection.set());
+ }
+ break;
+
+ case LFUN_MOUSE_MOTION:
+ {
+ // Only use motion with button 1
+ //if (ev.button() != mouse_button::button1)
+ // return false;
+
+ if (!bv->buffer())
+ break;
+
+ // Check for inset locking
+ if (bv->theLockingInset()) {
+ InsetOld * tli = bv->theLockingInset();
+ LyXCursor cursor = bv->text->cursor;
+ LyXFont font = bv->text->getFont(cursor.par(), cursor.pos());
+ int width = tli->width();
+ int inset_x = font.isVisibleRightToLeft()
+ ? cursor.ix() - width : cursor.ix();
+ int start_x = inset_x + tli->scroll();
+ FuncRequest cmd1 = cmd;
+ cmd1.x = cmd.x - start_x;
+ cmd1.y = cmd.y - cursor.iy() + bv->text->top_y();
+ tli->localDispatch(cmd1);
+ break;
+ }
+
+ // 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";
+ break;
+ }
+
+ RowList::iterator cursorrow = bv->text->cursorRow();
+ bv->text->setCursorFromCoordinates(cmd.x, cmd.y + bv->text->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 == bv->text->cursorRow()) {
+ if (cmd.y >= bv->workHeight())
+ bv->text->cursorDown(false);
+ else if (cmd.y < 0)
+ bv->text->cursorUp(false);
+ }
+
+ // Maybe an empty line was deleted
+ if (!bv->text->selection.set())
+ bv->update(BufferView::UPDATE);
+ bv->text->setSelection();
+ bv->repaint();
+ bv->fitCursor();
+ break;
+ }
+
+ // Single-click on work area
+ case LFUN_MOUSE_PRESS:
+ {
+ if (!bv->buffer())
+ break;
+
+ // ok ok, this is a hack (for xforms)
+ // We shouldn't go further down as we really should only do the
+ // scrolling and be done with this. Otherwise we may open some
+ // dialogs (Jug 20020424).
+ if (cmd.button() == mouse_button::button4) {
+ bv->scroll(-lyxrc.wheel_jump);
+ break;
+ }
+ if (cmd.button() == mouse_button::button5) {
+ bv->scroll(lyxrc.wheel_jump);
+ break;
+ }
+
+ int x = cmd.x;
+ int y = cmd.y;
+ InsetOld * inset_hit = bv->text->checkInsetHit(x, y);
+
+ // Middle button press pastes if we have a selection
+ // We do this here as if the selection was inside an inset
+ // it could get cleared on the unlocking of the inset so
+ // we have to check this first
+ bool paste_internally = false;
+ if (cmd.button() == mouse_button::button2 && selection.set()) {
+ bv->owner()->dispatch(FuncRequest(LFUN_COPY));
+ paste_internally = true;
+ }
+
+ int const screen_first = bv->text->top_y();
+
+ if (bv->theLockingInset()) {
+ // We are in inset locking mode
+
+ // Check whether the inset was hit. If not reset mode,
+ // otherwise give the event to the inset
+ if (inset_hit == bv->theLockingInset()) {
+ FuncRequest cmd1(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
+ bv->theLockingInset()->localDispatch(cmd1);
+ break;
+ }
+ bv->unlockInset(bv->theLockingInset());
+ }
+
+ if (!inset_hit)
+ selection_possible = true;
+
+ // Clear the selection
+ bv->screen().toggleSelection(bv->text, bv);
+ bv->text->clearSelection();
+ bv->text->partialRebreak();
+ bv->update();
+ bv->updateScrollbar();
+
+ // Single left click in math inset?
+ if (isHighlyEditableInset(inset_hit)) {
+ // Highly editable inset, like math
+ UpdatableInset * inset = static_cast<UpdatableInset *>(inset_hit);
+ selection_possible = false;
+ bv->owner()->message(inset->editMessage());
+ // We just have to lock the inset before calling a PressEvent on it!
+ if (!bv->lockInset(inset))
+ lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
+ FuncRequest cmd1(bv, LFUN_MOUSE_PRESS, x, y, cmd.button());
+ inset->localDispatch(cmd1);
+ break;
+ }
+ // I'm not sure we should continue here if we hit an inset (Jug20020403)
+
+ // Right click on a footnote flag opens float menu
+ if (cmd.button() == mouse_button::button3) {
+ selection_possible = false;
+ break;
+ }
+
+ if (!inset_hit) // otherwise it was already set in checkInsetHit(...)
+ bv->text->setCursorFromCoordinates(x, y + screen_first);
+ finishUndo();
+ bv->text->selection.cursor = bv->text->cursor;
+ bv->text->cursor.x_fix(bv->text->cursor.x());
+
+ if (bv->fitCursor())
+ selection_possible = false;
+
+ // Insert primary selection with middle mouse
+ // if there is a local selection in the current buffer,
+ // insert this
+ if (cmd.button() == mouse_button::button2) {
+ if (paste_internally)
+ bv->owner()->dispatch(FuncRequest(LFUN_PASTE));
+ else
+ bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph"));
+ selection_possible = false;
+ }
+ break;
+ }
+
+ case LFUN_MOUSE_RELEASE:
+ {
+ // do nothing if we used the mouse wheel
+ if (!bv->buffer())
+ break;
+
+ if (cmd.button() == mouse_button::button4
+ || cmd.button() == mouse_button::button5)
+ break;
+
+ // If we hit an inset, we have the inset coordinates in these
+ // and inset_hit points to the inset. If we do not hit an
+ // inset, inset_hit is 0, and inset_x == x, inset_y == y.
+ int x = cmd.x;
+ int y = cmd.y;
+ InsetOld * inset_hit = bv->text->checkInsetHit(x, y);
+
+ if (bv->theLockingInset()) {
+ // We are in inset locking mode.
+
+ // LyX does a kind of work-area grabbing for insets.
+ // Only a ButtonPress FuncRequest outside the inset will
+ // force a insetUnlock.
+ FuncRequest cmd1(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
+ bv->theLockingInset()->localDispatch(cmd1);
+ break;
+ }
+
+ selection_possible = false;
+
+ if (cmd.button() == mouse_button::button2)
+ break;
+
+ // finish selection
+ if (cmd.button() == mouse_button::button1)
+ bv->haveSelection(selection.set());
+
+ bv->switchKeyMap();
+ bv->owner()->view_state_changed();
+ bv->owner()->updateMenubar();
+ bv->owner()->updateToolbar();
+
+ // Did we hit an editable inset?
+ if (inset_hit) {
+ selection_possible = false;
+
+ // if we reach this point with a selection, it
+ // must mean we are currently selecting.
+ // But we don't want to open the inset
+ // because that is annoying for the user.
+ // So just pretend we didn't hit it.
+ // this is OK because a "kosher" ButtonRelease
+ // will follow a ButtonPress that clears
+ // the selection.
+ // Note this also fixes selection drawing
+ // problems if we end up opening an inset
+ if (selection.set())
+ break;
+
+ // CHECK fix this proper in 0.13
+ // well, maybe 13.0 !!!!!!!!!
+
+ // Following a ref shouldn't issue
+ // a push on the undo-stack
+ // anylonger, now that we have
+ // keybindings for following
+ // references and returning from
+ // references. IMHO though, it
+ // should be the inset's own business
+ // to push or not push on the undo
+ // stack. They don't *have* to
+ // alter the document...
+ // (Joacim)
+ // ...or maybe the SetCursorParUndo()
+ // below isn't necessary at all anylonger?
+ if (inset_hit->lyxCode() == InsetOld::REF_CODE)
+ recordUndo(bv, Undo::ATOMIC);
+
+ bv->owner()->message(inset_hit->editMessage());
+
+ FuncRequest cmd1(bv, LFUN_MOUSE_RELEASE, x, y, cmd.button());
+ inset_hit->localDispatch(cmd1);
+ }
+
+ break;
+ }
+