X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=34b5a478e357034a93c92d4a0ff62c214eb557a7;hb=dad1fc66e44a4dad94eb1e9ffd5736bf8f59ae6d;hp=0eff78a4fe135c05143771e52f27ac6b92e104da;hpb=64488b06afe0db0f6d598e5b54505413b33b0855;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 0eff78a4fe..34b5a478e3 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -8,10 +8,6 @@ #include -#ifdef __GNUG__ -#pragma implementation -#endif - #include "BufferView_pimpl.h" #include "frontends/WorkArea.h" #include "frontends/screen.h" @@ -20,6 +16,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" @@ -39,60 +36,37 @@ #include "gettext.h" #include "ParagraphParameters.h" #include "undo_funcs.h" -#include "lyxtextclasslist.h" +#include "funcrequest.h" +#include "iterators.h" +#include "lyxfind.h" #include "insets/insetbib.h" #include "insets/insettext.h" -#include "insets/inseturl.h" #include "insets/insetlatexaccent.h" #include "insets/insettoc.h" -#include "insets/insetref.h" -#include "insets/insetparent.h" #include "insets/insetindex.h" -#include "insets/insetnote.h" +#include "insets/insetref.h" #include "insets/insetinclude.h" #include "insets/insetcite.h" -#include "insets/insetert.h" -#include "insets/insetexternal.h" #include "insets/insetgraphics.h" -#include "insets/insetfoot.h" #include "insets/insetmarginal.h" -#include "insets/insetminipage.h" -#include "insets/insetfloat.h" -#include "insets/insettabular.h" -#if 0 -#include "insets/insettheorem.h" -#include "insets/insetlist.h" -#endif -#include "insets/insetcaption.h" #include "insets/insetfloatlist.h" -#include "insets/insetspecialchar.h" #include "mathed/formulabase.h" +#include "graphics/Previews.h" + #include "support/LAssert.h" #include "support/lstrings.h" #include "support/filetools.h" -#include "support/lyxfunctional.h" #include +#include +#include "BoostFormat.h" -#include -#include #include #include -#include - -extern string current_layout; - -#ifndef CXX_GLOBAL_CSTD -using std::tm; -using std::localtime; -using std::time; -using std::setlocale; -using std::strftime; -#endif using std::vector; using std::find_if; @@ -103,56 +77,55 @@ using std::make_pair; using std::min; using lyx::pos_type; -using lyx::textclass_type; - -/* the selection possible is needed, that only motion events are - * used, where the bottom press event was on the drawing area too */ -bool selection_possible = false; extern BufferList bufferlist; -extern char ascii_type; - -extern int bibitemMaxWidth(BufferView *, LyXFont const &); namespace { -const unsigned int saved_positions_num = 20; +unsigned int const saved_positions_num = 20; + +// All the below connection objects are needed because of a bug in some +// versions of GCC (<=2.96 are on the suspects list.) By having and assigning +// 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 kpresscon; +boost::signals::connection selectioncon; +boost::signals::connection lostcon; } // anon namespace -BufferView::Pimpl::Pimpl(BufferView * b, LyXView * o, +BufferView::Pimpl::Pimpl(BufferView * bv, LyXView * owner, int xpos, int ypos, int width, int height) - : bv_(b), owner_(o), buffer_(0), cursor_timeout(400), + : bv_(bv), owner_(owner), buffer_(0), cursor_timeout(400), using_xterm_cursor(false) { workarea_.reset(WorkAreaFactory::create(xpos, ypos, width, height)); screen_.reset(LyXScreenFactory::create(workarea())); - + // Setup the signals - workarea().scrollDocView.connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); - workarea().workAreaExpose - .connect(boost::bind(&BufferView::Pimpl::workAreaExpose, this)); - workarea().workAreaButtonPress - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonPress, this, _1, _2, _3)); - workarea().workAreaButtonRelease - .connect(boost::bind(&BufferView::Pimpl::workAreaButtonRelease, this, _1, _2, _3)); - workarea().workAreaMotionNotify - .connect(boost::bind(&BufferView::Pimpl::workAreaMotionNotify, this, _1, _2, _3)); - workarea().workAreaDoubleClick - .connect(boost::bind(&BufferView::Pimpl::doubleClick, this, _1, _2, _3)); - workarea().workAreaTripleClick - .connect(boost::bind(&BufferView::Pimpl::tripleClick, this, _1, _2, _3)); - workarea().workAreaKeyPress + doccon = workarea().scrollDocView + .connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); + resizecon = workarea().workAreaResize + .connect(boost::bind(&BufferView::Pimpl::workAreaResize, this)); + dispatchcon = workarea().dispatch + .connect(boost::bind(&BufferView::Pimpl::dispatch, this, _1)); + kpresscon = workarea().workAreaKeyPress .connect(boost::bind(&BufferView::Pimpl::workAreaKeyPress, this, _1, _2)); - workarea().selectionRequested + selectioncon = workarea().selectionRequested .connect(boost::bind(&BufferView::Pimpl::selectionRequested, this)); - workarea().selectionLost + lostcon = workarea().selectionLost .connect(boost::bind(&BufferView::Pimpl::selectionLost, this)); - cursor_timeout.timeout.connect(boost::bind(&BufferView::Pimpl::cursorToggle, this)); + timecon = cursor_timeout.timeout + .connect(boost::bind(&BufferView::Pimpl::cursorToggle, this)); cursor_timeout.start(); saved_positions.resize(saved_positions_num); } @@ -163,7 +136,7 @@ WorkArea & BufferView::Pimpl::workarea() const return *workarea_.get(); } - + LyXScreen & BufferView::Pimpl::screen() const { return *screen_.get(); @@ -179,7 +152,7 @@ Painter & BufferView::Pimpl::painter() const void BufferView::Pimpl::buffer(Buffer * b) { lyxerr[Debug::INFO] << "Setting buffer in BufferView (" - << b << ")" << endl; + << b << ')' << endl; if (buffer_) { buffer_->delUser(bv_); @@ -194,12 +167,14 @@ void BufferView::Pimpl::buffer(Buffer * b) bv_->text = 0; } - // Set current buffer + // set current buffer buffer_ = b; - if (bufferlist.getState() == BufferList::CLOSING) return; + // if we're quitting lyx, don't bother updating stuff + if (quitting) + return; - // If we are closing the buffer, use the first buffer as current + // if we are closing the buffer, use the first buffer as current if (!buffer_) { buffer_ = bufferlist.first(); } @@ -207,28 +182,23 @@ void BufferView::Pimpl::buffer(Buffer * b) if (buffer_) { lyxerr[Debug::INFO] << "Buffer addr: " << buffer_ << endl; buffer_->addUser(bv_); + // If we don't have a text object for this, we make one if (bv_->text == 0) { resizeCurrentBuffer(); - } else { - updateScreen(); - updateScrollbar(); } - bv_->text->first_y = screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); - owner_->updateMenubar(); - owner_->updateToolbar(); + + // FIXME: needed when ? + bv_->text->first_y = + screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); + // Similarly, buffer-dependent dialogs should be updated or // hidden. This should go here because some dialogs (eg ToC) // require bv_->text. - owner_->getDialogs()->updateBufferDependent(true); - redraw(); + owner_->getDialogs().updateBufferDependent(true); } else { lyxerr[Debug::INFO] << " No Buffer!" << endl; - owner_->updateMenubar(); - owner_->updateToolbar(); - owner_->getDialogs()->hideBufferDependent(); - updateScrollbar(); - workarea().redraw(); + owner_->getDialogs().hideBufferDependent(); // Also remove all remaining text's from the testcache. // (there should not be any!) (if there is any it is a @@ -237,32 +207,16 @@ void BufferView::Pimpl::buffer(Buffer * b) textcache.show(lyxerr, "buffer delete all"); textcache.clear(); } - // should update layoutchoice even if we don't have a buffer. - owner_->updateLayoutChoice(); + repaint(); + updateScrollbar(); + owner_->updateMenubar(); + owner_->updateToolbar(); + owner_->updateLayoutChoice(); owner_->updateWindowTitle(); -} - - -void BufferView::Pimpl::resize(int xpos, int ypos, int width, int height) -{ - workarea().resize(xpos, ypos, width, height); - update(bv_->text, SELECT); - redraw(); -} - - -void BufferView::Pimpl::resize() -{ - if (buffer_) - resizeCurrentBuffer(); -} - -void BufferView::Pimpl::redraw() -{ - lyxerr[Debug::INFO] << "BufferView::redraw()" << endl; - workarea().redraw(); + if (grfx::Previews::activated() && buffer_) + grfx::Previews::get().generateBufferPreviews(*buffer_); } @@ -277,9 +231,9 @@ bool BufferView::Pimpl::fitCursor() ret = screen().fitCursor(bv_->text, bv_); } - bv_->owner()->getDialogs()->updateParagraph(); + bv_->owner()->getDialogs().updateParagraph(); if (ret) - updateScrollbar(); + updateScrollbar(); return ret; } @@ -288,8 +242,10 @@ void BufferView::Pimpl::redoCurrentBuffer() { lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl; if (buffer_ && bv_->text) { - resize(); + resizeCurrentBuffer(); + updateScrollbar(); owner_->updateLayoutChoice(); + repaint(); } } @@ -309,8 +265,8 @@ int BufferView::Pimpl::resizeCurrentBuffer() bool selection = false; bool mark_set = false; - owner_->prohibitInput(); - + owner_->busy(true); + owner_->message(_("Formatting document...")); if (bv_->text) { @@ -342,6 +298,8 @@ int BufferView::Pimpl::resizeCurrentBuffer() // bv_->text->owner(bv_); if (lyxerr.debugging()) textcache.show(lyxerr, "resizeCurrentBuffer"); + + buffer_->resizeInsets(bv_); } else { bv_->text = new LyXText(bv_); bv_->text->init(bv_); @@ -349,8 +307,6 @@ int BufferView::Pimpl::resizeCurrentBuffer() } } - updateScreen(); - if (par) { bv_->text->selection.set(true); // At this point just to avoid the Delete-Empty-Paragraph- @@ -373,21 +329,16 @@ int BufferView::Pimpl::resizeCurrentBuffer() bv_->text->first_y = screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); - // this will scroll the screen such that the cursor becomes visible - updateScrollbar(); - redraw(); - - setState(); - owner_->allowInput(); + switchKeyMap(); + owner_->busy(false); - /// clear the "Formatting Document" message - owner_->message(""); + updateScrollbar(); return 0; } -void BufferView::Pimpl::updateScreen() +void BufferView::Pimpl::repaint() { // Regenerate the screen. screen().redraw(bv_->text, bv_); @@ -403,8 +354,11 @@ void BufferView::Pimpl::updateScrollbar() } LyXText const & t = *bv_->text; - - workarea().setScrollbarParams(t.height, t.first_y, t.defaultHeight()); + + lyxerr[Debug::GUI] << "Updating scrollbar: h " << t.height << ", first_y " + << t.first_y << ", default height " << defaultRowHeight() << endl; + + workarea().setScrollbarParams(t.height, t.first_y, defaultRowHeight()); } @@ -412,17 +366,17 @@ void BufferView::Pimpl::scrollDocView(int value) { lyxerr[Debug::GUI] << "scrollDocView of " << value << endl; - if (!buffer_) return; + if (!buffer_) + return; screen().draw(bv_->text, bv_, value); - if (!lyxrc.cursor_follows_scrollbar) { + if (!lyxrc.cursor_follows_scrollbar) return; - } LyXText * vbt = bv_->text; - int const height = vbt->defaultHeight(); + int const height = defaultRowHeight(); int const first = static_cast((bv_->text->first_y + height)); int const last = static_cast((bv_->text->first_y + workarea().workHeight() - height)); @@ -433,256 +387,33 @@ void BufferView::Pimpl::scrollDocView(int value) } -int BufferView::Pimpl::scroll(long time) -{ - if (!buffer_) - return 0; - - LyXText const * t = bv_->text; - - double const diff = t->defaultHeight() - + double(time) * double(time) * 0.125; - - scrollDocView(int(diff)); - workarea().setScrollbarParams(t->height, t->first_y, t->defaultHeight()); - return 0; -} - - -void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, - key_modifier::state state) -{ - bv_->owner()->getLyXFunc()->processKeySym(key, state); -} - - -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(); - - bv_->theLockingInset()-> - insetMotionNotify(bv_, - x - start_x, - y - cursor.iy() + bv_->text->first_y, - state); - 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) +void BufferView::Pimpl::scroll(int lines) { - 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_->getLyXFunc()->dispatch(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()) { - bv_->theLockingInset()-> - insetButtonPress(bv_, xpos, ypos, button); - return; - } else { - 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; - } - inset->insetButtonPress(bv_, xpos, ypos, button); - 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_->getLyXFunc()->dispatch(LFUN_PASTE); - else - owner_->getLyXFunc()->dispatch(LFUN_PASTESELECTION, - "paragraph"); - selection_possible = false; + if (!buffer_) { return; } -} + LyXText const * t = bv_->text; + int const line_height = defaultRowHeight(); -void BufferView::Pimpl::doubleClick(int /*x*/, int /*y*/, mouse_button::state button) -{ - if (!buffer_) - return; + // The new absolute coordinate + int new_first_y = t->first_y + lines * line_height; - LyXText * text = bv_->getLyXText(); + // Restrict to a valid value + new_first_y = std::min(t->height - 4 * line_height, new_first_y); + new_first_y = std::max(0, new_first_y); - if (text->bv_owner && bv_->theLockingInset()) - return; + scrollDocView(new_first_y); - 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); - } + // Update the scrollbar. + workarea().setScrollbarParams(t->height, t->first_y, defaultRowHeight()); } -void BufferView::Pimpl::tripleClick(int /*x*/, int /*y*/, mouse_button::state button) +void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key, + key_modifier::state state) { - 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); - } + bv_->owner()->getLyXFunc().processKeySym(key, state); } @@ -724,202 +455,10 @@ 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 Event outside the inset will - force a insetUnlock. */ - bv_->theLockingInset()-> - insetButtonRelease(bv_, x, y, button); - return; - } - - selection_possible = false; - - if (button == mouse_button::button2) - return; - - // finish selection - if (button == mouse_button::button1) { - workarea().haveSelection(bv_->getLyXText()->selection.set()); - } - - setState(); - owner_->showState(); - 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; - inset->insetButtonRelease(bv_, x, y, button); - } else { - inset_hit->insetButtonRelease(bv_, x, y, button); - // 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) - inset_hit->edit(bv_, x, y, button); - } - return; - } - - // Maybe we want to edit a bibitem ale970302 - if (bv_->text->cursor.par()->bibkey && x < 20 + - bibitemMaxWidth(bv_, textclasslist[buffer_->params.textclass].defaultfont())) { - 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; -} - - -void BufferView::Pimpl::workAreaExpose() +void BufferView::Pimpl::workAreaResize() { static int work_area_width; - static unsigned int work_area_height; + static int work_area_height; bool const widthChange = workarea().workWidth() != work_area_width; bool const heightChange = workarea().workHeight() != work_area_height; @@ -927,10 +466,11 @@ void BufferView::Pimpl::workAreaExpose() // update from work area work_area_width = workarea().workWidth(); work_area_height = workarea().workHeight(); + if (buffer_ != 0) { if (widthChange) { // The visible LyXView need a resize - owner_->view()->resize(); + resizeCurrentBuffer(); // Remove all texts from the textcache // This is not _really_ what we want to do. What @@ -941,22 +481,18 @@ void BufferView::Pimpl::workAreaExpose() if (lyxerr.debugging()) textcache.show(lyxerr, "Expose delete all"); textcache.clear(); + // FIXME: this is already done in resizeCurrentBuffer() ?? buffer_->resizeInsets(bv_); } else if (heightChange) { - // Rebuild image of current screen - updateScreen(); // fitCursor() ensures we don't jump back // to the start of the document on vertical // resize fitCursor(); - - // The main window size has changed, repaint most stuff - redraw(); - } else { - screen().redraw(bv_->text, bv_); } - } else { - screen().redraw(bv_->text, bv_); + } + + if (widthChange || heightChange) { + repaint(); } // always make sure that the scrollbar is sane. @@ -1047,9 +583,9 @@ void BufferView::Pimpl::update(LyXText * text, BufferView::UpdateCodes f) if (text->inset_owner) { text->inset_owner->setUpdateStatus(bv_, InsetText::NONE); - updateInset(text->inset_owner, false); + updateInset(text->inset_owner, false); } else { - update(); + update(); } if ((f & FITCUR)) { @@ -1070,10 +606,6 @@ void BufferView::Pimpl::cursorToggle() return; } - /* FIXME */ - extern void reapSpellchecker(void); - reapSpellchecker(); - if (!bv_->theLockingInset()) { screen().cursorToggle(bv_); } else { @@ -1084,122 +616,30 @@ void BufferView::Pimpl::cursorToggle() } -void BufferView::Pimpl::cursorPrevious(LyXText * text) +bool BufferView::Pimpl::available() const { - if (!text->cursor.row()->previous()) { - if (text->first_y > 0) { - int new_y = bv_->text->first_y - workarea().workHeight(); - screen().draw(bv_->text, bv_, new_y < 0 ? 0 : new_y); - updateScrollbar(); - } - return; - } + if (buffer_ && bv_->text) + return true; + return false; +} - int y = text->first_y; - Row * cursorrow = text->cursor.row(); - text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); - finishUndo(); +Change const BufferView::Pimpl::getCurrentChange() +{ + if (!bv_->buffer()->params.tracking_changes) + return Change(Change::UNCHANGED); - int new_y; - if (cursorrow == bv_->text->cursor.row()) { - // we have a row which is higher than the workarea so we leave the - // cursor on the start of the row and move only the draw up as soon - // as we move the cursor or do something while inside the row (it may - // span several workarea-heights) we'll move to the top again, but this - // is better than just jump down and only display part of the row. - new_y = bv_->text->first_y - workarea().workHeight(); - } else { - if (text->inset_owner) { - new_y = bv_->text->cursor.iy() - + bv_->theLockingInset()->insetInInsetY() + y - + text->cursor.row()->height() - - workarea().workHeight() + 1; - } else { - new_y = text->cursor.y() - - text->cursor.row()->baseline() - + text->cursor.row()->height() - - workarea().workHeight() + 1; - } - } - screen().draw(bv_->text, bv_, new_y < 0 ? 0 : new_y); - if (text->cursor.row()->previous()) { - LyXCursor cur; - text->setCursor(bv_, cur, text->cursor.row()->previous()->par(), - text->cursor.row()->previous()->pos(), false); - if (cur.y() > text->first_y) { - text->cursorUp(bv_, true); - } - } - updateScrollbar(); + LyXText * t(bv_->getLyXText()); + + if (!t->selection.set()) + return Change(Change::UNCHANGED); + + LyXCursor const & cur(t->selection.start); + return cur.par()->lookupChangeFull(cur.pos()); } -void BufferView::Pimpl::cursorNext(LyXText * text) -{ - if (!text->cursor.row()->next()) { - int y = text->cursor.y() - text->cursor.row()->baseline() + - text->cursor.row()->height(); - if (y > int(text->first_y + workarea().workHeight())) { - screen().draw(bv_->text, bv_, - bv_->text->first_y + workarea().workHeight()); - updateScrollbar(); - } - return; - } - - int y = text->first_y + workarea().workHeight(); - if (text->inset_owner && !text->first_y) { - y -= (bv_->text->cursor.iy() - - bv_->text->first_y - + bv_->theLockingInset()->insetInInsetY()); - } - - text->getRowNearY(y); - - Row * cursorrow = text->cursor.row(); - text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); // + workarea().workHeight()); - finishUndo(); - - int new_y; - if (cursorrow == bv_->text->cursor.row()) { - // we have a row which is higher than the workarea so we leave the - // cursor on the start of the row and move only the draw down as soon - // as we move the cursor or do something while inside the row (it may - // span several workarea-heights) we'll move to the top again, but this - // is better than just jump down and only display part of the row. - new_y = bv_->text->first_y + workarea().workHeight(); - } else { - if (text->inset_owner) { - new_y = bv_->text->cursor.iy() - + bv_->theLockingInset()->insetInInsetY() - + y - text->cursor.row()->baseline(); - } else { - new_y = text->cursor.y() - text->cursor.row()->baseline(); - } - } - screen().draw(bv_->text, bv_, new_y); - if (text->cursor.row()->next()) { - LyXCursor cur; - text->setCursor(bv_, cur, text->cursor.row()->next()->par(), - text->cursor.row()->next()->pos(), false); - if (cur.y() < int(text->first_y + workarea().workHeight())) { - text->cursorDown(bv_, true); - } - } - updateScrollbar(); -} - - -bool BufferView::Pimpl::available() const -{ - if (buffer_ && bv_->text) - return true; - return false; -} - - -void BufferView::Pimpl::beforeChange(LyXText * text) +void BufferView::Pimpl::beforeChange(LyXText * text) { toggleSelection(); text->clearSelection(); @@ -1215,8 +655,12 @@ void BufferView::Pimpl::savePosition(unsigned int i) bv_->text->cursor.pos()); if (i > 0) { ostringstream str; - str << _("Saved bookmark") << ' ' << i; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Saved bookmark %1$d")) % i; +#else + str << _("Saved bookmark ") << i; +#endif + owner_->message(STRCONV(str.str())); } } @@ -1244,11 +688,15 @@ void BufferView::Pimpl::restorePosition(unsigned int i) bv_->text->setCursor(bv_, par, min(par->size(), saved_positions[i].par_pos)); - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); + update(bv_->text, BufferView::SELECT | BufferView::FITCUR); if (i > 0) { ostringstream str; - str << _("Moved to bookmark") << ' ' << i; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Moved to bookmark %1$d")) % i; +#else + str << _("Moved to bookmark ") << i; +#endif + owner_->message(STRCONV(str.str())); } } @@ -1262,7 +710,7 @@ bool BufferView::Pimpl::isSavedPosition(unsigned int i) } -void BufferView::Pimpl::setState() +void BufferView::Pimpl::switchKeyMap() { if (!lyxrc.rtl_support) return; @@ -1270,13 +718,13 @@ void BufferView::Pimpl::setState() LyXText * text = bv_->getLyXText(); if (text->real_current_font.isRightToLeft() && !(bv_->theLockingInset() - && bv_->theLockingInset()->lyxCode()== Inset::ERT_CODE)) + && bv_->theLockingInset()->lyxCode() == Inset::ERT_CODE)) { - if (owner_->getIntl()->keymap == Intl::PRIMARY) - owner_->getIntl()->KeyMapSec(); + if (owner_->getIntl().keymap == Intl::PRIMARY) + owner_->getIntl().KeyMapSec(); } else { - if (owner_->getIntl()->keymap == Intl::SECONDARY) - owner_->getIntl()->KeyMapPrim(); + if (owner_->getIntl().keymap == Intl::SECONDARY) + owner_->getIntl().KeyMapPrim(); } } @@ -1323,37 +771,28 @@ void BufferView::Pimpl::toggleToggle() void BufferView::Pimpl::center() { - beforeChange(bv_->text); - if (bv_->text->cursor.y() > static_cast((workarea().workHeight() / 2))) { - screen().draw(bv_->text, bv_, bv_->text->cursor.y() - workarea().workHeight() / 2); - } else { - screen().draw(bv_->text, bv_, 0); - } - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); - redraw(); -} - - -void BufferView::Pimpl::pasteClipboard(bool asPara) -{ - if (!buffer_) - return; + LyXText * t = bv_->text; - screen().hideCursor(); - beforeChange(bv_->text); + beforeChange(t); + int const half_height = workarea().workHeight() / 2; + int new_y = 0; - string const clip(workarea().getClipboard()); + if (t->cursor.y() > half_height) { + new_y = t->cursor.y() - half_height; + } - if (clip.empty()) - return; + // FIXME: can we do this w/o calling screen directly ? + // This updates first_y but means the fitCursor() call + // from the update(FITCUR) doesn't realise that we might + // have moved (e.g. from GOTOPARAGRAPH), so doesn't cause + // the scrollbar to be updated as it should, so we have + // to do it manually. Any operation that does a center() + // and also might have moved first_y must make sure to call + // updateScrollbar() currently. Never mind that this is a + // pretty obfuscated way of updating t->first_y + screen().draw(t, bv_, new_y); - if (asPara) { - bv_->getLyXText()->insertStringAsParagraphs(bv_, clip); - } else { - bv_->getLyXText()->insertStringAsLines(bv_, clip); - } - bv_->getLyXText()->clearSelection(); - update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); + update(t, BufferView::SELECT | BufferView::FITCUR); } @@ -1369,42 +808,9 @@ void BufferView::Pimpl::stuffClipboard(string const & stuff) const */ -inline -void BufferView::Pimpl::moveCursorUpdate(bool selecting, bool fitcur) -{ - LyXText * lt = bv_->getLyXText(); - - if (selecting || lt->selection.mark()) { - lt->setSelection(bv_); - if (lt->bv_owner) - toggleToggle(); - else - updateInset(lt->inset_owner, false); - } - if (lt->bv_owner) { - if (fitcur) - update(lt, BufferView::SELECT|BufferView::FITCUR); - else - update(lt, BufferView::SELECT); - showCursor(); - } else if (bv_->text->status() != LyXText::UNCHANGED) { - bv_->theLockingInset()->hideInsetCursor(bv_); - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); - showCursor(); - } - - if (!lt->selection.set()) - workarea().haveSelection(false); - - /* ---> Everytime the cursor is moved, show the current font state. */ - // should this too me moved out of this func? - //owner->showState(); - setState(); -} - - Inset * BufferView::Pimpl::getInsetByCode(Inset::Code code) { +#if 0 LyXCursor cursor = bv_->getLyXText()->cursor; Buffer::inset_iterator it = find_if(Buffer::inset_iterator( @@ -1412,6 +818,42 @@ Inset * BufferView::Pimpl::getInsetByCode(Inset::Code code) buffer_->inset_iterator_end(), lyx::compare_memfun(&Inset::lyxCode, code)); return it != buffer_->inset_iterator_end() ? (*it) : 0; +#else + // Ok, this is a little bit too brute force but it + // should work for now. Better infrastructure is comming. (Lgb) + + Buffer * b = bv_->buffer(); + LyXCursor cursor = bv_->getLyXText()->cursor; + + Buffer::inset_iterator beg = b->inset_iterator_begin(); + Buffer::inset_iterator end = b->inset_iterator_end(); + + bool cursor_par_seen = false; + + for (; beg != end; ++beg) { + if (beg.getPar() == cursor.par()) { + cursor_par_seen = true; + } + if (cursor_par_seen) { + if (beg.getPar() == cursor.par() + && beg.getPos() >= cursor.pos()) { + break; + } else if (beg.getPar() != cursor.par()) { + break; + } + } + + } + if (beg != end) { + // Now find the first inset that matches code. + for (; beg != end; ++beg) { + if (beg->lyxCode() == code) { + return &(*beg); + } + } + } + return 0; +#endif } @@ -1439,7 +881,7 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) string(AddPath(system_lyxdir, "examples")))); FileDialog::Result result = - fileDlg.Select(initpath, + fileDlg.open(initpath, _("*.lyx| LyX Documents (*.lyx)")); if (result.first == FileDialog::Later) @@ -1461,58 +903,90 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) string const disp_fn(MakeDisplayPath(filename)); ostringstream s1; - s1 << _("Inserting document") << ' ' - << disp_fn << " ..."; - owner_->message(s1.str().c_str()); +#if USE_BOOST_FORMAT + s1 << boost::format(_("Inserting document %1$s...")) % disp_fn; +#else + s1 << _("Inserting document ") << disp_fn << _("..."); +#endif + owner_->message(STRCONV(s1.str())); bool const res = bv_->insertLyXFile(filename); if (res) { ostringstream str; - str << _("Document") << ' ' << disp_fn - << ' ' << _("inserted."); - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Document %1$s inserted.")) % disp_fn; +#else + str << _("Document ") << disp_fn << _(" inserted."); +#endif + owner_->message(STRCONV(str.str())); } else { ostringstream str; - str << _("Could not insert document") << ' ' - << disp_fn; - owner_->message(str.str().c_str()); +#if USE_BOOST_FORMAT + str << boost::format(_("Could not insert document %1$s")) % disp_fn; +#else + str << _("Could not insert document ") << disp_fn; +#endif + owner_->message(STRCONV(str.str())); } } -bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) +void BufferView::Pimpl::trackChanges() { - lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch: action[" - << action <<"] arg[" << argument << "]" << endl; + Buffer * buf(bv_->buffer()); + bool const tracking(buf->params.tracking_changes); - LyXTextClass const & tclass = textclasslist[buffer_->params.textclass]; + if (!tracking) { + ParIterator const end = buf->par_iterator_end(); + for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) { + (*it)->trackChanges(); + } + buf->params.tracking_changes = true; - switch (action) { - // --- Misc ------------------------------------------- - case LFUN_APPENDIX: - { - if (available()) { - LyXText * lt = bv_->getLyXText(); - lt->toggleAppendix(bv_); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); + // we cannot allow undos beyond the freeze point + buf->undostack.clear(); + } else { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*buf->paragraphs.begin()), 0); +#warning changes FIXME + //moveCursorUpdate(false); + + bool found = lyxfind::findNextChange(bv_); + if (found) { + owner_->getDialogs().showMergeChanges(); + return; } - } - break; - case LFUN_TOC_INSERT: - { - InsetCommandParams p; - p.setCmdName("tableofcontents"); - Inset * inset = new InsetTOC(p); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - break; + ParIterator const end = buf->par_iterator_end(); + for (ParIterator it = buf->par_iterator_begin(); it != end; ++it) { + (*it)->untrackChanges(); + } + buf->params.tracking_changes = false; } + + buf->redostack.clear(); +} + + +bool BufferView::Pimpl::dispatch(FuncRequest const & ev) +{ + lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:" + << " action[" << ev.action << ']' + << " arg[" << ev.argument << ']' + << " x[" << ev.x << ']' + << " y[" << ev.y << ']' + << " button[" << ev.button() << ']' + << endl; + + // e.g. Qt mouse press when no buffer + if (!buffer_) + return false; + + LyXTextClass const & tclass = buffer_->params.getLyXTextClass(); + + switch (ev.action) { case LFUN_SCROLL_INSET: - // this is not handled here as this funktion is only aktive + // this is not handled here as this function is only active // if we have a locking_inset and that one is (or contains) // a tabular-inset break; @@ -1530,76 +1004,13 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; } - case LFUN_PASTE: - bv_->paste(); - setState(); - break; - - case LFUN_PASTESELECTION: - { - bool asPara = false; - if (argument == "paragraph") - asPara = true; - pasteClipboard(asPara); - } - break; - - case LFUN_CUT: - bv_->cut(); - break; - - case LFUN_COPY: - bv_->copy(); - break; - case LFUN_LAYOUT_COPY: bv_->copyEnvironment(); break; case LFUN_LAYOUT_PASTE: bv_->pasteEnvironment(); - setState(); - break; - - case LFUN_GOTOERROR: - gotoInset(Inset::ERROR_CODE, false); - break; - - case LFUN_GOTONOTE: - gotoInset(Inset::IGNORE_CODE, false); - break; - - case LFUN_REFERENCE_GOTO: - { - vector tmp; - tmp.push_back(Inset::LABEL_CODE); - tmp.push_back(Inset::REF_CODE); - gotoInset(tmp, true); - break; - } - - case LFUN_HYPHENATION: - specialChar(InsetSpecialChar::HYPHENATION); - break; - - case LFUN_LIGATURE_BREAK: - specialChar(InsetSpecialChar::LIGATURE_BREAK); - break; - - case LFUN_LDOTS: - specialChar(InsetSpecialChar::LDOTS); - break; - - case LFUN_END_OF_SENTENCE: - specialChar(InsetSpecialChar::END_OF_SENTENCE); - break; - - case LFUN_MENU_SEPARATOR: - specialChar(InsetSpecialChar::MENU_SEPARATOR); - break; - - case LFUN_HFILL: - hfill(); + switchKeyMap(); break; case LFUN_DEPTH_MIN: @@ -1611,216 +1022,87 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; case LFUN_FREE: - owner_->getDialogs()->setUserFreeFont(); + owner_->getDialogs().setUserFreeFont(); break; case LFUN_FILE_INSERT: - MenuInsertLyXFile(argument); + MenuInsertLyXFile(ev.argument); break; case LFUN_FILE_INSERT_ASCII_PARA: - InsertAsciiFile(bv_, argument, true); + InsertAsciiFile(bv_, ev.argument, true); break; case LFUN_FILE_INSERT_ASCII: - InsertAsciiFile(bv_, argument, false); + InsertAsciiFile(bv_, ev.argument, false); break; - case LFUN_LAYOUT: - { - lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) " - << argument << endl; - - // This is not the good solution to the empty argument - // problem, but it will hopefully suffice for 1.2.0. - // The correct solution would be to augument the - // function list/array with information about what - // functions needs arguments and their type. - if (argument.empty()) { - owner_->getLyXFunc()->setErrorMessage( - _("LyX function 'layout' needs an argument.")); - break; - } - - // Derive layout number from given argument (string) - // and current buffer's textclass (number). */ - bool hasLayout = tclass.hasLayout(argument); - string layout = argument; - - // If the entry is obsolete, use the new one instead. - if (hasLayout) { - string const & obs = tclass[layout].obsoleted_by(); - if (!obs.empty()) - layout = obs; - } - - if (!hasLayout) { - owner_->getLyXFunc()->setErrorMessage( - string(N_("Layout ")) + argument + - N_(" not known")); - break; - } - - bool change_layout = (current_layout != layout); - LyXText * lt = bv_->getLyXText(); - if (!change_layout && lt->selection.set() && - lt->selection.start.par() != lt->selection.end.par()) - { - Paragraph * spar = lt->selection.start.par(); - Paragraph * epar = lt->selection.end.par()->next(); - while(spar != epar) { - if (spar->layout() != current_layout) { - change_layout = true; - break; - } - } - } - if (change_layout) { - hideCursor(); - current_layout = layout; - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - lt->setLayout(bv_, layout); - owner_->setLayout(layout); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - setState(); - } - } - break; - case LFUN_LANGUAGE: - lang(bv_, argument); - setState(); - owner_->showState(); + lang(bv_, ev.argument); + switchKeyMap(); + owner_->view_state_changed(); break; case LFUN_EMPH: emph(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_BOLD: bold(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_NOUN: noun(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_CODE: code(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_SANS: sans(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_ROMAN: roman(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_DEFAULT: styleReset(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_UNDERLINE: underline(bv_); - owner_->showState(); + owner_->view_state_changed(); break; case LFUN_FONT_SIZE: - fontSize(bv_, argument); - owner_->showState(); + fontSize(bv_, ev.argument); + owner_->view_state_changed(); break; case LFUN_FONT_STATE: - owner_->getLyXFunc()->setMessage(currentState(bv_)); + owner_->getLyXFunc().setMessage(currentState(bv_)); break; - case LFUN_UPCASE_WORD: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - lt->changeCase(bv_, LyXText::text_uppercase); - if (lt->inset_owner) - updateInset(lt->inset_owner, true); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - break; - - case LFUN_LOWCASE_WORD: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->changeCase(bv_, LyXText::text_lowercase); - if (lt->inset_owner) - updateInset(lt->inset_owner, true); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - break; - - case LFUN_CAPITALIZE_WORD: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->changeCase(bv_, LyXText::text_capitalization); - if (lt->inset_owner) - updateInset(lt->inset_owner, true); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - break; - - case LFUN_TRANSPOSE_CHARS: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->transposeChars(*bv_); - if (lt->inset_owner) - updateInset(lt->inset_owner, true); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - break; - - case LFUN_INSERT_LABEL: - MenuInsertLabel(bv_, argument); + MenuInsertLabel(bv_, ev.argument); break; case LFUN_REF_INSERT: - if (argument.empty()) { + if (ev.argument.empty()) { InsetCommandParams p("ref"); - owner_->getDialogs()->createRef(p.getAsString()); + owner_->getDialogs().createRef(p.getAsString()); } else { InsetCommandParams p; - p.setFromString(argument); + p.setFromString(ev.argument); InsetRef * inset = new InsetRef(p, *buffer_); if (!insertInset(inset)) @@ -1831,16 +1113,16 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; case LFUN_BOOKMARK_SAVE: - savePosition(strToUnsignedInt(argument)); + savePosition(strToUnsignedInt(ev.argument)); break; case LFUN_BOOKMARK_GOTO: - restorePosition(strToUnsignedInt(argument)); + restorePosition(strToUnsignedInt(ev.argument)); break; case LFUN_REF_GOTO: { - string label(argument); + string label = ev.argument; if (label.empty()) { InsetRef * inset = static_cast(getInsetByCode(Inset::REF_CODE)); @@ -1860,1244 +1142,147 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) } break; - // --- Cursor Movements ----------------------------- - case LFUN_RIGHT: - { - LyXText * lt = bv_->getLyXText(); - - bool is_rtl = lt->cursor.par()->isRightToLeftPar(buffer_->params); - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - if (is_rtl) - lt->cursorLeft(bv_, false); - if (lt->cursor.pos() < lt->cursor.par()->size() - && lt->cursor.par()->isInset(lt->cursor.pos()) - && isHighlyEditableInset(lt->cursor.par()->getInset(lt->cursor.pos()))) { - Inset * tmpinset = lt->cursor.par()->getInset(lt->cursor.pos()); - owner_->getLyXFunc()->setMessage(tmpinset->editMessage()); - if (is_rtl) - tmpinset->edit(bv_, false); - else - tmpinset->edit(bv_); - break; - } - if (!is_rtl) - lt->cursorRight(bv_, false); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; + // --- accented characters --------------------------- - case LFUN_LEFT: - { - // This is soooo ugly. Isn`t it possible to make - // it simpler? (Lgb) - LyXText * lt = bv_->getLyXText(); - bool const is_rtl = lt->cursor.par()->isRightToLeftPar(buffer_->params); - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - LyXCursor const cur = lt->cursor; - if (!is_rtl) - lt->cursorLeft(bv_, false); - if ((is_rtl || cur != lt->cursor) && // only if really moved! - lt->cursor.pos() < lt->cursor.par()->size() && - lt->cursor.par()->isInset(lt->cursor.pos()) && - isHighlyEditableInset(lt->cursor.par()->getInset(lt->cursor.pos()))) { - Inset * tmpinset = lt->cursor.par()->getInset(lt->cursor.pos()); - owner_->getLyXFunc()->setMessage(tmpinset->editMessage()); - if (is_rtl) - tmpinset->edit(bv_); - else - tmpinset->edit(bv_, false); - break; + case LFUN_UMLAUT: + case LFUN_CIRCUMFLEX: + case LFUN_GRAVE: + case LFUN_ACUTE: + case LFUN_TILDE: + case LFUN_CEDILLA: + case LFUN_MACRON: + case LFUN_DOT: + case LFUN_UNDERDOT: + case LFUN_UNDERBAR: + case LFUN_CARON: + case LFUN_SPECIAL_CARON: + case LFUN_BREVE: + case LFUN_TIE: + case LFUN_HUNG_UMLAUT: + case LFUN_CIRCLE: + case LFUN_OGONEK: + if (ev.argument.empty()) { + // As always... + owner_->getLyXFunc().handleKeyFunc(ev.action); + } else { + owner_->getLyXFunc().handleKeyFunc(ev.action); + owner_->getIntl().getTransManager() + .TranslateAndInsert(ev.argument[0], bv_->getLyXText()); + update(bv_->getLyXText(), + BufferView::SELECT + | BufferView::FITCUR + | BufferView::CHANGE); } - if (is_rtl) - lt->cursorRight(bv_, false); + break; - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; + case LFUN_MATH_MACRO: + case LFUN_MATH_DELIM: + case LFUN_INSERT_MATRIX: + case LFUN_INSERT_MATH: + case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection + case LFUN_MATH_DISPLAY: // Open or create a displayed math inset + case LFUN_MATH_MODE: // Open or create an inlined math inset + case LFUN_GREEK: // Insert a single greek letter + mathDispatch(FuncRequest(bv_, ev.action, ev.argument)); + break; - case LFUN_UP: + case LFUN_CITATION_INSERT: { - LyXText * lt = bv_->getLyXText(); + InsetCommandParams p; + p.setFromString(ev.argument); + + InsetCitation * inset = new InsetCitation(p); + if (!insertInset(inset)) + delete inset; + else { + inset->setLoadingBuffer(bv_->buffer(), false); + updateInset(inset, true); + } - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorUp(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); } break; - case LFUN_DOWN: + case LFUN_INSERT_BIBTEX: { - LyXText * lt = bv_->getLyXText(); + // ale970405+lasgoutt970425 + // The argument can be up to two tokens separated + // by a space. The first one is the bibstyle. + string const db = token(ev.argument, ' ', 0); + string bibstyle = token(ev.argument, ' ', 1); + if (bibstyle.empty()) + bibstyle = "plain"; - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorDown(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); + InsetCommandParams p("BibTeX", db, bibstyle); + InsetBibtex * inset = new InsetBibtex(p); + + if (insertInset(inset)) { + if (ev.argument.empty()) + inset->edit(bv_); + } else + delete inset; } break; - case LFUN_UP_PARAGRAPH: + // BibTeX data bases + case LFUN_BIBDB_ADD: { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorUpParagraph(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); + InsetBibtex * inset = + static_cast(getInsetByCode(Inset::BIBTEX_CODE)); + if (inset) { + inset->addDatabase(ev.argument); + } } break; - case LFUN_DOWN_PARAGRAPH: + case LFUN_BIBDB_DEL: { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorDownParagraph(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); + InsetBibtex * inset = + static_cast(getInsetByCode(Inset::BIBTEX_CODE)); + if (inset) + inset->delDatabase(ev.argument); } break; - case LFUN_PRIOR: + case LFUN_BIBTEX_STYLE: { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - cursorPrevious(lt); - finishUndo(); - moveCursorUpdate(false, false); - owner_->showState(); + InsetBibtex * inset = + static_cast(getInsetByCode(Inset::BIBTEX_CODE)); + if (inset) + inset->setOptions(ev.argument); } break; - case LFUN_NEXT: + case LFUN_CHILD_INSERT: { - LyXText * lt = bv_->getLyXText(); + InsetInclude::Params p; + if (!ev.argument.empty()) + p.cparams.setFromString(ev.argument); + p.masterFilename_ = buffer_->fileName(); - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - cursorNext(lt); - finishUndo(); - moveCursorUpdate(false, false); - owner_->showState(); - } - break; - - case LFUN_HOME: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorHome(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_END: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorEnd(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_SHIFT_TAB: - case LFUN_TAB: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorTab(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_WORDRIGHT: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorLeftOneWord(bv_); - else - lt->cursorRightOneWord(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_WORDLEFT: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorRightOneWord(bv_); - else - lt->cursorLeftOneWord(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_BEGINNINGBUF: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorTop(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - case LFUN_ENDBUF: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorBottom(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - /* cursor selection ---------------------------- */ - case LFUN_RIGHTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorLeft(bv_); - else - lt->cursorRight(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_LEFTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorRight(bv_); - else - lt->cursorLeft(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_UPSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorUp(bv_, true); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_DOWNSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorDown(bv_, true); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_UP_PARAGRAPHSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorUpParagraph(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_DOWN_PARAGRAPHSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorDownParagraph(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_PRIORSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - cursorPrevious(lt); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_NEXTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - cursorNext(lt); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_HOMESEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorHome(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_ENDSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorEnd(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_WORDRIGHTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorLeftOneWord(bv_); - else - lt->cursorRightOneWord(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_WORDLEFTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - if (lt->cursor.par()->isRightToLeftPar(buffer_->params)) - lt->cursorRightOneWord(bv_); - else - lt->cursorLeftOneWord(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_BEGINNINGBUFSEL: - { - LyXText * lt = bv_->getLyXText(); - - if (lt->inset_owner) - break; - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorTop(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - case LFUN_ENDBUFSEL: - { - LyXText * lt = bv_->getLyXText(); - - if (lt->inset_owner) - break; - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorBottom(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->showState(); - } - break; - - // --- text changing commands ------------------------ - case LFUN_BREAKLINE: - { - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - lt->insertChar(bv_, Paragraph::META_NEWLINE); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - lt->setCursor(bv_, lt->cursor.par(), lt->cursor.pos()); - moveCursorUpdate(false); - } - break; - - case LFUN_PROTECTEDSPACE: - { - LyXText * lt = bv_->getLyXText(); - - LyXLayout const & style = tclass[lt->cursor.par()->layout()]; - - if (style.free_spacing) { - lt->insertChar(bv_, ' '); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } else { - specialChar(InsetSpecialChar::PROTECTED_SEPARATOR); - } - moveCursorUpdate(false); - } - break; - - case LFUN_SETMARK: - { - LyXText * lt = bv_->getLyXText(); - - if (lt->selection.mark()) { - beforeChange(lt); - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - owner_->getLyXFunc()->setMessage(N_("Mark removed")); - } else { - beforeChange(lt); - lt->selection.mark(true); - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - owner_->getLyXFunc()->setMessage(N_("Mark set")); - } - lt->selection.cursor = lt->cursor; - } - break; - - case LFUN_DELETE: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.set()) { - lt->Delete(bv_); - lt->selection.cursor = lt->cursor; - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - // It is possible to make it a lot faster still - // just comment out the line below... - showCursor(); - } else { - bv_->cut(false); - } - moveCursorUpdate(false); - owner_->showState(); - setState(); - } - break; - - case LFUN_DELETE_SKIP: - { - LyXText * lt = bv_->getLyXText(); - - // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP. - - LyXCursor cursor = lt->cursor; - - if (!lt->selection.set()) { - if (cursor.pos() == cursor.par()->size()) { - lt->cursorRight(bv_); - cursor = lt->cursor; - if (cursor.pos() == 0 - && !(cursor.par()->params().spaceTop() - == VSpace (VSpace::NONE))) { - lt->setParagraph - (bv_, - cursor.par()->params().lineTop(), - cursor.par()->params().lineBottom(), - cursor.par()->params().pagebreakTop(), - cursor.par()->params().pagebreakBottom(), - VSpace(VSpace::NONE), - cursor.par()->params().spaceBottom(), - cursor.par()->params().spacing(), - cursor.par()->params().align(), - cursor.par()->params().labelWidthString(), 0); - lt->cursorLeft(bv_); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } else { - lt->cursorLeft(bv_); - lt->Delete(bv_); - lt->selection.cursor = lt->cursor; - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - } else { - lt->Delete(bv_); - lt->selection.cursor = lt->cursor; - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - } else { - bv_->cut(false); - } - } - break; - - /* -------> Delete word forward. */ - case LFUN_DELETE_WORD_FORWARD: - update(bv_->getLyXText(), BufferView::SELECT|BufferView::FITCUR); - bv_->getLyXText()->deleteWordForward(bv_); - update(bv_->getLyXText(), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); - moveCursorUpdate(false); - owner_->showState(); - break; - - /* -------> Delete word backward. */ - case LFUN_DELETE_WORD_BACKWARD: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->deleteWordBackward(bv_); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - moveCursorUpdate(false); - owner_->showState(); - } - break; - - /* -------> Kill to end of line. */ - case LFUN_DELETE_LINE_FORWARD: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->deleteLineForward(bv_); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - moveCursorUpdate(false); - } - break; - - /* -------> Set mark off. */ - case LFUN_MARK_OFF: - { - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->selection.cursor = lt->cursor; - owner_->getLyXFunc()->setMessage(N_("Mark off")); - } - break; - - /* -------> Set mark on. */ - case LFUN_MARK_ON: - { - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - lt->selection.mark(true); - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->selection.cursor = lt->cursor; - owner_->getLyXFunc()->setMessage(N_("Mark on")); - } - break; - - case LFUN_BACKSPACE: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.set()) { - if (owner_->getIntl()->getTransManager().backspace()) { - lt->backspace(bv_); - lt->selection.cursor = lt->cursor; - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - // It is possible to make it a lot faster still - // just comment out the line below... - showCursor(); - } - } else { - bv_->cut(false); - } - owner_->showState(); - setState(); - } - break; - - case LFUN_BACKSPACE_SKIP: - { - // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP. - LyXText * lt = bv_->getLyXText(); - - LyXCursor cursor = lt->cursor; - - if (!lt->selection.set()) { - if (cursor.pos() == 0 - && !(cursor.par()->params().spaceTop() - == VSpace (VSpace::NONE))) { - lt->setParagraph - (bv_, - cursor.par()->params().lineTop(), - cursor.par()->params().lineBottom(), - cursor.par()->params().pagebreakTop(), - cursor.par()->params().pagebreakBottom(), - VSpace(VSpace::NONE), cursor.par()->params().spaceBottom(), - cursor.par()->params().spacing(), - cursor.par()->params().align(), - cursor.par()->params().labelWidthString(), 0); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } else { - lt->backspace(bv_); - lt->selection.cursor = cursor; - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - } else - bv_->cut(false); - } - break; - - case LFUN_BREAKPARAGRAPH: - { - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - lt->breakParagraph(bv_, 0); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - lt->selection.cursor = lt->cursor; - setState(); - owner_->showState(); - break; - } - - case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - { - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - lt->breakParagraph(bv_, 1); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - lt->selection.cursor = lt->cursor; - setState(); - owner_->showState(); - break; - } - - case LFUN_BREAKPARAGRAPH_SKIP: - { - // When at the beginning of a paragraph, remove - // indentation and add a "defskip" at the top. - // Otherwise, do the same as LFUN_BREAKPARAGRAPH. - LyXText * lt = bv_->getLyXText(); - - LyXCursor cursor = lt->cursor; - - beforeChange(lt); - if (cursor.pos() == 0) { - if (cursor.par()->params().spaceTop() == VSpace(VSpace::NONE)) { - lt->setParagraph - (bv_, - cursor.par()->params().lineTop(), - cursor.par()->params().lineBottom(), - cursor.par()->params().pagebreakTop(), - cursor.par()->params().pagebreakBottom(), - VSpace(VSpace::DEFSKIP), cursor.par()->params().spaceBottom(), - cursor.par()->params().spacing(), - cursor.par()->params().align(), - cursor.par()->params().labelWidthString(), 1); - //update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); - } - } - else { - lt->breakParagraph(bv_, 0); - //update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); - } - - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - lt->selection.cursor = cursor; - setState(); - owner_->showState(); - } - break; - - case LFUN_PARAGRAPH_SPACING: - { - LyXText * lt = bv_->getLyXText(); - - Paragraph * par = lt->cursor.par(); - Spacing::Space cur_spacing = par->params().spacing().getSpace(); - float cur_value = 1.0; - if (cur_spacing == Spacing::Other) { - cur_value = par->params().spacing().getValue(); - } - - istringstream istr(argument.c_str()); - - string tmp; - istr >> tmp; - Spacing::Space new_spacing = cur_spacing; - float new_value = cur_value; - if (tmp.empty()) { - lyxerr << "Missing argument to `paragraph-spacing'" - << endl; - } else if (tmp == "single") { - new_spacing = Spacing::Single; - } else if (tmp == "onehalf") { - new_spacing = Spacing::Onehalf; - } else if (tmp == "double") { - new_spacing = Spacing::Double; - } else if (tmp == "other") { - new_spacing = Spacing::Other; - float tmpval = 0.0; - istr >> tmpval; - lyxerr << "new_value = " << tmpval << endl; - if (tmpval != 0.0) - new_value = tmpval; - } else if (tmp == "default") { - new_spacing = Spacing::Default; - } else { - lyxerr << _("Unknown spacing argument: ") - << argument << endl; - } - if (cur_spacing != new_spacing || cur_value != new_value) { - par->params().spacing(Spacing(new_spacing, new_value)); - lt->redoParagraph(bv_); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - } - break; - - case LFUN_INSET_TOGGLE: - { - LyXText * lt = bv_->getLyXText(); - hideCursor(); - beforeChange(lt); - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->toggleInset(bv_); - update(lt, BufferView::SELECT|BufferView::FITCUR); - setState(); - } - break; - - case LFUN_QUOTE: - smartQuote(); - break; - - case LFUN_HTMLURL: - case LFUN_URL: - { - InsetCommandParams p; - if (action == LFUN_HTMLURL) - p.setCmdName("htmlurl"); - else - p.setCmdName("url"); - owner_->getDialogs()->createUrl(p.getAsString()); - } - break; - - case LFUN_INSERT_URL: - { - InsetCommandParams p; - p.setFromString(argument); - - InsetUrl * inset = new InsetUrl(p); - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; - - case LFUN_INSET_ERT: - insertAndEditInset(new InsetERT(buffer_->params)); - break; - - case LFUN_INSET_EXTERNAL: - insertAndEditInset(new InsetExternal); - break; - - case LFUN_INSET_FOOTNOTE: - insertAndEditInset(new InsetFoot(buffer_->params)); - break; - - case LFUN_INSET_MARGINAL: - insertAndEditInset(new InsetMarginal(buffer_->params)); - break; - - case LFUN_INSET_MINIPAGE: - insertAndEditInset(new InsetMinipage(buffer_->params)); - break; - - case LFUN_INSERT_NOTE: - insertAndEditInset(new InsetNote(buffer_->params)); - break; - - case LFUN_INSET_FLOAT: - // check if the float type exist - if (floatList.typeExist(argument)) { - insertAndEditInset(new InsetFloat(buffer_->params, - argument)); - } else { - lyxerr << "Non-existent float type: " - << argument << endl; - } - break; - - case LFUN_INSET_WIDE_FLOAT: - // check if the float type exist - if (floatList.typeExist(argument)) { - InsetFloat * new_inset = - new InsetFloat(buffer_->params, argument); - new_inset->wide(true); - insertAndEditInset(new_inset); - } else { - lyxerr << "Non-existent float type: " - << argument << endl; - } - break; - -#if 0 - case LFUN_INSET_LIST: - insertAndEditInset(new InsetList); - break; - - case LFUN_INSET_THEOREM: - insertAndEditInset(new InsetTheorem); - break; -#endif - - case LFUN_INSET_CAPTION: - { - // Do we have a locking inset... - if (bv_->theLockingInset()) { - lyxerr << "Locking inset code: " - << static_cast(bv_->theLockingInset()->lyxCode()); - InsetCaption * new_inset = - new InsetCaption(buffer_->params); - new_inset->setOwner(bv_->theLockingInset()); - new_inset->setAutoBreakRows(true); - new_inset->setDrawFrame(0, InsetText::LOCKED); - new_inset->setFrameColor(0, LColor::captionframe); - if (insertInset(new_inset)) - new_inset->edit(bv_); - else - delete new_inset; - } - } - break; - - case LFUN_INSET_TABULAR: - { - int r = 2; - int c = 2; - if (!argument.empty()) - ::sscanf(argument.c_str(),"%d%d", &r, &c); - InsetTabular * new_inset = - new InsetTabular(*buffer_, r, c); - bool const rtl = - bv_->getLyXText()->real_current_font.isRightToLeft(); - if (!open_new_inset(new_inset, rtl)) - delete new_inset; - } - break; - - // --- lyxserver commands ---------------------------- - - case LFUN_CHARATCURSOR: - { - pos_type pos = bv_->getLyXText()->cursor.pos(); - if (pos < bv_->getLyXText()->cursor.par()->size()) - owner_->getLyXFunc()->setMessage( - tostr(bv_->getLyXText()->cursor.par()->getChar(pos))); - else - owner_->getLyXFunc()->setMessage("EOF"); - } - break; - - case LFUN_GETXY: - owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.x()) - + ' ' - + tostr(bv_->getLyXText()->cursor.y())); - break; - - case LFUN_SETXY: - { - int x = 0; - int y = 0; - if (::sscanf(argument.c_str(), " %d %d", &x, &y) != 2) { - lyxerr << "SETXY: Could not parse coordinates in '" - << argument << std::endl; - } - bv_->getLyXText()->setCursorFromCoordinates(bv_, x, y); - } - break; - - case LFUN_GETLAYOUT: - owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.par()->layout())); - break; - - case LFUN_GETFONT: - { - LyXFont & font = bv_->getLyXText()->current_font; - if (font.shape() == LyXFont::ITALIC_SHAPE) - owner_->getLyXFunc()->setMessage("E"); - else if (font.shape() == LyXFont::SMALLCAPS_SHAPE) - owner_->getLyXFunc()->setMessage("N"); - else - owner_->getLyXFunc()->setMessage("0"); - - } - break; - - // --- accented characters --------------------------- - - case LFUN_UMLAUT: - case LFUN_CIRCUMFLEX: - case LFUN_GRAVE: - case LFUN_ACUTE: - case LFUN_TILDE: - case LFUN_CEDILLA: - case LFUN_MACRON: - case LFUN_DOT: - case LFUN_UNDERDOT: - case LFUN_UNDERBAR: - case LFUN_CARON: - case LFUN_SPECIAL_CARON: - case LFUN_BREVE: - case LFUN_TIE: - case LFUN_HUNG_UMLAUT: - case LFUN_CIRCLE: - case LFUN_OGONEK: - if (argument.empty()) { - // As always... - owner_->getLyXFunc()->handleKeyFunc(action); - } else { - owner_->getLyXFunc()->handleKeyFunc(action); - owner_->getIntl()->getTransManager() - .TranslateAndInsert(argument[0], bv_->getLyXText()); - update(bv_->getLyXText(), - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - break; - - case LFUN_MATH: - mathDispatch(bv_, argument); - break; - - case LFUN_MATH_MACRO: - mathDispatchMathMacro(bv_, argument); - break; - - case LFUN_MATH_DELIM: - mathDispatchMathDelim(bv_, argument); - break; - - case LFUN_INSERT_MATRIX: - mathDispatchInsertMatrix(bv_, argument); - break; - - case LFUN_INSERT_MATH: - mathDispatchInsertMath(bv_, argument); - break; - - case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection - mathDispatchMathImportSelection(bv_, argument); - break; - - case LFUN_MATH_DISPLAY: // Open or create a displayed math inset - mathDispatchMathDisplay(bv_, argument); - break; - - case LFUN_MATH_MODE: // Open or create an inlined math inset - mathDispatchMathMode(bv_, argument); - break; - - case LFUN_GREEK: // Insert a single greek letter - mathDispatchGreek(bv_, argument); - break; - - case LFUN_CITATION_INSERT: - { - InsetCommandParams p; - p.setFromString(argument); - - InsetCitation * inset = new InsetCitation(p); - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; - - case LFUN_INSERT_BIBTEX: - { - // ale970405+lasgoutt970425 - // The argument can be up to two tokens separated - // by a space. The first one is the bibstyle. - string const db = token(argument, ' ', 0); - string const bibstyle = token(argument, ' ', 1); - - InsetCommandParams p("BibTeX", db, bibstyle); - InsetBibtex * inset = new InsetBibtex(p); - - if (insertInset(inset)) { - if (argument.empty()) - inset->edit(bv_); - } else - delete inset; - } - break; - - // BibTeX data bases - case LFUN_BIBDB_ADD: - { - InsetBibtex * inset = - static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { - inset->addDatabase(argument); - } - } - break; - - case LFUN_BIBDB_DEL: - { - InsetBibtex * inset = - static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { - inset->delDatabase(argument); - } - } - break; - - case LFUN_BIBTEX_STYLE: - { - InsetBibtex * inset = - static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { - inset->setOptions(argument); - } - } - break; - - case LFUN_INDEX_CREATE: - { - InsetCommandParams p("index"); - if (argument.empty()) { - string const idxstring(bv_->getLyXText()->getStringToIndex(bv_)); - p.setContents(idxstring); - } else { - p.setContents(argument); - } - - owner_->getDialogs()->createIndex(p.getAsString()); - } - break; - - case LFUN_INDEX_INSERT: - { - InsetCommandParams p; - p.setFromString(argument); - InsetIndex * inset = new InsetIndex(p); - - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; - - case LFUN_INDEX_INSERT_LAST: - { - string const idxstring(bv_->getLyXText()->getStringToIndex(bv_)); - if (!idxstring.empty()) { - owner_->message(_("Word `") - + idxstring + _(("' indexed."))); - InsetCommandParams p("index", idxstring); - InsetIndex * inset = new InsetIndex(p); - - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - } - break; - - case LFUN_INDEX_PRINT: - { - InsetCommandParams p("printindex"); - Inset * inset = new InsetPrintIndex(p); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - } - break; - - case LFUN_PARENTINSERT: - { - InsetCommandParams p("lyxparent", argument); - Inset * inset = new InsetParent(p, *buffer_); - if (!insertInset(inset, tclass.defaultLayoutName())) - delete inset; - } - - break; - - case LFUN_CHILD_INSERT: - { - InsetInclude::Params p; - p.cparams.setFromString(argument); - p.masterFilename_ = buffer_->fileName(); - - InsetInclude * inset = new InsetInclude(p); - if (!insertInset(inset)) - delete inset; - else { - updateInset(inset, true); - bv_->owner()->getDialogs()->showInclude(inset); - } + InsetInclude * inset = new InsetInclude(p); + if (!insertInset(inset)) + delete inset; + else { + updateInset(inset, true); + bv_->owner()->getDialogs().showInclude(inset); + } } break; case LFUN_FLOAT_LIST: - if (floatList.typeExist(argument)) { - Inset * inset = new InsetFloatList(argument); + if (tclass.floats().typeExist(ev.argument)) { + Inset * inset = new InsetFloatList(ev.argument); if (!insertInset(inset, tclass.defaultLayoutName())) delete inset; } else { lyxerr << "Non-existent float type: " - << argument << endl; + << ev.argument << endl; } break; case LFUN_THESAURUS_ENTRY: { - string arg = argument; + string arg = ev.argument; if (arg.empty()) { arg = bv_->getLyXText()->selectionAsString(buffer_, @@ -3112,209 +1297,79 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) } } - bv_->owner()->getDialogs()->showThesaurus(arg); + bv_->owner()->getDialogs().showThesaurus(arg); } break; - case LFUN_SELFINSERT: - { - if (argument.empty()) break; - - /* Automatically delete the currently selected - * text and replace it with what is being - * typed in now. Depends on lyxrc settings - * "auto_region_delete", which defaults to - * true (on). */ - - LyXText * lt = bv_->getLyXText(); - - if (lyxrc.auto_region_delete) { - if (lt->selection.set()) { - lt->cutSelection(bv_, false, false); - bv_->update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } - workarea().haveSelection(false); - } - - beforeChange(lt); - LyXFont const old_font(lt->real_current_font); + case LFUN_TRACK_CHANGES: + trackChanges(); + break; + + case LFUN_MERGE_CHANGES: + owner_->getDialogs().showMergeChanges(); + break; + + case LFUN_ACCEPT_ALL_CHANGES: { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0); +#warning FIXME changes + //moveCursorUpdate(false); - string::const_iterator cit = argument.begin(); - string::const_iterator end = argument.end(); - for (; cit != end; ++cit) { - owner_->getIntl()->getTransManager(). - TranslateAndInsert(*cit, lt); + while (lyxfind::findNextChange(bv_)) { + bv_->getLyXText()->acceptChange(bv_); } - - bv_->update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - - lt->selection.cursor = lt->cursor; - moveCursorUpdate(false); - - // real_current_font.number can change so we need to - // update the minibuffer - if (old_font != lt->real_current_font) - owner_->showState(); - //return string(); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; } - break; + + case LFUN_REJECT_ALL_CHANGES: { + bv_->update(bv_->text, BufferView::SELECT | BufferView::FITCUR); + bv_->text->setCursor(bv_, &(*bv_->buffer()->paragraphs.begin()), 0); +#warning FIXME changes + //moveCursorUpdate(false); - case LFUN_DATE_INSERT: // jdblair: date-insert cmd - { - time_t now_time_t = time(NULL); - struct tm * now_tm = localtime(&now_time_t); - setlocale(LC_TIME, ""); - string arg; - if (!argument.empty()) - arg = argument; - else - arg = lyxrc.date_insert_format; - char datetmp[32]; - int const datetmp_len = - ::strftime(datetmp, 32, arg.c_str(), now_tm); - - LyXText * lt = bv_->getLyXText(); - - for (int i = 0; i < datetmp_len; i++) { - lt->insertChar(bv_, datetmp[i]); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); + while (lyxfind::findNextChange(bv_)) { + bv_->getLyXText()->rejectChange(bv_); } - - lt->selection.cursor = lt->cursor; - moveCursorUpdate(false); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; + } + + case LFUN_ACCEPT_CHANGE: { + bv_->getLyXText()->acceptChange(bv_); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; } - break; + case LFUN_REJECT_CHANGE: { + bv_->getLyXText()->rejectChange(bv_); + update(bv_->text, + BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); + break; + } + case LFUN_UNKNOWN_ACTION: - owner_->getLyXFunc()->setErrorMessage(N_("Unknown function!")); + ev.errorMessage(N_("Unknown function!")); break; default: - return false; + return bv_->getLyXText()->dispatch(FuncRequest(ev, bv_)); } // end of switch return true; } -void BufferView::Pimpl::newline() -{ - if (available()) { - LyXText * lt = bv_->getLyXText(); - hideCursor(); - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - lt->insertChar(bv_, Paragraph::META_NEWLINE); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } -} - - -void BufferView::Pimpl::hfill() -{ - if (available()) { - LyXText * lt = bv_->getLyXText(); - hideCursor(); - update(lt, - BufferView::SELECT - | BufferView::FITCUR); - lt->insertChar(bv_, Paragraph::META_HFILL); - update(lt, - BufferView::SELECT - | BufferView::FITCUR - | BufferView::CHANGE); - } -} - - -void BufferView::Pimpl::specialChar(InsetSpecialChar::Kind kind) -{ - if (available()) { - LyXText * lt = bv_->getLyXText(); - - hideCursor(); - update(lt, BufferView::SELECT|BufferView::FITCUR); - InsetSpecialChar * new_inset = - new InsetSpecialChar(kind); - if (!insertInset(new_inset)) - delete new_inset; - else - updateInset(new_inset, true); - } -} - - -void BufferView::Pimpl::smartQuote() -{ - LyXText const * lt = bv_->getLyXText(); - Paragraph const * par = lt->cursor.par(); - pos_type pos = lt->cursor.pos(); - char c; - - if (!pos - || (par->isInset(pos - 1) - && par->getInset(pos - 1)->isSpace())) - c = ' '; - else - c = par->getChar(pos - 1); - - - hideCursor(); - - LyXLayout const & style = - textclasslist[bv_->buffer()->params.textclass][par->layout()]; - - if (style.pass_thru || - (!insertInset(new InsetQuotes(c, bv_->buffer()->params)))) - bv_->owner()->getLyXFunc()->dispatch(LFUN_SELFINSERT, "\""); -} - - -void BufferView::Pimpl::insertAndEditInset(Inset * inset) -{ - if (insertInset(inset)) - inset->edit(bv_); - else - delete inset; -} - - -// Open and lock an updatable inset -bool BufferView::Pimpl::open_new_inset(UpdatableInset * new_inset, bool behind) -{ - LyXText * lt = bv_->getLyXText(); - - beforeChange(lt); - finishUndo(); - if (!insertInset(new_inset)) { - delete new_inset; - return false; - } - new_inset->edit(bv_, !behind); - return true; -} - - bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) { // if we are in a locking inset we should try to insert the // inset there otherwise this is a illegal function now if (bv_->theLockingInset()) { if (bv_->theLockingInset()->insetAllowed(inset)) - return bv_->theLockingInset()->insertInset(bv_, inset); + return bv_->theLockingInset()->insertInset(bv_, inset); return false; } @@ -3328,7 +1383,7 @@ bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) bv_->text->breakParagraph(bv_); update(bv_->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); - if (bv_->text->cursor.par()->size()) { + if (!bv_->text->cursor.par()->empty()) { bv_->text->cursorLeft(bv_); bv_->text->breakParagraph(bv_); @@ -3337,7 +1392,7 @@ bool BufferView::Pimpl::insertInset(Inset * inset, string const & lout) string lres = lout; LyXTextClass const & tclass = - textclasslist[buffer_->params.textclass]; + buffer_->params.getLyXTextClass(); bool hasLayout = tclass.hasLayout(lres); string lay = tclass.defaultLayoutName(); @@ -3401,7 +1456,7 @@ void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) // if yes do the update as always otherwise we have to update the // toplevel inset where this inset is inside Inset * tl_inset = inset; - while(tl_inset->owner()) + while (tl_inset->owner()) tl_inset = tl_inset->owner(); hideCursor(); if (tl_inset == inset) { @@ -3420,56 +1475,9 @@ void BufferView::Pimpl::updateInset(Inset * inset, bool mark_dirty) } else if (static_cast(tl_inset) ->updateInsetInInset(bv_, inset)) { - if (bv_->text->updateInset(bv_, tl_inset)) { - update(); - updateScrollbar(); - } - } -} - - -void BufferView::Pimpl::gotoInset(vector const & codes, - bool same_content) -{ - if (!available()) return; - - hideCursor(); - beforeChange(bv_->text); - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); - - LyXCursor const & cursor = bv_->text->cursor; - - string contents; - if (same_content && - cursor.par()->isInset(cursor.pos())) { - Inset const * inset = cursor.par()->getInset(cursor.pos()); - if (find(codes.begin(), codes.end(), inset->lyxCode()) - != codes.end()) - contents = - static_cast(inset)->getContents(); - } - - - if (!bv_->text->gotoNextInset(bv_, codes, contents)) { - if (bv_->text->cursor.pos() - || bv_->text->cursor.par() != bv_->text->ownerParagraph()) { - LyXCursor tmp = bv_->text->cursor; - bv_->text->cursor.par(bv_->text->ownerParagraph()); - bv_->text->cursor.pos(0); - if (!bv_->text->gotoNextInset(bv_, codes, contents)) { - bv_->text->cursor = tmp; - bv_->owner()->message(_("No more insets")); - } - } else { - bv_->owner()->message(_("No more insets")); + if (bv_->text->updateInset(bv_, tl_inset)) { + update(); + updateScrollbar(); } } - update(bv_->text, BufferView::SELECT|BufferView::FITCUR); - bv_->text->selection.cursor = bv_->text->cursor; -} - - -void BufferView::Pimpl::gotoInset(Inset::Code code, bool same_content) -{ - gotoInset(vector(1, code), same_content); }