the workarea changes plus small math stuff

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@5128 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2002-08-28 08:30:27 +00:00
parent 6af5ac769a
commit 3c7c7a3209
18 changed files with 531 additions and 413 deletions

View File

@ -190,6 +190,7 @@ public:
void stuffClipboard(string const &) const; void stuffClipboard(string const &) const;
/// ///
bool dispatch(FuncRequest const & argument); bool dispatch(FuncRequest const & argument);
private: private:
/// ///
struct Pimpl; struct Pimpl;

View File

@ -20,6 +20,7 @@
#include "frontends/Dialogs.h" #include "frontends/Dialogs.h"
#include "frontends/Alert.h" #include "frontends/Alert.h"
#include "frontends/FileDialog.h" #include "frontends/FileDialog.h"
#include "frontends/mouse_state.h"
#include "lyxtext.h" #include "lyxtext.h"
#include "lyxrow.h" #include "lyxrow.h"
#include "paragraph.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. // to these connections we avoid a segfault upon startup, and also at exit.
// (Lgb) // (Lgb)
boost::signals::connection dispatchcon;
boost::signals::connection timecon; boost::signals::connection timecon;
boost::signals::connection doccon; boost::signals::connection doccon;
boost::signals::connection resizecon; 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 kpresscon;
boost::signals::connection selectioncon; boost::signals::connection selectioncon;
boost::signals::connection lostcon; boost::signals::connection lostcon;
@ -193,16 +190,8 @@ BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner,
.connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); .connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1));
resizecon = workarea().workAreaResize resizecon = workarea().workAreaResize
.connect(boost::bind(&BufferView::Pimpl::workAreaResize, this)); .connect(boost::bind(&BufferView::Pimpl::workAreaResize, this));
bpresscon = workarea().workAreaButtonPress dispatchcon = workarea().dispatch
.connect(boost::bind(&BufferView::Pimpl::workAreaButtonPress, this, _1, _2, _3)); .connect(boost::bind(&BufferView::Pimpl::dispatch, this, _1));
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));
kpresscon = workarea().workAreaKeyPress kpresscon = workarea().workAreaKeyPress
.connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2)); .connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2));
selectioncon = workarea().selectionRequested 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<UpdatableInset *>(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() void BufferView::Pimpl::selectionRequested()
{ {
static string sel; 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) 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) bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
{ {
lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action[" lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
<< ev.action <<"] arg[" << ev.argument << "]" << endl; << " action[" << ev.action <<"]"
<< " arg[" << ev.argument << "]"
<< " x[" << ev.x << "]"
<< " y[" << ev.y << "]"
<< " button[" << ev.button() << "]"
<< endl;
LyXTextClass const & tclass = buffer_->params.getLyXTextClass(); LyXTextClass const & tclass = buffer_->params.getLyXTextClass();
@ -1770,10 +1425,353 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
ev.errorMessage(N_("Unknown function!")); ev.errorMessage(N_("Unknown function!"));
break; 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<UpdatableInset *>(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: default:
FuncRequest cmd = ev; return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_));
cmd.setView(bv_);
return bv_->getLyXText()->dispatch(cmd);
} // end of switch } // end of switch
return true; return true;

View File

@ -13,7 +13,6 @@
#include "BufferView.h" #include "BufferView.h"
#include "frontends/Timeout.h" #include "frontends/Timeout.h"
#include "frontends/key_state.h" #include "frontends/key_state.h"
#include "frontends/mouse_state.h"
#include "frontends/LyXKeySym.h" #include "frontends/LyXKeySym.h"
#include "support/types.h" #include "support/types.h"
@ -27,6 +26,7 @@
class LyXView; class LyXView;
class WorkArea; class WorkArea;
class LyXScreen; class LyXScreen;
class FuncRequest;
/// ///
struct BufferView::Pimpl : public boost::signals::trackable { 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 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 selectionRequested();
/// ///
void selectionLost(); void selectionLost();

View File

@ -1,4 +1,12 @@
2002-08-28 André Pönitz <poenitz@gmx.net>
* 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 <lahaye@snu.ac.kr> 2002-08-28 Rob Lahaye <lahaye@snu.ac.kr>
* buffer.C: increment LYX_FORMAT to 221 * buffer.C: increment LYX_FORMAT to 221
* lyxrc.[Ch]: declare display_graphics as grfx::DisplayType and use * lyxrc.[Ch]: declare display_graphics as grfx::DisplayType and use

View File

@ -1154,6 +1154,7 @@ bool Buffer::readFile(LyXLex & lex, Paragraph * par)
if (dot != string::npos) if (dot != string::npos)
tmp_format.erase(dot, 1); tmp_format.erase(dot, 1);
file_format = strToInt(tmp_format); file_format = strToInt(tmp_format);
//lyxerr << "format: " << file_format << endl;
if (file_format == LYX_FORMAT) { if (file_format == LYX_FORMAT) {
// current format // current format
} else if (file_format > LYX_FORMAT) { } else if (file_format > LYX_FORMAT) {

View File

@ -286,6 +286,8 @@ enum kb_action {
LFUN_MOUSE_PRESS, // André 9 Aug 2002 LFUN_MOUSE_PRESS, // André 9 Aug 2002
LFUN_MOUSE_MOTION, // André 9 Aug 2002 LFUN_MOUSE_MOTION, // André 9 Aug 2002
LFUN_MOUSE_RELEASE, // 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_EDIT, // André 16 Aug 2002
LFUN_LASTACTION /* this marks the end of the table */ LFUN_LASTACTION /* this marks the end of the table */
}; };

View File

@ -1,3 +1,8 @@
2002-08-28 André Pönitz <poenitz@gmx.net>
* WorkArea.h: replace bunch of mouse event handler by 'dispatch' handler
2002-08-20 Lars Gullik Bjønnes <larsbj@gullik.net> 2002-08-20 Lars Gullik Bjønnes <larsbj@gullik.net>
* Dialogs.h (noncopyable): ws changes only * Dialogs.h (noncopyable): ws changes only

View File

@ -11,9 +11,9 @@
#ifndef WORKAREA_H #ifndef WORKAREA_H
#define WORKAREA_H #define WORKAREA_H
#include "frontends/mouse_state.h"
#include "frontends/key_state.h" #include "frontends/key_state.h"
#include "frontends/LyXKeySym.h" #include "frontends/LyXKeySym.h"
#include "funcrequest.h"
#include <boost/signals/signal0.hpp> #include <boost/signals/signal0.hpp>
#include <boost/signals/signal1.hpp> #include <boost/signals/signal1.hpp>
@ -68,16 +68,8 @@ public:
boost::signal1<void, int> scrollDocView; boost::signal1<void, int> scrollDocView;
/// a key combination has been pressed /// a key combination has been pressed
boost::signal2<void, LyXKeySymPtr, key_modifier::state> workAreaKeyPress; boost::signal2<void, LyXKeySymPtr, key_modifier::state> workAreaKeyPress;
/// a mouse button has been pressed /// some mouse event
boost::signal3<void, int, int, mouse_button::state> workAreaButtonPress; boost::signal1<void, FuncRequest> dispatch;
/// a mouse button has been released
boost::signal3<void, int, int, mouse_button::state> workAreaButtonRelease;
/// the mouse has moved
boost::signal3<void, int, int, mouse_button::state> workAreaMotionNotify;
/// a mouse button has been double-clicked
boost::signal3<void, int, int, mouse_button::state> workAreaDoubleClick;
/// a mouse button has been triple-clicked
boost::signal3<void, int, int, mouse_button::state> workAreaTripleClick;
/// emitted when an X client has requested our selection /// emitted when an X client has requested our selection
boost::signal0<void> selectionRequested; boost::signal0<void> selectionRequested;
/// emitted when another X client has stolen our selection /// emitted when another X client has stolen our selection

View File

@ -16,6 +16,7 @@
#include "QWorkArea.h" #include "QWorkArea.h"
#include "QLyXKeySym.h" #include "QLyXKeySym.h"
#include "funcrequest.h"
#include <qevent.h> #include <qevent.h>
#include <qpainter.h> #include <qpainter.h>
@ -96,19 +97,25 @@ void QContentPane::scrollBarChanged(int val)
void QContentPane::mousePressEvent(QMouseEvent * e) 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) 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) 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) 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 // FIXME: triple click
} }

