From 3c7c7a3209eabc681ba53fe499f5d15b6d32007a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Wed, 28 Aug 2002 08:30:27 +0000 Subject: [PATCH] the workarea changes plus small math stuff git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@5128 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView.h | 1 + src/BufferView_pimpl.C | 716 +++++++++++++++---------------- src/BufferView_pimpl.h | 12 +- src/ChangeLog | 8 + src/buffer.C | 1 + src/commandtags.h | 2 + src/frontends/ChangeLog | 5 + src/frontends/WorkArea.h | 14 +- src/frontends/qt2/QContentPane.C | 17 +- src/frontends/xforms/XWorkArea.C | 53 ++- src/funcrequest.C | 13 +- src/funcrequest.h | 12 +- src/lyxrc.C | 2 +- src/mathed/Makefile.am | 2 + src/mathed/math_factory.C | 3 + src/mathed/math_inferinset.C | 44 ++ src/mathed/math_inferinset.h | 32 ++ src/mathed/math_parser.C | 7 + 18 files changed, 531 insertions(+), 413 deletions(-) create mode 100644 src/mathed/math_inferinset.C create mode 100644 src/mathed/math_inferinset.h diff --git a/src/BufferView.h b/src/BufferView.h index 7303ec2ad2..b3d510f24d 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -190,6 +190,7 @@ public: void stuffClipboard(string const &) const; /// bool dispatch(FuncRequest const & argument); + private: /// struct Pimpl; diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index c38baae6b8..949281956f 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -20,6 +20,7 @@ #include "frontends/Dialogs.h" #include "frontends/Alert.h" #include "frontends/FileDialog.h" +#include "frontends/mouse_state.h" #include "lyxtext.h" #include "lyxrow.h" #include "paragraph.h" @@ -99,14 +100,10 @@ unsigned int const saved_positions_num = 20; // to these connections we avoid a segfault upon startup, and also at exit. // (Lgb) +boost::signals::connection dispatchcon; boost::signals::connection timecon; boost::signals::connection doccon; boost::signals::connection resizecon; -boost::signals::connection bpresscon; -boost::signals::connection breleasecon; -boost::signals::connection motioncon; -boost::signals::connection doublecon; -boost::signals::connection triplecon; boost::signals::connection kpresscon; boost::signals::connection selectioncon; boost::signals::connection lostcon; @@ -193,16 +190,8 @@ BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner, .connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); resizecon = workarea().workAreaResize .connect(boost::bind(&BufferView::Pimpl::workAreaResize, this)); - bpresscon = workarea().workAreaButtonPress - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonPress, this, _1, _2, _3)); - breleasecon = workarea().workAreaButtonRelease - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonRelease, this, _1, _2, _3)); - motioncon = workarea().workAreaMotionNotify - .connect(boost::bind(&BufferView::Pimpl::workAreaMotionNotify, this, _1, _2, _3)); - doublecon = workarea().workAreaDoubleClick - .connect(boost::bind(&BufferView::Pimpl::doubleClick, this, _1, _2, _3)); - triplecon = workarea().workAreaTripleClick - .connect(boost::bind(&BufferView::Pimpl::tripleClick, this, _1, _2, _3)); + dispatchcon = workarea().dispatch + .connect(boost::bind(&BufferView::Pimpl::dispatch, this, _1)); kpresscon = workarea().workAreaKeyPress .connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2)); selectioncon = workarea().selectionRequested @@ -492,233 +481,6 @@ void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, } -void BufferView::Pimpl::workAreaMotionNotify(int x, int y, mouse_button::state state) -{ - // Only use motion with button 1 - if (!(state & mouse_button::button1)) - return; - - if (!buffer_) - return; - - // Check for inset locking - if (bv_->theLockingInset()) { - LyXCursor cursor = bv_->text->cursor; - LyXFont font = bv_->text->getFont(buffer_, - cursor.par(), cursor.pos()); - int width = bv_->theLockingInset()->width(bv_, font); - int inset_x = font.isVisibleRightToLeft() - ? cursor.ix() - width : cursor.ix(); - int start_x = inset_x + bv_->theLockingInset()->scroll(); - - FuncRequest cmd(bv_, LFUN_MOUSE_MOTION, - x - start_x, y - cursor.iy() + bv_->text->first_y, state); - bv_->theLockingInset()->localDispatch(cmd); - return; - } - - // 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) - return; - - screen().hideCursor(); - - Row * cursorrow = bv_->text->cursor.row(); - bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_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->cursor.row()) { - if (y >= int(workarea().workHeight())) { - bv_->text->cursorDown(bv_, false); - } else if (y < 0) { - bv_->text->cursorUp(bv_, false); - } - } - - if (!bv_->text->selection.set()) - update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted - - bv_->text->setSelection(bv_); - screen().toggleToggle(bv_->text, bv_); - fitCursor(); - showCursor(); -} - - -// Single-click on work area -void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, - mouse_button::state button) -{ - if (!buffer_) - return; - - // ok ok, this is a hack (for xforms) - if (button == mouse_button::button4) { - scroll(-lyxrc.wheel_jump); - // 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). - return; - } else if (button == mouse_button::button5) { - scroll(lyxrc.wheel_jump); - // 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). - return; - } - - Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos); - - // 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 (button == mouse_button::button2 && bv_->getLyXText()->selection.set()) { - owner_->dispatch(FuncRequest(LFUN_COPY)); - paste_internally = true; - } - - int const screen_first = bv_->text->first_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 cmd(bv_, LFUN_MOUSE_PRESS, xpos, ypos, button); - bv_->theLockingInset()->localDispatch(cmd); - return; - } - bv_->unlockInset(bv_->theLockingInset()); - } - - if (!inset_hit) - selection_possible = true; - screen().hideCursor(); - - // Clear the selection - screen().toggleSelection(bv_->text, bv_); - bv_->text->clearSelection(); - bv_->text->fullRebreak(bv_); - update(); - updateScrollbar(); - - // Single left click in math inset? - if (isHighlyEditableInset(inset_hit)) { - // Highly editable inset, like math - UpdatableInset * inset = static_cast(inset_hit); - selection_possible = false; - owner_->updateLayoutChoice(); - owner_->message(inset->editMessage()); - //inset->edit(bv_, xpos, ypos, button); - // We just have to lock the inset before calling a PressEvent on it! - // we don't need the edit() call here! (Jug20020329) - if (!bv_->lockInset(inset)) { - lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; - } - FuncRequest cmd(bv_, LFUN_MOUSE_PRESS, xpos, ypos, button); - inset->localDispatch(cmd); - return; - } - // I'm not sure we should continue here if we hit an inset (Jug20020403) - - // Right click on a footnote flag opens float menu - if (button == mouse_button::button3) { - selection_possible = false; - return; - } - - if (!inset_hit) // otherwise it was already set in checkInsetHit(...) - bv_->text->setCursorFromCoordinates(bv_, xpos, ypos + screen_first); - finishUndo(); - bv_->text->selection.cursor = bv_->text->cursor; - bv_->text->cursor.x_fix(bv_->text->cursor.x()); - - owner_->updateLayoutChoice(); - if (fitCursor()) { - selection_possible = false; - } - - // Insert primary selection with middle mouse - // if there is a local selection in the current buffer, - // insert this - if (button == mouse_button::button2) { - if (paste_internally) - owner_->dispatch(FuncRequest(LFUN_PASTE)); - else - owner_->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph")); - selection_possible = false; - return; - } -} - - -void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, mouse_button::state button) -{ - if (!buffer_) - return; - - LyXText * text = bv_->getLyXText(); - - if (text->bv_owner && bv_->theLockingInset()) - return; - - if (button == mouse_button::button1) { - if (text->bv_owner) { - screen().hideCursor(); - screen().toggleSelection(text, bv_); - text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); - screen().toggleSelection(text, bv_, false); - } else { - text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); - } - // This will fit the cursor on the screen if necessary - update(text, BufferView::SELECT|BufferView::FITCUR); - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } -} - - -void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, mouse_button::state button) -{ - if (!buffer_) - return; - - LyXText * text = bv_->getLyXText(); - - if (text->bv_owner && bv_->theLockingInset()) - return; - - if (button == mouse_button::button1) { - if (text->bv_owner) { - screen().hideCursor(); - screen().toggleSelection(text, bv_); - } - text->cursorHome(bv_); - text->selection.cursor = text->cursor; - text->cursorEnd(bv_); - text->setSelection(bv_); - if (text->bv_owner) { - screen().toggleSelection(text, bv_, false); - } - // This will fit the cursor on the screen if necessary - update(text, BufferView::SELECT|BufferView::FITCUR); - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } -} - - void BufferView::Pimpl::selectionRequested() { static string sel; @@ -757,118 +519,6 @@ void BufferView::Pimpl::selectionLost() } -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; -} - - - Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y) { @@ -1349,8 +999,13 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) bool BufferView::Pimpl::dispatch(FuncRequest const & ev) { - lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action[" - << ev.action <<"] arg[" << ev.argument << "]" << endl; + lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:" + << " action[" << ev.action <<"]" + << " arg[" << ev.argument << "]" + << " x[" << ev.x << "]" + << " y[" << ev.y << "]" + << " button[" << ev.button() << "]" + << endl; LyXTextClass const & tclass = buffer_->params.getLyXTextClass(); @@ -1770,10 +1425,353 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) ev.errorMessage(N_("Unknown function!")); break; + case LFUN_MOUSE_TRIPLE: + { + if (!buffer_) + return false; + + LyXText * text = bv_->getLyXText(); + + if (text->bv_owner && bv_->theLockingInset()) + return false; + + if (ev.button() == mouse_button::button1) { + if (text->bv_owner) { + screen().hideCursor(); + screen().toggleSelection(text, bv_); + } + text->cursorHome(bv_); + text->selection.cursor = text->cursor; + text->cursorEnd(bv_); + text->setSelection(bv_); + if (text->bv_owner) + screen().toggleSelection(text, bv_, false); + // This will fit the cursor on the screen if necessary + update(text, BufferView::SELECT|BufferView::FITCUR); + workarea().haveSelection(bv_->getLyXText()->selection.set()); + } + break; + } + + case LFUN_MOUSE_DOUBLE: + { + if (!buffer_) + return false; + + LyXText * text = bv_->getLyXText(); + + if (text->bv_owner && bv_->theLockingInset()) + return false; + + if (ev.button() == mouse_button::button1) { + if (text->bv_owner) { + screen().hideCursor(); + screen().toggleSelection(text, bv_); + text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); + screen().toggleSelection(text, bv_, false); + } else { + text->selectWord(bv_, LyXText::WHOLE_WORD_STRICT); + } + // This will fit the cursor on the screen if necessary + update(text, BufferView::SELECT|BufferView::FITCUR); + workarea().haveSelection(bv_->getLyXText()->selection.set()); + } + break; + } + + case LFUN_MOUSE_MOTION: + { + // Only use motion with button 1 + //if (ev.button() != mouse_button::button1) + // return false; + + if (!buffer_) + return false; + + // Check for inset locking + if (bv_->theLockingInset()) { + LyXCursor cursor = bv_->text->cursor; + LyXFont font = bv_->text->getFont(buffer_, + cursor.par(), cursor.pos()); + int width = bv_->theLockingInset()->width(bv_, font); + int inset_x = font.isVisibleRightToLeft() + ? cursor.ix() - width : cursor.ix(); + int start_x = inset_x + bv_->theLockingInset()->scroll(); + + FuncRequest cmd(bv_, LFUN_MOUSE_MOTION, + ev.x - start_x, ev.y - cursor.iy() + bv_->text->first_y, ev.button()); + bv_->theLockingInset()->localDispatch(cmd); + return false; + } + + // 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"; + return false; + } + + screen().hideCursor(); + + Row * cursorrow = bv_->text->cursor.row(); + bv_->text->setCursorFromCoordinates(bv_, ev.x, ev.y + bv_->text->first_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->cursor.row()) { + if (ev.y >= int(workarea().workHeight())) { + bv_->text->cursorDown(bv_, false); + } else if (ev.y < 0) { + bv_->text->cursorUp(bv_, false); + } + } + + if (!bv_->text->selection.set()) + update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted + + bv_->text->setSelection(bv_); + screen().toggleToggle(bv_->text, bv_); + fitCursor(); + showCursor(); + break; + } + + // Single-click on work area + case LFUN_MOUSE_PRESS: + { + if (!buffer_) + return false; + + // ok ok, this is a hack (for xforms) + if (ev.button() == mouse_button::button4) { + scroll(-lyxrc.wheel_jump); + // 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). + return false; + } + if (ev.button() == mouse_button::button5) { + scroll(lyxrc.wheel_jump); + // 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). + return false; + } + + int x = ev.x; + int y = ev.y; + Inset * inset_hit = checkInsetHit(bv_->text, 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 (ev.button() == mouse_button::button2 + && bv_->getLyXText()->selection.set()) + { + owner_->dispatch(FuncRequest(LFUN_COPY)); + paste_internally = true; + } + + int const screen_first = bv_->text->first_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 cmd(bv_, LFUN_MOUSE_PRESS, x, y, ev.button()); + bv_->theLockingInset()->localDispatch(cmd); + return false; + } + bv_->unlockInset(bv_->theLockingInset()); + } + + if (!inset_hit) + selection_possible = true; + screen().hideCursor(); + + // Clear the selection + screen().toggleSelection(bv_->text, bv_); + bv_->text->clearSelection(); + bv_->text->fullRebreak(bv_); + update(); + updateScrollbar(); + + // Single left click in math inset? + if (isHighlyEditableInset(inset_hit)) { + // Highly editable inset, like math + UpdatableInset * inset = static_cast(inset_hit); + selection_possible = false; + owner_->updateLayoutChoice(); + owner_->message(inset->editMessage()); + //inset->edit(bv_, x, y, ev.button()); + // We just have to lock the inset before calling a PressEvent on it! + // we don't need the edit() call here! (Jug20020329) + if (!bv_->lockInset(inset)) { + lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; + } + FuncRequest cmd(bv_, LFUN_MOUSE_PRESS, x, y, ev.button()); + inset->localDispatch(cmd); + return false; + } + // I'm not sure we should continue here if we hit an inset (Jug20020403) + + // Right click on a footnote flag opens float menu + if (ev.button() == mouse_button::button3) { + selection_possible = false; + return false; + } + + if (!inset_hit) // otherwise it was already set in checkInsetHit(...) + bv_->text->setCursorFromCoordinates(bv_, x, y + screen_first); + finishUndo(); + bv_->text->selection.cursor = bv_->text->cursor; + bv_->text->cursor.x_fix(bv_->text->cursor.x()); + + owner_->updateLayoutChoice(); + if (fitCursor()) { + selection_possible = false; + } + + // Insert primary selection with middle mouse + // if there is a local selection in the current buffer, + // insert this + if (ev.button() == mouse_button::button2) { + if (paste_internally) + owner_->dispatch(FuncRequest(LFUN_PASTE)); + else + owner_->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph")); + selection_possible = false; + return false; + } + break; + } + + case LFUN_MOUSE_RELEASE: + { + // do nothing if we used the mouse wheel + if (!buffer_ + || ev.button() == mouse_button::button4 + || ev.button() == mouse_button::button5) + return false; + + // 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 = ev.x; + int y = ev.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, ev.button()); + bv_->theLockingInset()->localDispatch(cmd); + return false; + } + + selection_possible = false; + + if (ev.button() == mouse_button::button2) + return false; + + // finish selection + if (ev.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 false; + + // 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, ev.button()); + inset->localDispatch(cmd); + } else { + FuncRequest cmd(bv_, LFUN_MOUSE_RELEASE, x, y, ev.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, ev.button()); + } + return false; + } + + // 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 false; + } + default: - FuncRequest cmd = ev; - cmd.setView(bv_); - return bv_->getLyXText()->dispatch(cmd); + return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_)); } // end of switch return true; diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index df5292b32a..b1832f9b36 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -13,7 +13,6 @@ #include "BufferView.h" #include "frontends/Timeout.h" #include "frontends/key_state.h" -#include "frontends/mouse_state.h" #include "frontends/LyXKeySym.h" #include "support/types.h" @@ -27,6 +26,7 @@ class LyXView; class WorkArea; class LyXScreen; +class FuncRequest; /// struct BufferView::Pimpl : public boost::signals::trackable { @@ -73,16 +73,6 @@ struct BufferView::Pimpl : public boost::signals::trackable { /// void workAreaKeyPress(LyXKeySymPtr key, key_modifier::state state); /// - void workAreaMotionNotify(int x, int y, mouse_button::state state); - /// - void workAreaButtonPress(int x, int y, mouse_button::state button); - /// - void workAreaButtonRelease(int x, int y, mouse_button::state button); - /// - void doubleClick(int x, int y, mouse_button::state button); - /// - void tripleClick(int x, int y, mouse_button::state button); - /// void selectionRequested(); /// void selectionLost(); diff --git a/src/ChangeLog b/src/ChangeLog index 77b6d4cd9f..69bd7f322e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,4 +1,12 @@ +2002-08-28 André Pönitz + + * commandtags.h: new LFUN_MOUSE_DOUBLE, LFUN_MOUSE_TRIPLE + + * BufferView.h: + * BufferView_pimpl.[Ch] move work area mouse event to LFUNs + 2002-08-28 Rob Lahaye + * buffer.C: increment LYX_FORMAT to 221 * lyxrc.[Ch]: declare display_graphics as grfx::DisplayType and use diff --git a/src/buffer.C b/src/buffer.C index 335037aa3d..5d4745abbe 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -1154,6 +1154,7 @@ bool Buffer::readFile(LyXLex & lex, Paragraph * par) if (dot != string::npos) tmp_format.erase(dot, 1); file_format = strToInt(tmp_format); + //lyxerr << "format: " << file_format << endl; if (file_format == LYX_FORMAT) { // current format } else if (file_format > LYX_FORMAT) { diff --git a/src/commandtags.h b/src/commandtags.h index dcd1e1e019..1ef2827646 100644 --- a/src/commandtags.h +++ b/src/commandtags.h @@ -286,6 +286,8 @@ enum kb_action { LFUN_MOUSE_PRESS, // André 9 Aug 2002 LFUN_MOUSE_MOTION, // André 9 Aug 2002 LFUN_MOUSE_RELEASE, // André 9 Aug 2002 + LFUN_MOUSE_DOUBLE, // André 9 Aug 2002 + LFUN_MOUSE_TRIPLE, // André 9 Aug 2002 LFUN_EDIT, // André 16 Aug 2002 LFUN_LASTACTION /* this marks the end of the table */ }; diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index 07317cff66..0d73022ea6 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,8 @@ + +2002-08-28 André Pönitz + + * WorkArea.h: replace bunch of mouse event handler by 'dispatch' handler + 2002-08-20 Lars Gullik Bjønnes * Dialogs.h (noncopyable): ws changes only diff --git a/src/frontends/WorkArea.h b/src/frontends/WorkArea.h index 7ecf1aad60..b586530c8f 100644 --- a/src/frontends/WorkArea.h +++ b/src/frontends/WorkArea.h @@ -11,9 +11,9 @@ #ifndef WORKAREA_H #define WORKAREA_H -#include "frontends/mouse_state.h" #include "frontends/key_state.h" #include "frontends/LyXKeySym.h" +#include "funcrequest.h" #include #include @@ -68,16 +68,8 @@ public: boost::signal1 scrollDocView; /// a key combination has been pressed boost::signal2 workAreaKeyPress; - /// a mouse button has been pressed - boost::signal3 workAreaButtonPress; - /// a mouse button has been released - boost::signal3 workAreaButtonRelease; - /// the mouse has moved - boost::signal3 workAreaMotionNotify; - /// a mouse button has been double-clicked - boost::signal3 workAreaDoubleClick; - /// a mouse button has been triple-clicked - boost::signal3 workAreaTripleClick; + /// some mouse event + boost::signal1 dispatch; /// emitted when an X client has requested our selection boost::signal0 selectionRequested; /// emitted when another X client has stolen our selection diff --git a/src/frontends/qt2/QContentPane.C b/src/frontends/qt2/QContentPane.C index ff63407603..dd1aed4d53 100644 --- a/src/frontends/qt2/QContentPane.C +++ b/src/frontends/qt2/QContentPane.C @@ -16,6 +16,7 @@ #include "QWorkArea.h" #include "QLyXKeySym.h" +#include "funcrequest.h" #include #include @@ -96,19 +97,25 @@ void QContentPane::scrollBarChanged(int val) void QContentPane::mousePressEvent(QMouseEvent * e) { - wa_->workAreaButtonPress(e->x(), e->y(), q_button_state(e->button())); + FuncRequest cmd + (LFUN_MOUSE_PRESS, e->x(), e->y(), q_button_state(e->button())); + wa_->dispatch(cmd); } void QContentPane::mouseReleaseEvent(QMouseEvent * e) { - wa_->workAreaButtonRelease(e->x(), e->y(), q_button_state(e->button())); + FuncRequest cmd + (LFUN_MOUSE_RELEASE, e->x(), e->y(), q_button_state(e->button())); + wa_->dispatch(cmd); } void QContentPane::mouseMoveEvent(QMouseEvent * e) { - wa_->workAreaMotionNotify(e->x(), e->y(), q_motion_state(e->state())); + FuncRequest cmd + (LFUN_MOUSE_RELEASE, e->x(), e->y(), q_motion_state(e->button())); + wa_->dispatch(cmd); } @@ -125,7 +132,9 @@ void QContentPane::keyPressEvent(QKeyEvent * e) void QContentPane::mouseDoubleClickEvent(QMouseEvent * e) { - wa_->workAreaDoubleClick(e->x(), e->y(), q_button_state(e->state())); + FuncRequest cmd + (LFUN_MOUSE_DOUBLE, e->x(), e->y(), q_button_state(e->button())); + wa_->dispatch(cmd); // FIXME: triple click } diff --git a/src/frontends/xforms/XWorkArea.C b/src/frontends/xforms/XWorkArea.C index bf55552598..3ba600e83d 100644 --- a/src/frontends/xforms/XWorkArea.C +++ b/src/frontends/xforms/XWorkArea.C @@ -18,6 +18,7 @@ #include "LyXView.h" #include "XLyXKeySym.h" #include "ColorHandler.h" +#include "funcrequest.h" #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5)) #include "lyxlookup.h" @@ -351,24 +352,27 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, if (!ev || ev->xbutton.button == 0) break; // Should really have used xbutton.state lyxerr[Debug::WORKAREA] << "Workarea event: PUSH" << endl; - area->workAreaButtonPress(ev->xbutton.x - ob->x, - ev->xbutton.y - ob->y, - x_button_state(ev->xbutton.button)); + area->dispatch( + FuncRequest(LFUN_MOUSE_PRESS, ev->xbutton.x - ob->x, + ev->xbutton.y - ob->y, + x_button_state(ev->xbutton.button))); break; case FL_RELEASE: if (!ev || ev->xbutton.button == 0) break; // Should really have used xbutton.state lyxerr[Debug::WORKAREA] << "Workarea event: RELEASE" << endl; - area->workAreaButtonRelease(ev->xbutton.x - ob->x, - ev->xbutton.y - ob->y, - x_button_state(ev->xbutton.button)); + area->dispatch( + FuncRequest(LFUN_MOUSE_RELEASE, ev->xbutton.x - ob->x, + ev->xbutton.y - ob->y, + x_button_state(ev->xbutton.button))); break; #if FL_VERSION < 1 && FL_REVISION < 89 case FL_MOUSE: #else case FL_DRAG: #endif - if (!ev || ! area->scrollbar) break; + if (!ev || !area->scrollbar) + break; if (ev->xmotion.x != x_old || ev->xmotion.y != y_old || fl_get_scrollbar_value(area->scrollbar) != scrollbar_value_old @@ -377,9 +381,10 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, y_old = ev->xmotion.y; scrollbar_value_old = fl_get_scrollbar_value(area->scrollbar); lyxerr[Debug::WORKAREA] << "Workarea event: MOUSE" << endl; - area->workAreaMotionNotify(ev->xmotion.x - ob->x, - ev->xmotion.y - ob->y, - x_motion_state(ev->xbutton.state)); + area->dispatch( + FuncRequest(LFUN_MOUSE_MOTION, ev->xbutton.x - ob->x, + ev->xbutton.y - ob->y, + x_button_state(ev->xbutton.button))); } break; #if FL_VERSION < 1 && FL_REVISION < 89 @@ -510,22 +515,26 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, lyxerr[Debug::WORKAREA] << "Workarea event: LEAVE" << endl; break; case FL_DBLCLICK: - if (!ev) break; - lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl; - area->workAreaDoubleClick(ev->xbutton.x - ob->x, - ev->xbutton.y - ob->y, - x_button_state(ev->xbutton.button)); + if (ev) { + lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl; + FuncRequest cmd(LFUN_MOUSE_DOUBLE, ev->xbutton.x - ob->x, + ev->xbutton.y - ob->y, + x_button_state(ev->xbutton.button)); + area->dispatch(cmd); + } break; case FL_TRPLCLICK: - if (!ev) break; - lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl; - area->workAreaTripleClick(ev->xbutton.x - ob->x, - ev->xbutton.y - ob->y, - x_button_state(ev->xbutton.button)); + if (ev) { + lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl; + FuncRequest cmd(LFUN_MOUSE_TRIPLE, ev->xbutton.x - ob->x, + ev->xbutton.y - ob->y, + x_button_state(ev->xbutton.button)); + area->dispatch(cmd); + } break; case FL_OTHER: - if (!ev) break; - lyxerr[Debug::WORKAREA] << "Workarea event: OTHER" << endl; + if (ev) + lyxerr[Debug::WORKAREA] << "Workarea event: OTHER" << endl; break; } diff --git a/src/funcrequest.C b/src/funcrequest.C index 31c6409846..c9e5865956 100644 --- a/src/funcrequest.C +++ b/src/funcrequest.C @@ -28,6 +28,12 @@ FuncRequest::FuncRequest(kb_action act, string const & arg) {} +FuncRequest::FuncRequest + (kb_action act, int ax, int ay, mouse_button::state button) + : view_(0), action(act), argument(), x(ax), y(ay), button_(button) +{} + + FuncRequest::FuncRequest(BufferView * view, kb_action act) : view_(view), action(act) {} @@ -44,13 +50,18 @@ FuncRequest::FuncRequest {} - FuncRequest::FuncRequest(FuncRequest const & cmd, string const & arg) : view_(cmd.view_), action(cmd.action), argument(arg), x(cmd.x), y(cmd.y), button_(cmd.button_) {} +FuncRequest::FuncRequest(FuncRequest const & cmd, BufferView * view) + : view_(view), action(cmd.action), argument(cmd.argument), + x(cmd.x), y(cmd.y), button_(cmd.button_) +{} + + BufferView * FuncRequest::view() const { return view_; diff --git a/src/funcrequest.h b/src/funcrequest.h index a03d953081..037cbb32ed 100644 --- a/src/funcrequest.h +++ b/src/funcrequest.h @@ -25,22 +25,26 @@ public: FuncRequest(); /// actions without extra argument explicit FuncRequest(kb_action act); + /// actions without extra argument + FuncRequest(kb_action act, int x, int y, mouse_button::state button); /// actions with extra argument FuncRequest(kb_action act, string const & arg); /// actions without extra argument - FuncRequest(BufferView * view, kb_action act); + FuncRequest(BufferView * bv, kb_action act); /// actions with extra argument - FuncRequest(BufferView * view, kb_action act, string const & arg); + FuncRequest(BufferView * bv, kb_action act, string const & arg); /// for mouse events - FuncRequest(BufferView * view, kb_action act, + FuncRequest(BufferView * bv, kb_action act, int x, int y, mouse_button::state button); /// for changing requests a bit FuncRequest(FuncRequest const & cmd, string const & arg); + /// for changing requests a bit + FuncRequest(FuncRequest const & cmd, BufferView * bv); /// access to the view BufferView * view() const; /// access to the view - void setView(BufferView * view); + void setView(BufferView * bv); /// access to button mouse_button::state button() const; diff --git a/src/lyxrc.C b/src/lyxrc.C index a6cb86e308..e7d25273a6 100644 --- a/src/lyxrc.C +++ b/src/lyxrc.C @@ -730,7 +730,7 @@ int LyXRC::read(string const & filename) { string lyx_name, x11_name; - if (lexrc.next()) { + if (lexrc.next()) { lyx_name = lexrc.getString(); } else { lexrc.printError("Missing color tag."); diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index 3f333fe95a..e8f1d9a53f 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -77,6 +77,8 @@ libmathed_la_SOURCES = \ math_gridinset.h \ math_hullinset.C \ math_hullinset.h \ + math_inferinset.C \ + math_inferinset.h \ math_inset.C \ math_inset.h \ math_iterator.C \ diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index 5dd795b5ac..c1604d03d0 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -14,6 +14,7 @@ #include "math_fontoldinset.h" #include "math_fracinset.h" #include "math_kerninset.h" +#include "math_inferinset.h" #include "math_lefteqninset.h" #include "math_macro.h" #include "math_macrotable.h" @@ -241,6 +242,8 @@ MathAtom createMathInset(string const & s) return MathAtom(new MathBinomInset(s == "choose")); if (s == "over" || s == "frac") return MathAtom(new MathFracInset); + //if (s == "infer") + // return MathAtom(new MathInferInset); if (s == "atop") return MathAtom(new MathFracInset(true)); if (s == "lefteqn") diff --git a/src/mathed/math_inferinset.C b/src/mathed/math_inferinset.C new file mode 100644 index 0000000000..61d49081f6 --- /dev/null +++ b/src/mathed/math_inferinset.C @@ -0,0 +1,44 @@ +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "math_inferinset.h" +#include "math_support.h" +#include "frontends/Painter.h" +#include "math_mathmlstream.h" +#include "textpainter.h" + + +using std::max; + + +MathInferInset::MathInferInset() + : MathGridInset(1, 1) +{} + + +MathInset * MathInferInset::clone() const +{ + return new MathInferInset(*this); +} + + +void MathInferInset::metrics(MathMetricsInfo &) const +{ +} + + +void MathInferInset::draw(MathPainterInfo &, int, int) const +{ +} + + +void MathInferInset::write(WriteStream & os) const +{ + os << "\\infer"; + if (opt_.size()) + os << "[" << opt_ << "]"; + MathGridInset::write(os); +} + + diff --git a/src/mathed/math_inferinset.h b/src/mathed/math_inferinset.h new file mode 100644 index 0000000000..ce496f4de9 --- /dev/null +++ b/src/mathed/math_inferinset.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +#ifndef MATH_INFERINSET_H +#define MATH_INFERINSET_H + +#include "math_gridinset.h" + +#ifdef __GNUG__ +#pragma interface +#endif + +/** for proof.sty's \infer + \author André Poenitz + */ +class MathInferInset : public MathGridInset { +public: + /// + explicit MathInferInset(); + /// + MathInset * clone() const; + /// + void metrics(MathMetricsInfo & mi) const; + /// + void draw(MathPainterInfo & pi, int x, int y) const; + /// + void write(WriteStream & os) const; + +public: + /// + MathArray opt_; +}; + +#endif diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index f8224ab5c0..993ddbd62a 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -1077,6 +1077,13 @@ void Parser::parse1(MathGridInset & grid, unsigned flags, } #if 0 + else if (t.cs() == "infer") { + MathArray ar; + parse(ar, FLAG_OPTION, mode); + cell->push_back(createMathInset(t.cs())); + parse2(cell->back(), FLAG_ITEM, mode, false); + } + // Disabled else if (1 && t.cs() == "ar") { MathXYArrowInset * p = new MathXYArrowInset; -- 2.39.2