X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView_pimpl.C;h=34b5a478e357034a93c92d4a0ff62c214eb557a7;hb=498f06d43a0f2000c3f704db1ea39fda3c819fe6;hp=6362e88c7925c08f0ab484079e742be1847f971a;hpb=1d0eda5d0258fdc0658529c72cd84b482948bae8;p=lyx.git diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 6362e88c79..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,34 +36,21 @@ #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" @@ -75,26 +59,14 @@ #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; @@ -105,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().workAreaResize + doccon = workarea().scrollDocView + .connect(boost::bind(&BufferView::Pimpl::scrollDocView, this, _1)); + resizecon = workarea().workAreaResize .connect(boost::bind(&BufferView::Pimpl::workAreaResize, 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 + 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); } @@ -181,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_); @@ -196,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(); } @@ -216,15 +189,16 @@ void BufferView::Pimpl::buffer(Buffer * b) } // FIXME: needed when ? - bv_->text->first_y = screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); + 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); + owner_->getDialogs().updateBufferDependent(true); } else { lyxerr[Debug::INFO] << " No Buffer!" << endl; - owner_->getDialogs()->hideBufferDependent(); + owner_->getDialogs().hideBufferDependent(); // Also remove all remaining text's from the testcache. // (there should not be any!) (if there is any it is a @@ -257,7 +231,7 @@ bool BufferView::Pimpl::fitCursor() ret = screen().fitCursor(bv_->text, bv_); } - bv_->owner()->getDialogs()->updateParagraph(); + bv_->owner()->getDialogs().updateParagraph(); if (ret) updateScrollbar(); return ret; @@ -269,7 +243,9 @@ void BufferView::Pimpl::redoCurrentBuffer() lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl; if (buffer_ && bv_->text) { resizeCurrentBuffer(); + updateScrollbar(); owner_->updateLayoutChoice(); + repaint(); } } @@ -289,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) { @@ -322,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_); @@ -352,10 +330,9 @@ int BufferView::Pimpl::resizeCurrentBuffer() bv_->text->first_y = screen().topCursorVisible(bv_->text->cursor, bv_->text->first_y); switchKeyMap(); - owner_->allowInput(); + owner_->busy(false); - /// clear the "Formatting Document" message - owner_->message(""); + updateScrollbar(); return 0; } @@ -377,11 +354,11 @@ void BufferView::Pimpl::updateScrollbar() } LyXText const & t = *bv_->text; - + lyxerr[Debug::GUI] << "Updating scrollbar: h " << t.height << ", first_y " - << t.first_y << ", default height " << t.defaultHeight() << endl; + << t.first_y << ", default height " << defaultRowHeight() << endl; - workarea().setScrollbarParams(t.height, t.first_y, t.defaultHeight()); + workarea().setScrollbarParams(t.height, t.first_y, defaultRowHeight()); } @@ -389,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)); @@ -410,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, - string("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); } @@ -701,198 +455,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 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()); - } - - 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; - 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::workAreaResize() { static int work_area_width; @@ -919,7 +481,7 @@ void BufferView::Pimpl::workAreaResize() if (lyxerr.debugging()) textcache.show(lyxerr, "Expose delete all"); textcache.clear(); - // FIXME: this is aalready done in resizeCurrentBuffer() ?? + // FIXME: this is already done in resizeCurrentBuffer() ?? buffer_->resizeInsets(bv_); } else if (heightChange) { // fitCursor() ensures we don't jump back @@ -1044,10 +606,6 @@ void BufferView::Pimpl::cursorToggle() return; } - /* FIXME */ - extern void reapSpellchecker(void); - reapSpellchecker(); - if (!bv_->theLockingInset()) { screen().cursorToggle(bv_); } else { @@ -1058,118 +616,26 @@ 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; - } - - int y = text->first_y; - Row * cursorrow = text->cursor.row(); - - text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); - 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 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(); + if (buffer_ && bv_->text) + return true; + return false; } -void BufferView::Pimpl::cursorNext(LyXText * text) +Change const BufferView::Pimpl::getCurrentChange() { - 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(); -} + if (!bv_->buffer()->params.tracking_changes) + return Change(Change::UNCHANGED); - -bool BufferView::Pimpl::available() const -{ - if (buffer_ && bv_->text) - return true; - return false; + LyXText * t(bv_->getLyXText()); + + if (!t->selection.set()) + return Change(Change::UNCHANGED); + + LyXCursor const & cur(t->selection.start); + return cur.par()->lookupChangeFull(cur.pos()); } @@ -1189,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())); } } @@ -1221,8 +691,12 @@ void BufferView::Pimpl::restorePosition(unsigned int i) 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())); } } @@ -1244,13 +718,13 @@ void BufferView::Pimpl::switchKeyMap() 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(); } } @@ -1298,15 +772,15 @@ void BufferView::Pimpl::toggleToggle() void BufferView::Pimpl::center() { LyXText * t = bv_->text; - + beforeChange(t); int const half_height = workarea().workHeight() / 2; int new_y = 0; - + if (t->cursor.y() > half_height) { new_y = t->cursor.y() - half_height; } - + // 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 @@ -1314,41 +788,18 @@ void BufferView::Pimpl::center() // 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 + // updateScrollbar() currently. Never mind that this is a // pretty obfuscated way of updating t->first_y screen().draw(t, bv_, new_y); - + update(t, BufferView::SELECT | BufferView::FITCUR); } -void BufferView::Pimpl::pasteClipboard(bool asPara) +void BufferView::Pimpl::stuffClipboard(string const & stuff) const { - if (!buffer_) - return; - - screen().hideCursor(); - beforeChange(bv_->text); - - string const clip(workarea().getClipboard()); - - if (clip.empty()) - return; - - 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); -} - - -void BufferView::Pimpl::stuffClipboard(string const & stuff) const -{ - workarea().putClipboard(stuff); -} + workarea().putClipboard(stuff); +} /* @@ -1357,39 +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); - - switchKeyMap(); -} - - Inset * BufferView::Pimpl::getInsetByCode(Inset::Code code) { +#if 0 LyXCursor cursor = bv_->getLyXText()->cursor; Buffer::inset_iterator it = find_if(Buffer::inset_iterator( @@ -1397,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 } @@ -1424,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) @@ -1446,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; @@ -1515,28 +1004,6 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) break; } - case LFUN_PASTE: - bv_->paste(); - switchKeyMap(); - 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; @@ -1546,1314 +1013,132 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) switchKeyMap(); 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(); - break; - case LFUN_DEPTH_MIN: changeDepth(bv_, bv_->getLyXText(), -1); break; case LFUN_DEPTH_PLUS: - changeDepth(bv_, bv_->getLyXText(), 1); - break; - - case LFUN_FREE: - owner_->getDialogs()->setUserFreeFont(); - break; - - case LFUN_FILE_INSERT: - MenuInsertLyXFile(argument); - break; - - case LFUN_FILE_INSERT_ASCII_PARA: - InsertAsciiFile(bv_, argument, true); - break; - - case LFUN_FILE_INSERT_ASCII: - InsertAsciiFile(bv_, 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()->name() != 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); - switchKeyMap(); - } - } - break; - - case LFUN_LANGUAGE: - lang(bv_, argument); - switchKeyMap(); - owner_->view_state_changed(); - break; - - case LFUN_EMPH: - emph(bv_); - owner_->view_state_changed(); - break; - - case LFUN_BOLD: - bold(bv_); - owner_->view_state_changed(); - break; - - case LFUN_NOUN: - noun(bv_); - owner_->view_state_changed(); - break; - - case LFUN_CODE: - code(bv_); - owner_->view_state_changed(); - break; - - case LFUN_SANS: - sans(bv_); - owner_->view_state_changed(); - break; - - case LFUN_ROMAN: - roman(bv_); - owner_->view_state_changed(); - break; - - case LFUN_DEFAULT: - styleReset(bv_); - owner_->view_state_changed(); - break; - - case LFUN_UNDERLINE: - underline(bv_); - owner_->view_state_changed(); - break; - - case LFUN_FONT_SIZE: - fontSize(bv_, argument); - owner_->view_state_changed(); - break; - - case LFUN_FONT_STATE: - 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); - break; - - case LFUN_REF_INSERT: - if (argument.empty()) { - InsetCommandParams p("ref"); - owner_->getDialogs()->createRef(p.getAsString()); - } else { - InsetCommandParams p; - p.setFromString(argument); - - InsetRef * inset = new InsetRef(p, *buffer_); - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; - - case LFUN_BOOKMARK_SAVE: - savePosition(strToUnsignedInt(argument)); - break; - - case LFUN_BOOKMARK_GOTO: - restorePosition(strToUnsignedInt(argument)); - break; - - case LFUN_REF_GOTO: - { - string label(argument); - if (label.empty()) { - InsetRef * inset = - static_cast(getInsetByCode(Inset::REF_CODE)); - if (inset) { - label = inset->getContents(); - savePosition(0); - } - } - - if (!label.empty()) { - //bv_->savePosition(0); - if (!bv_->gotoLabel(label)) - Alert::alert(_("Error"), - _("Couldn't find this label"), - _("in current document.")); - } - } - 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_->view_state_changed(); - } - break; - - 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; - } - if (is_rtl) - lt->cursorRight(bv_, false); - - finishUndo(); - moveCursorUpdate(false); - owner_->view_state_changed(); - } - break; - - case LFUN_UP: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorUp(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->view_state_changed(); - } - break; - - case LFUN_DOWN: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorDown(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->view_state_changed(); - } - break; - - case LFUN_UP_PARAGRAPH: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorUpParagraph(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->view_state_changed(); - } - break; - - case LFUN_DOWN_PARAGRAPH: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - lt->cursorDownParagraph(bv_); - finishUndo(); - moveCursorUpdate(false); - owner_->view_state_changed(); - } - break; - - case LFUN_PRIOR: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - cursorPrevious(lt); - finishUndo(); - moveCursorUpdate(false, false); - owner_->view_state_changed(); - } - break; - - case LFUN_NEXT: - { - LyXText * lt = bv_->getLyXText(); - - if (!lt->selection.mark()) - beforeChange(lt); - update(lt, BufferView::UPDATE); - cursorNext(lt); - finishUndo(); - moveCursorUpdate(false, false); - owner_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - break; - - case LFUN_UPSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorUp(bv_, true); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_DOWNSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorDown(bv_, true); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_UP_PARAGRAPHSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorUpParagraph(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_DOWN_PARAGRAPHSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, - BufferView::SELECT|BufferView::FITCUR); - lt->cursorDownParagraph(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_PRIORSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - cursorPrevious(lt); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_NEXTSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - cursorNext(lt); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_HOMESEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorHome(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - break; - - case LFUN_ENDSEL: - { - LyXText * lt = bv_->getLyXText(); - - update(lt, BufferView::SELECT|BufferView::FITCUR); - lt->cursorEnd(bv_); - finishUndo(); - moveCursorUpdate(true); - owner_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_->view_state_changed(); - } - 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_ptr const & style = 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_->view_state_changed(); - switchKeyMap(); - } - 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_->view_state_changed(); - 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_->view_state_changed(); - } - 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_->view_state_changed(); - switchKeyMap(); - } - 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; - switchKeyMap(); - owner_->view_state_changed(); - 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; - switchKeyMap(); - owner_->view_state_changed(); - 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; - switchKeyMap(); - owner_->view_state_changed(); - } - 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); - switchKeyMap(); - } + changeDepth(bv_, bv_->getLyXText(), 1); break; - case LFUN_QUOTE: - smartQuote(); + case LFUN_FREE: + owner_->getDialogs().setUserFreeFont(); 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); + case LFUN_FILE_INSERT: + MenuInsertLyXFile(ev.argument); + break; - InsetUrl * inset = new InsetUrl(p); - if (!insertInset(inset)) - delete inset; - else - updateInset(inset, true); - } - break; + case LFUN_FILE_INSERT_ASCII_PARA: + InsertAsciiFile(bv_, ev.argument, true); + break; - case LFUN_INSET_ERT: - insertAndEditInset(new InsetERT(buffer_->params)); + case LFUN_FILE_INSERT_ASCII: + InsertAsciiFile(bv_, ev.argument, false); break; - case LFUN_INSET_EXTERNAL: - insertAndEditInset(new InsetExternal); + case LFUN_LANGUAGE: + lang(bv_, ev.argument); + switchKeyMap(); + owner_->view_state_changed(); break; - case LFUN_INSET_FOOTNOTE: - insertAndEditInset(new InsetFoot(buffer_->params)); + case LFUN_EMPH: + emph(bv_); + owner_->view_state_changed(); break; - case LFUN_INSET_MARGINAL: - insertAndEditInset(new InsetMarginal(buffer_->params)); + case LFUN_BOLD: + bold(bv_); + owner_->view_state_changed(); break; - case LFUN_INSET_MINIPAGE: - insertAndEditInset(new InsetMinipage(buffer_->params)); + case LFUN_NOUN: + noun(bv_); + owner_->view_state_changed(); break; - case LFUN_INSERT_NOTE: - insertAndEditInset(new InsetNote(buffer_->params)); + case LFUN_CODE: + code(bv_); + owner_->view_state_changed(); 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; - } + case LFUN_SANS: + sans(bv_); + owner_->view_state_changed(); 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; - } + case LFUN_ROMAN: + roman(bv_); + owner_->view_state_changed(); break; -#if 0 - case LFUN_INSET_LIST: - insertAndEditInset(new InsetList); + case LFUN_DEFAULT: + styleReset(bv_); + owner_->view_state_changed(); break; - case LFUN_INSET_THEOREM: - insertAndEditInset(new InsetTheorem); + case LFUN_UNDERLINE: + underline(bv_); + owner_->view_state_changed(); 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_FONT_SIZE: + fontSize(bv_, ev.argument); + owner_->view_state_changed(); + 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; + case LFUN_FONT_STATE: + owner_->getLyXFunc().setMessage(currentState(bv_)); + break; - // --- lyxserver commands ---------------------------- + case LFUN_INSERT_LABEL: + MenuInsertLabel(bv_, ev.argument); + break; - 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_REF_INSERT: + if (ev.argument.empty()) { + InsetCommandParams p("ref"); + owner_->getDialogs().createRef(p.getAsString()); + } else { + InsetCommandParams p; + p.setFromString(ev.argument); - case LFUN_GETXY: - owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.x()) - + ' ' - + tostr(bv_->getLyXText()->cursor.y())); + InsetRef * inset = new InsetRef(p, *buffer_); + if (!insertInset(inset)) + delete inset; + else + updateInset(inset, true); + } 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_BOOKMARK_SAVE: + savePosition(strToUnsignedInt(ev.argument)); + break; - case LFUN_GETLAYOUT: - owner_->getLyXFunc()->setMessage(tostr(bv_->getLyXText()->cursor.par()->layout())); + case LFUN_BOOKMARK_GOTO: + restorePosition(strToUnsignedInt(ev.argument)); break; - case LFUN_GETFONT: + case LFUN_REF_GOTO: { - 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"); + string label = ev.argument; + if (label.empty()) { + InsetRef * inset = + static_cast(getInsetByCode(Inset::REF_CODE)); + if (inset) { + label = inset->getContents(); + savePosition(0); + } + } + if (!label.empty()) { + //bv_->savePosition(0); + if (!bv_->gotoLabel(label)) + Alert::alert(_("Error"), + _("Couldn't find this label"), + _("in current document.")); + } } break; @@ -2876,13 +1161,13 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) case LFUN_HUNG_UMLAUT: case LFUN_CIRCLE: case LFUN_OGONEK: - if (argument.empty()) { + if (ev.argument.empty()) { // As always... - owner_->getLyXFunc()->handleKeyFunc(action); + owner_->getLyXFunc().handleKeyFunc(ev.action); } else { - owner_->getLyXFunc()->handleKeyFunc(action); - owner_->getIntl()->getTransManager() - .TranslateAndInsert(argument[0], bv_->getLyXText()); + owner_->getLyXFunc().handleKeyFunc(ev.action); + owner_->getIntl().getTransManager() + .TranslateAndInsert(ev.argument[0], bv_->getLyXText()); update(bv_->getLyXText(), BufferView::SELECT | BufferView::FITCUR @@ -2890,52 +1175,30 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) } 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); + mathDispatch(FuncRequest(bv_, ev.action, ev.argument)); break; case LFUN_CITATION_INSERT: { InsetCommandParams p; - p.setFromString(argument); + p.setFromString(ev.argument); InsetCitation * inset = new InsetCitation(p); if (!insertInset(inset)) delete inset; - else + else { + inset->setLoadingBuffer(bv_->buffer(), false); updateInset(inset, true); + } + } break; @@ -2944,14 +1207,16 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) // 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); + string const db = token(ev.argument, ' ', 0); + string bibstyle = token(ev.argument, ' ', 1); + if (bibstyle.empty()) + bibstyle = "plain"; InsetCommandParams p("BibTeX", db, bibstyle); InsetBibtex * inset = new InsetBibtex(p); if (insertInset(inset)) { - if (argument.empty()) + if (ev.argument.empty()) inset->edit(bv_); } else delete inset; @@ -2964,7 +1229,7 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) InsetBibtex * inset = static_cast(getInsetByCode(Inset::BIBTEX_CODE)); if (inset) { - inset->addDatabase(argument); + inset->addDatabase(ev.argument); } } break; @@ -2973,9 +1238,8 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) { InsetBibtex * inset = static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { - inset->delDatabase(argument); - } + if (inset) + inset->delDatabase(ev.argument); } break; @@ -2983,57 +1247,16 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) { InsetBibtex * inset = static_cast(getInsetByCode(Inset::BIBTEX_CODE)); - if (inset) { - inset->setOptions(argument); - } - } - break; - - case LFUN_INDEX_INSERT: - { - string entry = argument; - if (entry.empty()) { - entry = bv_->getLyXText()->getStringToIndex(bv_); - } - - if (entry.empty()) { - owner_->getDialogs()->createIndex(); - break; - } - - InsetIndex * inset = new InsetIndex(InsetCommandParams("index", entry)); - - 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; + if (inset) + inset->setOptions(ev.argument); } - break; case LFUN_CHILD_INSERT: { InsetInclude::Params p; - p.cparams.setFromString(argument); + if (!ev.argument.empty()) + p.cparams.setFromString(ev.argument); p.masterFilename_ = buffer_->fileName(); InsetInclude * inset = new InsetInclude(p); @@ -3041,25 +1264,25 @@ bool BufferView::Pimpl::Dispatch(kb_action action, string const & argument) delete inset; else { updateInset(inset, true); - bv_->owner()->getDialogs()->showInclude(inset); + 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_, @@ -3074,225 +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_->view_state_changed(); - //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_ptr const & style = par->layout(); - - if (style->pass_thru || - (!insertInset(new InsetQuotes(c, bv_->buffer()->params)))) - bv_->owner()->getLyXFunc()->dispatch(LFUN_SELFINSERT, string("\"")); -} - - -void BufferView::Pimpl::insertAndEditInset(Inset * inset) -{ -#if 0 - if (insertInset(inset)) - inset->edit(bv_); - else - delete inset; -#else - bool gotsel = false; - - if (bv_->getLyXText()->selection.set()) { - bv_->getLyXText()->cutSelection(bv_, true, false); - gotsel = true; - } - - if (insertInset(inset)) { - inset->edit(bv_); - if (gotsel) - owner_->getLyXFunc()->dispatch(LFUN_PASTESELECTION); - } - else - delete inset; -#endif -} - - -// 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; } @@ -3306,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_); @@ -3315,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(); @@ -3379,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) { @@ -3398,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); }