-void BufferView::Pimpl::workAreaButtonRelease(int x, int y,
- mouse_button::state button)
-{
- // do nothing if we used the mouse wheel
- if (!buffer_ || button == mouse_button::button4 || button == mouse_button::button5)
- return;
-
- // 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.
- Inset * inset_hit = checkInsetHit(bv_->text, 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 cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button);
- bv_->theLockingInset()->localDispatch(cmd);
- return;
- }
-
- selection_possible = false;
-
- if (button == mouse_button::button2)
- return;
-
- // finish selection
- if (button == mouse_button::button1) {
- workarea().haveSelection(bv_->getLyXText()->selection.set());
- }
-
- switchKeyMap();
- owner_->view_state_changed();
- owner_->updateMenubar();
- 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 (bv_->getLyXText()->selection.set())
- return;
-
- // 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() == Inset::REF_CODE) {
- setCursorParUndo(bv_);
- }
-
- owner_->message(inset_hit->editMessage());
-
- if (isHighlyEditableInset(inset_hit)) {
- // Highly editable inset, like math
- UpdatableInset *inset = (UpdatableInset *)inset_hit;
- FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button);
- inset->localDispatch(cmd);
- } else {
- FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, button);
- inset_hit->localDispatch(cmd);
- // IMO this is a grosshack! Inset's should be changed so that
- // they call the actions they have to do with the insetButtonRel.
- // function and not in the edit(). This should be changed
- // (Jug 20020329)
-#ifdef WITH_WARNINGS
-#warning Please remove donot call inset->edit() here (Jug 20020812)
-#endif
- inset_hit->edit(bv_, x, y, button);
- }
- return;
- }
-
- // Maybe we want to edit a bibitem ale970302
- if (bv_->text->cursor.par()->bibkey) {
- bool const is_rtl = bv_->text->cursor.par()->isRightToLeftPar(buffer_->params);
- int const width = bibitemMaxWidth(bv_, buffer_->params.getLyXTextClass().defaultfont());
- if ((is_rtl && x > bv_->text->workWidth(bv_)-20-width) ||
- (!is_rtl && x < 20+width)) {
- bv_->text->cursor.par()->bibkey->edit(bv_, 0, 0, mouse_button::none);
- }
- }
-
- return;
-}
-
-
-Box BufferView::Pimpl::insetDimensions(LyXText const & text,
- LyXCursor const & cursor) const
-{
- Paragraph /*const*/ & par = *cursor.par();
- pos_type const pos = cursor.pos();
-
- lyx::Assert(par.getInset(pos));
-
- Inset const & inset(*par.getInset(pos));
-
- LyXFont const & font = text.getFont(buffer_, &par, pos);
-
- int const width = inset.width(bv_, font);
- int const inset_x = font.isVisibleRightToLeft()
- ? (cursor.ix() - width) : cursor.ix();
-
- return Box(
- inset_x + inset.scroll(),
- inset_x + width,
- cursor.iy() - inset.ascent(bv_, font),
- cursor.iy() + inset.descent(bv_, font));
-}
-
-
-Inset * BufferView::Pimpl::checkInset(LyXText const & text,
- LyXCursor const & cursor,
- int & x, int & y) const
-{
- pos_type const pos(cursor.pos());
- Paragraph /*const*/ & par(*cursor.par());
-
- if (pos >= par.size() || !par.isInset(pos)) {
- return 0;
- }
-
- Inset /*const*/ * inset = par.getInset(pos);
-
- if (!isEditableInset(inset)) {
- return 0;
- }
-
- Box b(insetDimensions(text, cursor));
-
- if (!b.contained(x, y)) {
- lyxerr[Debug::GUI] << "Missed inset at x,y " << x << "," << y
- << " box " << b << endl;
- return 0;
- }
-
- text.setCursor(bv_, &par, pos, true);
-
- x -= b.x1;
- // The origin of an inset is on the baseline
- y -= text.cursor.iy();
-
- return inset;
-}
-
-
-Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y)
-{
- int y_tmp = y + text->first_y;
-
- LyXCursor cursor;
- text->setCursorFromCoordinates(bv_, cursor, x, y_tmp);
-
- Inset * inset(checkInset(*text, cursor, x, y_tmp));
-
- if (inset) {
- y = y_tmp;
- return inset;
- }
-
- // look at previous position
-
- if (cursor.pos() == 0) {
- return 0;
- }
-
- // move back one
- text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true);
-
- inset = checkInset(*text, cursor, x, y_tmp);
- if (inset) {
- y = y_tmp;
- }
- return inset;
-}
-
-