View File

@ -18,6 +18,7 @@
#include "LyXView.h" #include "LyXView.h"
#include "XLyXKeySym.h" #include "XLyXKeySym.h"
#include "ColorHandler.h" #include "ColorHandler.h"
#include "funcrequest.h"
#if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5)) #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5))
#include "lyxlookup.h" #include "lyxlookup.h"
@ -351,24 +352,27 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
if (!ev || ev->xbutton.button == 0) break; if (!ev || ev->xbutton.button == 0) break;
// Should really have used xbutton.state // Should really have used xbutton.state
lyxerr[Debug::WORKAREA] << "Workarea event: PUSH" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: PUSH" << endl;
area->workAreaButtonPress(ev->xbutton.x - ob->x, area->dispatch(
ev->xbutton.y - ob->y, FuncRequest(LFUN_MOUSE_PRESS, ev->xbutton.x - ob->x,
x_button_state(ev->xbutton.button)); ev->xbutton.y - ob->y,
x_button_state(ev->xbutton.button)));
break; break;
case FL_RELEASE: case FL_RELEASE:
if (!ev || ev->xbutton.button == 0) break; if (!ev || ev->xbutton.button == 0) break;
// Should really have used xbutton.state // Should really have used xbutton.state
lyxerr[Debug::WORKAREA] << "Workarea event: RELEASE" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: RELEASE" << endl;
area->workAreaButtonRelease(ev->xbutton.x - ob->x, area->dispatch(
ev->xbutton.y - ob->y, FuncRequest(LFUN_MOUSE_RELEASE, ev->xbutton.x - ob->x,
x_button_state(ev->xbutton.button)); ev->xbutton.y - ob->y,
x_button_state(ev->xbutton.button)));
break; break;
#if FL_VERSION < 1 && FL_REVISION < 89 #if FL_VERSION < 1 && FL_REVISION < 89
case FL_MOUSE: case FL_MOUSE:
#else #else
case FL_DRAG: case FL_DRAG:
#endif #endif
if (!ev || ! area->scrollbar) break; if (!ev || !area->scrollbar)
break;
if (ev->xmotion.x != x_old || if (ev->xmotion.x != x_old ||
ev->xmotion.y != y_old || ev->xmotion.y != y_old ||
fl_get_scrollbar_value(area->scrollbar) != scrollbar_value_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; y_old = ev->xmotion.y;
scrollbar_value_old = fl_get_scrollbar_value(area->scrollbar); scrollbar_value_old = fl_get_scrollbar_value(area->scrollbar);
lyxerr[Debug::WORKAREA] << "Workarea event: MOUSE" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: MOUSE" << endl;
area->workAreaMotionNotify(ev->xmotion.x - ob->x, area->dispatch(
ev->xmotion.y - ob->y, FuncRequest(LFUN_MOUSE_MOTION, ev->xbutton.x - ob->x,
x_motion_state(ev->xbutton.state)); ev->xbutton.y - ob->y,
x_button_state(ev->xbutton.button)));
} }
break; break;
#if FL_VERSION < 1 && FL_REVISION < 89 #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; lyxerr[Debug::WORKAREA] << "Workarea event: LEAVE" << endl;
break; break;
case FL_DBLCLICK: case FL_DBLCLICK:
if (!ev) break; if (ev) {
lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl;
area->workAreaDoubleClick(ev->xbutton.x - ob->x, FuncRequest cmd(LFUN_MOUSE_DOUBLE, ev->xbutton.x - ob->x,
ev->xbutton.y - ob->y, ev->xbutton.y - ob->y,
x_button_state(ev->xbutton.button)); x_button_state(ev->xbutton.button));
area->dispatch(cmd);
}
break; break;
case FL_TRPLCLICK: case FL_TRPLCLICK:
if (!ev) break; if (ev) {
lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl;
area->workAreaTripleClick(ev->xbutton.x - ob->x, FuncRequest cmd(LFUN_MOUSE_TRIPLE, ev->xbutton.x - ob->x,
ev->xbutton.y - ob->y, ev->xbutton.y - ob->y,
x_button_state(ev->xbutton.button)); x_button_state(ev->xbutton.button));
area->dispatch(cmd);
}
break; break;
case FL_OTHER: case FL_OTHER:
if (!ev) break; if (ev)
lyxerr[Debug::WORKAREA] << "Workarea event: OTHER" << endl; lyxerr[Debug::WORKAREA] << "Workarea event: OTHER" << endl;
break; break;
} }

