X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext3.C;h=a468a7289665a3590980354f8cc5dc346177fa62;hb=eead5ba43d0ddf06544ad1b40063981d3788c635;hp=6da72b34b15bdf54b5bab6e6a09cf0a4c7db30b6;hpb=38fce2feaced45d99f3e78ee8e877f2c37aa6bd1;p=lyx.git diff --git a/src/text3.C b/src/text3.C index 6da72b34b1..a468a72896 100644 --- a/src/text3.C +++ b/src/text3.C @@ -20,6 +20,7 @@ #include "debug.h" #include "bufferparams.h" #include "buffer.h" +#include "bufferview_funcs.h" #include "ParagraphParameters.h" #include "gettext.h" #include "factory.h" @@ -27,6 +28,8 @@ #include "box.h" #include "language.h" #include "support/tostr.h" +#include "support/lstrings.h" +#include "support/LAssert.h" #include "frontends/LyXView.h" #include "frontends/screen.h" #include "frontends/Dialogs.h" @@ -42,6 +45,9 @@ #include #include +using namespace lyx::support; +using namespace bv_funcs; + using std::endl; using std::find; using std::vector; @@ -66,11 +72,11 @@ namespace { if (lt->isInInset()) bv->updateInset(lt->inset_owner); else - bv->toggleToggle(); + bv->repaint(); } if (!lt->isInInset()) { bv->update(lt, BufferView::SELECT); - } else if (bv->text->refreshStatus() != LyXText::REFRESH_NONE) { + } else if (bv->text->needRefresh()) { bv->update(BufferView::SELECT); } @@ -91,7 +97,7 @@ namespace { // check if the given co-ordinates are inside an inset at the // given cursor, if one exists. If so, the inset is returned, // and the co-ordinates are made relative. Otherwise, 0 is returned. - Inset * checkInset(BufferView * bv, LyXText & text, +InsetOld * checkInset(BufferView * /*bv*/, LyXText & text, LyXCursor const & cur, int & x, int & y) { lyx::pos_type const pos = cur.pos(); @@ -100,25 +106,25 @@ namespace { if (pos >= par->size() || !par->isInset(pos)) return 0; - Inset /*const*/ * inset = par->getInset(pos); + InsetOld /*const*/ * inset = par->getInset(pos); if (!isEditableInset(inset)) return 0; // get inset dimensions - lyx::Assert(par->getInset(pos)); + Assert(par->getInset(pos)); - LyXFont const & font = text.getFont(bv->buffer(), par, pos); + LyXFont const & font = text.getFont(par, pos); - int const width = inset->width(bv, font); + int const width = inset->width(); int const inset_x = font.isVisibleRightToLeft() ? (cur.ix() - width) : cur.ix(); Box b( inset_x + inset->scroll(), inset_x + width, - cur.iy() - inset->ascent(bv, font), - cur.iy() + inset->descent(bv, font) + cur.iy() - inset->ascent(), + cur.iy() + inset->descent() ); if (!b.contained(x, y)) { @@ -140,14 +146,14 @@ namespace { } // anon namespace -Inset * LyXText::checkInsetHit(int & x, int & y) +InsetOld * LyXText::checkInsetHit(int & x, int & y) { int y_tmp = y + top_y(); LyXCursor cur; setCursorFromCoordinates(cur, x, y_tmp); - Inset * inset = checkInset(bv(), *this, cur, x, y_tmp); + InsetOld * inset = checkInset(bv(), *this, cur, x, y_tmp); if (inset) { y = y_tmp; return inset; @@ -167,14 +173,14 @@ Inset * LyXText::checkInsetHit(int & x, int & y) } -bool LyXText::gotoNextInset(vector const & codes, +bool LyXText::gotoNextInset(vector const & codes, string const & contents) { ParagraphList::iterator end = ownerParagraphs().end(); ParagraphList::iterator pit = cursor.par(); pos_type pos = cursor.pos(); - Inset * inset; + InsetOld * inset; do { if (pos + 1 < pit->size()) { ++pos; @@ -199,7 +205,7 @@ bool LyXText::gotoNextInset(vector const & codes, } -void LyXText::gotoInset(vector const & codes, +void LyXText::gotoInset(vector const & codes, bool same_content) { bv()->beforeChange(this); @@ -208,7 +214,7 @@ void LyXText::gotoInset(vector const & codes, string contents; if (same_content && cursor.pos() < cursor.par()->size() && cursor.par()->isInset(cursor.pos())) { - Inset const * inset = cursor.par()->getInset(cursor.pos()); + InsetOld const * inset = cursor.par()->getInset(cursor.pos()); if (find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end()) contents = static_cast(inset)->getContents(); @@ -232,9 +238,9 @@ void LyXText::gotoInset(vector const & codes, } -void LyXText::gotoInset(Inset::Code code, bool same_content) +void LyXText::gotoInset(InsetOld::Code code, bool same_content) { - gotoInset(vector(1, code), same_content); + gotoInset(vector(1, code), same_content); } @@ -242,49 +248,43 @@ void LyXText::cursorPrevious() { int y = top_y(); - if (cursor.row() == rows().begin()) { - if (y > 0) { - int new_y = bv()->text->top_y() - bv()->workHeight(); - bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y); + if (cursorRow() == rows().begin()) { + if (y > 0) bv()->updateScrollbar(); - } return; } - RowList::iterator cursorrow = cursor.row(); + RowList::iterator cursorrow = cursorRow(); setCursorFromCoordinates(cursor.x_fix(), y); finishUndo(); int new_y; - if (cursorrow == bv()->text->cursor.row()) { + if (cursorrow == bv()->text->cursorRow()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the previous row instead. cursorUp(true); return; // This is what we used to do, so we wouldn't skip right past // tall rows, but it's not working right now. -#if 0 - new_y = bv->text->top_y() - bv->workHeight(); -#endif } else { if (inset_owner) { new_y = bv()->text->cursor.iy() + bv()->theLockingInset()->insetInInsetY() + y - + cursor.row()->height() + + cursorRow()->height() - bv()->workHeight() + 1; } else { new_y = cursor.y() - - cursor.row()->baseline() - + cursor.row()->height() + - cursorRow()->baseline() + + cursorRow()->height() - bv()->workHeight() + 1; } } - bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y); - if (cursor.row() != rows().begin()) { + //bv()->screen().draw(bv()->text, bv(), new_y < 0 ? 0 : new_y); + if (cursorRow() != rows().begin()) { LyXCursor cur; - setCursor(cur, boost::prior(cursor.row())->par(), - boost::prior(cursor.row())->pos(), false); + setCursor(cur, boost::prior(cursorRow())->par(), + boost::prior(cursorRow())->pos(), false); if (cur.y() > top_y()) { cursorUp(true); } @@ -297,11 +297,11 @@ void LyXText::cursorNext() { int topy = top_y(); - if (boost::next(cursor.row()) == rows().end()) { - int y = cursor.y() - cursor.row()->baseline() + - cursor.row()->height(); + if (boost::next(cursorRow()) == rows().end()) { + int y = cursor.y() - cursorRow()->baseline() + + cursorRow()->height(); if (y > topy + bv()->workHeight()) { - bv()->screen().draw(bv()->text, bv(), bv()->text->top_y() + bv()->workHeight()); + //bv()->screen().draw(bv()->text, bv(), bv()->text->top_y() + bv()->workHeight()); bv()->updateScrollbar(); } return; @@ -316,13 +316,13 @@ void LyXText::cursorNext() getRowNearY(y); - RowList::iterator cursorrow = cursor.row(); + RowList::iterator cursorrow = cursorRow(); setCursorFromCoordinates(cursor.x_fix(), y); // + bv->workHeight()); finishUndo(); int new_y; - if (cursorrow == bv()->text->cursor.row()) { + if (cursorrow == bv()->text->cursorRow()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the next row instead. cursorDown(true); @@ -336,16 +336,17 @@ void LyXText::cursorNext() if (inset_owner) { new_y = bv()->text->cursor.iy() + bv()->theLockingInset()->insetInInsetY() - + y - cursor.row()->baseline(); + + y - cursorRow()->baseline(); } else { - new_y = cursor.y() - cursor.row()->baseline(); + new_y = cursor.y() - cursorRow()->baseline(); } } - bv()->screen().draw(bv()->text, bv(), new_y); - if (boost::next(cursor.row()) != rows().end()) { + //bv()->screen().draw(bv()->text, bv(), new_y); + + RowList::iterator next_row = boost::next(cursorRow()); + if (next_row != rows().end()) { LyXCursor cur; - setCursor(cur, boost::next(cursor.row())->par(), - boost::next(cursor.row())->pos(), false); + setCursor(cur, next_row->par(), next_row->pos(), false); if (cur.y() < top_y() + bv()->workHeight()) { cursorDown(true); } @@ -365,6 +366,7 @@ void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind) { lt->update(); InsetSpecialChar * new_inset = new InsetSpecialChar(kind); + replaceSelection(lt); if (!bv->insertInset(new_inset)) delete new_inset; else @@ -375,13 +377,13 @@ void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind) void doInsertInset(LyXText * lt, FuncRequest const & cmd, bool edit, bool pastesel) { - Inset * inset = createInset(cmd); + InsetOld * inset = createInset(cmd); BufferView * bv = cmd.view(); if (inset) { bool gotsel = false; if (lt->selection.set()) { - lt->cutSelection(true, false); + bv->owner()->dispatch(FuncRequest(LFUN_CUT)); gotsel = true; } if (bv->insertInset(inset)) { @@ -390,7 +392,7 @@ void doInsertInset(LyXText * lt, FuncRequest const & cmd, inset->localDispatch(cmd); } if (gotsel && pastesel) - bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION)); + bv->owner()->dispatch(FuncRequest(LFUN_PASTE)); } else delete inset; @@ -399,7 +401,7 @@ void doInsertInset(LyXText * lt, FuncRequest const & cmd, } -Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) +InsetOld::RESULT LyXText::dispatch(FuncRequest const & cmd) { lyxerr[Debug::ACTION] << "LyXFunc::dispatch: action[" << cmd.action <<"] arg[" << cmd.argument << ']' << endl; @@ -418,7 +420,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) for (; tmp != end; ++tmp) { if (tmp->params().startOfAppendix()) { - setUndo(bv, Undo::EDIT, tmp); + recordUndo(bv, Undo::ATOMIC, tmp); tmp->params().startOfAppendix(false); int tmpy; setHeightOfRow(getRow(tmp, 0, tmpy)); @@ -426,13 +428,13 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } } - setUndo(bv, Undo::EDIT, pit); + recordUndo(bv, Undo::ATOMIC, pit); pit->params().startOfAppendix(start); // we can set the refreshing parameters now updateCounters(); redoHeightOfParagraph(); - postPaint(0); + postPaint(); setCursor(cursor.par(), cursor.pos()); update(); break; @@ -586,9 +588,9 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) case LFUN_WORDSEL: { update(); - LyXCursor cur1; + LyXCursor cur1 = cursor; LyXCursor cur2; - getWord(cur1, cur2, WHOLE_WORD); + ::getWord(cur1, cur2, lyx::WHOLE_WORD, ownerParagraphs()); setCursor(cur1.par(), cur1.pos()); bv->beforeChange(this); setCursor(cur2.par(), cur2.pos()); @@ -606,7 +608,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (cursor.pos() < cursor.par()->size() && cursor.par()->isInset(cursor.pos()) && isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) { - Inset * tmpinset = cursor.par()->getInset(cursor.pos()); + InsetOld * tmpinset = cursor.par()->getInset(cursor.pos()); cmd.message(tmpinset->editMessage()); FuncRequest cmd1(bv, LFUN_INSET_EDIT, is_rtl ? "right" : "left"); tmpinset->localDispatch(cmd1); @@ -632,7 +634,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) cursor.pos() < cursor.par()->size() && cursor.par()->isInset(cursor.pos()) && isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) { - Inset * tmpinset = cursor.par()->getInset(cursor.pos()); + InsetOld * tmpinset = cursor.par()->getInset(cursor.pos()); cmd.message(tmpinset->editMessage()); FuncRequest cmd1(bv, LFUN_INSET_EDIT, is_rtl ? "left" : "right"); tmpinset->localDispatch(cmd1); @@ -648,7 +650,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (!selection.mark()) bv->beforeChange(this); bv->update(this, BufferView::UPDATE); - cursorUp(bv); + cursorUp(false); finishChange(bv); break; @@ -656,7 +658,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (!selection.mark()) bv->beforeChange(this); bv->update(this, BufferView::UPDATE); - cursorDown(bv); + cursorDown(false); finishChange(bv); break; @@ -682,10 +684,6 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) bv->update(this, BufferView::UPDATE); cursorPrevious(); finishChange(bv, false); - // was: - // finishUndo(); - // moveCursorUpdate(bv, false, false); - // owner_->view_state_changed(); break; case LFUN_NEXT: @@ -719,7 +717,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (cursor.pos() <= body) break; - bv->beforeChange(this); + replaceSelection(bv->getLyXText()); insertInset(new InsetNewline); update(); setCursor(cursor.par(), cursor.pos()); @@ -736,7 +734,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // just comment out the line below... } else { update(); - cutSelection(bv, true); + cutSelection(true, false); update(); } moveCursorUpdate(bv, false); @@ -777,7 +775,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } } else { update(); - cutSelection(bv, true); + cutSelection(true, false); } update(); break; @@ -794,7 +792,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } } else { update(); - cutSelection(bv, true); + cutSelection(true, false); update(); } bv->owner()->view_state_changed(); @@ -823,13 +821,13 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } } else { update(); - cutSelection(bv, true); + cutSelection(true, false); } update(); break; case LFUN_BREAKPARAGRAPH: - bv->beforeChange(this); + replaceSelection(bv->getLyXText()); breakParagraph(bv->buffer()->paragraphs, 0); update(); selection.cursor = cursor; @@ -838,7 +836,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) break; case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - bv->beforeChange(this); + replaceSelection(bv->getLyXText()); breakParagraph(bv->buffer()->paragraphs, 1); update(); selection.cursor = cursor; @@ -851,7 +849,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // indentation and add a "defskip" at the top. // Otherwise, do the same as LFUN_BREAKPARAGRAPH. LyXCursor cur = cursor; - bv->beforeChange(this); + replaceSelection(bv->getLyXText()); if (cur.pos() == 0) { if (cur.par()->params().spaceTop() == VSpace(VSpace::NONE)) { setParagraph( @@ -918,7 +916,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } case LFUN_INSET_SETTINGS: - lyx::Assert(bv->theLockingInset()); + Assert(bv->theLockingInset()); bv->theLockingInset()->getLockingInset()->showInsetDialog(bv); break; @@ -1014,27 +1012,34 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) case LFUN_TRANSPOSE_CHARS: update(); - transposeChars(*this, cursor); + recordUndo(bv, Undo::ATOMIC, cursor.par()); + if (transposeChars(cursor)) + checkParagraph(cursor.par(), cursor.pos()); if (inset_owner) bv->updateInset(inset_owner); update(); break; - case LFUN_PASTE: + case LFUN_PASTE: { cmd.message(_("Paste")); - // clear the selection - bv->toggleSelection(); - clearSelection(); - update(); - pasteSelection(); + replaceSelection(bv->getLyXText()); + size_t sel_index = 0; + string const & arg = cmd.argument; + if (isStrUnsignedInt(arg)) { + size_t const paste_arg = strToUnsignedInt(arg); +#warning FIXME Check if the arg is in the domain of available selections. + sel_index = paste_arg; + } + pasteSelection(sel_index); clearSelection(); // bug 393 update(); bv->switchKeyMap(); break; + } case LFUN_CUT: update(); - cutSelection(bv, true); + cutSelection(true, true); update(); cmd.message(_("Cut")); break; @@ -1169,23 +1174,24 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } case LFUN_GOTOERROR: - gotoInset(Inset::ERROR_CODE, false); + gotoInset(InsetOld::ERROR_CODE, false); break; case LFUN_GOTONOTE: - gotoInset(Inset::NOTE_CODE, false); + gotoInset(InsetOld::NOTE_CODE, false); break; case LFUN_REFERENCE_GOTO: { - vector tmp; - tmp.push_back(Inset::LABEL_CODE); - tmp.push_back(Inset::REF_CODE); + vector tmp; + tmp.push_back(InsetOld::LABEL_CODE); + tmp.push_back(InsetOld::REF_CODE); gotoInset(tmp, true); break; } case LFUN_QUOTE: { + replaceSelection(bv->getLyXText()); ParagraphList::iterator pit = cursor.par(); lyx::pos_type pos = cursor.pos(); char c; @@ -1207,6 +1213,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) } case LFUN_DATE_INSERT: { + replaceSelection(bv->getLyXText()); time_t now_time_t = time(NULL); struct tm * now_tm = localtime(&now_time_t); setlocale(LC_TIME, ""); @@ -1256,10 +1263,10 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (cmd.button() == mouse_button::button1) { if (!isInInset()) { bv->screen().toggleSelection(this, bv); - selectWord(LyXText::WHOLE_WORD_STRICT); + selectWord(lyx::WHOLE_WORD_STRICT); bv->screen().toggleSelection(this, bv, false); } else { - selectWord(LyXText::WHOLE_WORD_STRICT); + selectWord(lyx::WHOLE_WORD_STRICT); } update(); bv->haveSelection(selection.set()); @@ -1277,11 +1284,10 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // Check for inset locking if (bv->theLockingInset()) { - Inset * tli = bv->theLockingInset(); + InsetOld * tli = bv->theLockingInset(); LyXCursor cursor = bv->text->cursor; - LyXFont font = bv->text->getFont(bv->buffer(), - cursor.par(), cursor.pos()); - int width = tli->width(bv, font); + LyXFont font = bv->text->getFont(cursor.par(), cursor.pos()); + int width = tli->width(); int inset_x = font.isVisibleRightToLeft() ? cursor.ix() - width : cursor.ix(); int start_x = inset_x + tli->scroll(); @@ -1301,7 +1307,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) break; } - RowList::iterator cursorrow = bv->text->cursor.row(); + RowList::iterator cursorrow = bv->text->cursorRow(); bv->text->setCursorFromCoordinates(cmd.x, cmd.y + bv->text->top_y()); #if 0 // sorry for this but I have a strange error that the y value jumps at @@ -1313,7 +1319,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) << bv->text->cursor.y() << endl; #endif // This is to allow jumping over large insets - if (cursorrow == bv->text->cursor.row()) { + if (cursorrow == bv->text->cursorRow()) { if (cmd.y >= bv->workHeight()) bv->text->cursorDown(false); else if (cmd.y < 0) @@ -1324,7 +1330,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) if (!bv->text->selection.set()) bv->update(BufferView::UPDATE); bv->text->setSelection(); - bv->screen().toggleToggle(bv->text, bv); + bv->repaint(); bv->fitCursor(); break; } @@ -1350,7 +1356,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) int x = cmd.x; int y = cmd.y; - Inset * inset_hit = bv->text->checkInsetHit(x, y); + InsetOld * inset_hit = bv->text->checkInsetHit(x, y); // Middle button press pastes if we have a selection // We do this here as if the selection was inside an inset @@ -1383,7 +1389,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // Clear the selection bv->screen().toggleSelection(bv->text, bv); bv->text->clearSelection(); - bv->text->fullRebreak(); + bv->text->partialRebreak(); bv->update(); bv->updateScrollbar(); @@ -1445,7 +1451,7 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // inset, inset_hit is 0, and inset_x == x, inset_y == y. int x = cmd.x; int y = cmd.y; - Inset * inset_hit = bv->text->checkInsetHit(x, y); + InsetOld * inset_hit = bv->text->checkInsetHit(x, y); if (bv->theLockingInset()) { // We are in inset locking mode. @@ -1505,8 +1511,8 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) // (Joacim) // ...or maybe the SetCursorParUndo() // below isn't necessary at all anylonger? - if (inset_hit->lyxCode() == Inset::REF_CODE) - setCursorParUndo(bv); + if (inset_hit->lyxCode() == InsetOld::REF_CODE) + recordUndo(bv, Undo::ATOMIC); bv->owner()->message(inset_hit->editMessage()); @@ -1598,7 +1604,6 @@ Inset::RESULT LyXText::dispatch(FuncRequest const & cmd) break; case LFUN_INDEX_PRINT: - case LFUN_PARENTINSERT: case LFUN_TOC_INSERT: case LFUN_HFILL: // do nothing fancy