View File

@ -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) FuncRequest::FuncRequest(BufferView * view, kb_action act)
: view_(view), action(act) : view_(view), action(act)
{} {}
@ -44,13 +50,18 @@ FuncRequest::FuncRequest
{} {}
FuncRequest::FuncRequest(FuncRequest const & cmd, string const & arg) FuncRequest::FuncRequest(FuncRequest const & cmd, string const & arg)
: view_(cmd.view_), action(cmd.action), argument(arg), : view_(cmd.view_), action(cmd.action), argument(arg),
x(cmd.x), y(cmd.y), button_(cmd.button_) 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 BufferView * FuncRequest::view() const
{ {
return view_; return view_;

View File

@ -25,22 +25,26 @@ public:
FuncRequest(); FuncRequest();
/// actions without extra argument /// actions without extra argument
explicit FuncRequest(kb_action act); 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 /// actions with extra argument
FuncRequest(kb_action act, string const & arg); FuncRequest(kb_action act, string const & arg);
/// actions without extra argument /// actions without extra argument
FuncRequest(BufferView * view, kb_action act); FuncRequest(BufferView * bv, kb_action act);
/// actions with extra argument /// 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 /// for mouse events
FuncRequest(BufferView * view, kb_action act, FuncRequest(BufferView * bv, kb_action act,
int x, int y, mouse_button::state button); int x, int y, mouse_button::state button);
/// for changing requests a bit /// for changing requests a bit
FuncRequest(FuncRequest const & cmd, string const & arg); FuncRequest(FuncRequest const & cmd, string const & arg);
/// for changing requests a bit
FuncRequest(FuncRequest const & cmd, BufferView * bv);
/// access to the view /// access to the view
BufferView * view() const; BufferView * view() const;
/// access to the view /// access to the view
void setView(BufferView * view); void setView(BufferView * bv);
/// access to button /// access to button
mouse_button::state button() const; mouse_button::state button() const;

View File

@ -730,7 +730,7 @@ int LyXRC::read(string const & filename)
{ {
string lyx_name, x11_name; string lyx_name, x11_name;
if (lexrc.next()) { if (lexrc.next()) {
lyx_name = lexrc.getString(); lyx_name = lexrc.getString();
} else { } else {
lexrc.printError("Missing color tag."); lexrc.printError("Missing color tag.");

View File

@ -77,6 +77,8 @@ libmathed_la_SOURCES = \
math_gridinset.h \ math_gridinset.h \
math_hullinset.C \ math_hullinset.C \
math_hullinset.h \ math_hullinset.h \
math_inferinset.C \
math_inferinset.h \
math_inset.C \ math_inset.C \
math_inset.h \ math_inset.h \
math_iterator.C \ math_iterator.C \

View File

@ -14,6 +14,7 @@
#include "math_fontoldinset.h" #include "math_fontoldinset.h"
#include "math_fracinset.h" #include "math_fracinset.h"
#include "math_kerninset.h" #include "math_kerninset.h"
#include "math_inferinset.h"
#include "math_lefteqninset.h" #include "math_lefteqninset.h"
#include "math_macro.h" #include "math_macro.h"
#include "math_macrotable.h" #include "math_macrotable.h"
@ -241,6 +242,8 @@ MathAtom createMathInset(string const & s)
return MathAtom(new MathBinomInset(s == "choose")); return MathAtom(new MathBinomInset(s == "choose"));
if (s == "over" || s == "frac") if (s == "over" || s == "frac")
return MathAtom(new MathFracInset); return MathAtom(new MathFracInset);
//if (s == "infer")
// return MathAtom(new MathInferInset);
if (s == "atop") if (s == "atop")
return MathAtom(new MathFracInset(true)); return MathAtom(new MathFracInset(true));
if (s == "lefteqn") if (s == "lefteqn")

View File

@ -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);
}

View File

@ -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

View File

@ -1077,6 +1077,13 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
} }
#if 0 #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 // Disabled
else if (1 && t.cs() == "ar") { else if (1 && t.cs() == "ar") {
MathXYArrowInset * p = new MathXYArrowInset; MathXYArrowInset * p = new MathXYArrowInset;