X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=4133732325f9ee46ee023724806c3002dfd269bf;hb=65ec1c0437fd53ac6cff0b329f1563d91e481b6e;hp=45b5163613b1cd9e15dd5c326ff300a1a8bf97cd;hpb=cd6e293ed7c588748fe0cf5927f46dc5e9ae6e35;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 45b5163613..4133732325 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -10,12 +10,6 @@ #include -#include -#include - -#include -//#include - #ifdef __GNUG__ #pragma implementation #endif @@ -32,15 +26,11 @@ #include "layout.h" #include "LaTeXFeatures.h" #include "Painter.h" -#include "frontends/Alert.h" #include "lyxtext.h" #include "lyxcursor.h" #include "CutAndPaste.h" #include "font.h" #include "LColor.h" -#include "support/textutils.h" -#include "support/LAssert.h" -#include "support/lstrings.h" #include "lyxrow.h" #include "lyxrc.h" #include "intl.h" @@ -53,6 +43,17 @@ #include "undo_funcs.h" #include "lyxfind.h" +#include "frontends/Alert.h" + +#include "support/textutils.h" +#include "support/LAssert.h" +#include "support/lstrings.h" + +#include +#include +#include +//#include + using std::ostream; using std::ifstream; using std::endl; @@ -61,6 +62,10 @@ using std::max; using std::make_pair; using std::vector; +using lyx::pos_type; +using lyx::layout_type; +using lyx::textclass_type; + extern unsigned char getCurrentTextClass(Buffer *); extern bool math_insert_greek(BufferView *, char); extern int greek_kb_flag; @@ -72,7 +77,7 @@ void InsetText::saveLyXTextState(LyXText * t) const { // check if my paragraphs are still valid Paragraph * p = par; - while(p) { + while (p) { if (p == t->cursor.par()) break; p = p->next(); @@ -157,7 +162,7 @@ InsetText & InsetText::operator=(InsetText const & it) void InsetText::init(InsetText const * ins, bool same_id) { if (ins) { - setParagraphData(ins->par); + setParagraphData(ins->par, same_id); autoBreakRows = ins->autoBreakRows; drawFrame_ = ins->drawFrame_; frame_color = ins->frame_color; @@ -165,7 +170,7 @@ void InsetText::init(InsetText const * ins, bool same_id) id_ = ins->id_; } else { Paragraph * p = par; - while(p) { + while (p) { p->setInsetOwner(this); p = p->next(); } @@ -175,8 +180,6 @@ void InsetText::init(InsetText const * ins, bool same_id) autoBreakRows = false; } top_y = 0; - last_width = 0; - last_height = 0; insetAscent = 0; insetDescent = 0; insetWidth = 0; @@ -192,6 +195,7 @@ void InsetText::init(InsetText const * ins, bool same_id) frame_is_visible = false; cached_bview = 0; sstate.lpar = 0; + in_insetAllowed = false; } @@ -217,6 +221,7 @@ void InsetText::clear() par = tmp; } par = new Paragraph; + reinitLyXText(); need_update = INIT; } @@ -273,7 +278,7 @@ void InsetText::read(Buffer const * buf, LyXLex & lex) if (!return_par) return_par = par; par = return_par; - while(return_par) { + while (return_par) { return_par->setInsetOwner(this); return_par = return_par->next(); } @@ -288,26 +293,17 @@ void InsetText::read(Buffer const * buf, LyXLex & lex) int InsetText::ascent(BufferView * bv, LyXFont const &) const { - int y_temp = 0; - Row * row = getLyXText(bv)->getRowNearY(y_temp); - insetAscent = row->ascent_of_text() + TEXT_TO_INSET_OFFSET; + insetAscent = getLyXText(bv)->firstRow()->ascent_of_text() + + TEXT_TO_INSET_OFFSET; return insetAscent; } int InsetText::descent(BufferView * bv, LyXFont const &) const { - bool clear = false; - if (!lt) { - lt = getLyXText(bv); - clear = true; - } - int y_temp = 0; - Row * row = lt->getRowNearY(y_temp); - insetDescent = lt->height - row->ascent_of_text() + - TEXT_TO_INSET_OFFSET; - if (clear) - lt = 0; + LyXText * llt = getLyXText(bv); + insetDescent = llt->height - llt->firstRow()->ascent_of_text() + + TEXT_TO_INSET_OFFSET; return insetDescent; } @@ -368,7 +364,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, // repaint the background if needed if (cleared && backgroundColor() != LColor::background) { top_x = int(x); - clearInset(pain, baseline, cleared); + clearInset(bv, baseline, cleared); top_x = old_x; } @@ -389,10 +385,10 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, x += static_cast(scroll()); // if top_x differs we did it already - if (!cleared && (top_x == int(x)) && - ((need_update&(INIT|FULL)) || (top_baseline!=baseline) || - (last_drawn_width!=insetWidth))) { - clearInset(pain, baseline, cleared); + if (!cleared && (top_x == int(x)) + && ((need_update&(INIT|FULL)) || (top_baseline != baseline) + ||(last_drawn_width != insetWidth))) { + clearInset(bv, baseline, cleared); } top_x = int(x); @@ -406,14 +402,18 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, return; } + // call these methods so that insetWidth, insetAscent and + // insetDescent have the right values. + width(bv, f); + ascent(bv, f); + descent(bv, f); + top_baseline = baseline; - top_y = baseline - ascent(bv, f); - last_width = width(bv, f); - last_height = ascent(bv, f) + descent(bv, f); + top_y = baseline - insetAscent; - if (cleared || (last_drawn_width != insetWidth)) { + if (last_drawn_width != insetWidth) { if (!cleared) - clearInset(pain, baseline, cleared); + clearInset(bv, baseline, cleared); need_update |= FULL; last_drawn_width = insetWidth; } @@ -426,7 +426,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, if (!cleared && (need_update == CURSOR) && !getLyXText(bv)->selection.set()) { drawFrame(pain, cleared); - x += last_width; // was width(bv, f); + x += insetWidth; need_update = NONE; return; } @@ -437,12 +437,11 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, } x += TEXT_TO_INSET_OFFSET; - int y = 0; - Row * row = lt->getRowNearY(y); + Row * row = lt->firstRow(); int y_offset = baseline - row->ascent_of_text(); int ph = pain.paperHeight(); int first = 0; - y = y_offset; + int y = y_offset; while ((row != 0) && ((y+row->height()) <= 0)) { y += row->height(); first += row->height(); @@ -490,14 +489,13 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, clearFrame(pain, cleared); } - x += last_width /* was width(bv, f) */ - TEXT_TO_INSET_OFFSET; + x += insetWidth - TEXT_TO_INSET_OFFSET; if (bv->text->status() == LyXText::CHANGED_IN_DRAW) { need_update |= FULL; } else if (need_update != INIT) { need_update = NONE; } - if (clear) lt = 0; } @@ -509,7 +507,7 @@ void InsetText::drawFrame(Painter & pain, bool cleared) const if (!frame_is_visible || cleared) { frame_x = top_x + ttoD2; frame_y = top_baseline - insetAscent + ttoD2; - frame_w = last_width - TEXT_TO_INSET_OFFSET; + frame_w = insetWidth - TEXT_TO_INSET_OFFSET; frame_h = insetAscent + insetDescent - TEXT_TO_INSET_OFFSET; pain.rectangle(frame_x, frame_y, frame_w, frame_h, @@ -543,6 +541,7 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) in_update = true; if (reinit || need_update == INIT) { need_update = FULL; + // we should put this call where we set need_update to INIT! reinitLyXText(); if (owner()) owner()->update(bv, font, true); @@ -560,18 +559,6 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) lt = getLyXText(bv); clear = true; } -#if 0 - int oldw = insetWidth; - insetWidth = lt->width + (2 * TEXT_TO_INSET_OFFSET); - if (oldw != insetWidth) { - resizeLyXText(bv); - need_update |= FULL; - if (clear) - lt = 0; - in_update = false; - return; - } -#endif if ((need_update & CURSOR_PAR) && (lt->status() == LyXText::UNCHANGED) && the_locking_inset) { @@ -587,36 +574,34 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) void InsetText::setUpdateStatus(BufferView * bv, int what) const { - bool clear = false; - if (!lt) { - lt = getLyXText(bv); - clear = true; - } + // this does nothing dangerous so use only a localized buffer + LyXText * llt = getLyXText(bv); + need_update |= what; // we have to redraw us full if our LyXText NEEDS_MORE_REFRES or // if we don't break row so that we only have one row to update! - if ((lt->status() == LyXText::NEED_MORE_REFRESH) || + if ((llt->status() == LyXText::NEED_MORE_REFRESH) || (!autoBreakRows && - (lt->status() == LyXText::NEED_VERY_LITTLE_REFRESH))) + (llt->status() == LyXText::NEED_VERY_LITTLE_REFRESH))) { need_update |= FULL; - } else if (lt->status() == LyXText::NEED_VERY_LITTLE_REFRESH) { + } else if (llt->status() == LyXText::NEED_VERY_LITTLE_REFRESH) { need_update |= CURSOR_PAR; } // this to not draw a selection when we redraw all of it! if (need_update & CURSOR && !(need_update & SELECTION)) { - if (lt->selection.set()) + if (llt->selection.set()) need_update = FULL; - lt->clearSelection(); + llt->clearSelection(); } - if (clear) - lt = 0; } void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) const { + if (!autoBreakRows && par->next()) + collapseParagraphs(bv->buffer()->params); bool clear = false; if (!lt) { lt = getLyXText(bv); @@ -624,11 +609,12 @@ void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) const } lt->fullRebreak(bv); setUpdateStatus(bv, what); - if (((need_update != CURSOR) && (need_update != NONE)) || - (lt->status() != LyXText::UNCHANGED) || lt->selection.set()) - { + bool flag = (((need_update != CURSOR) && (need_update != NONE)) || + (lt->status() != LyXText::UNCHANGED) || lt->selection.set()); + if (clear) + lt = 0; + if (flag) bv->updateInset(const_cast(this), mark_dirty); - } if (need_update == CURSOR) need_update = NONE; bv->owner()->showState(); @@ -636,8 +622,6 @@ void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) const bv->owner()->setLayout(cpar(bv)->getLayout()); old_par = cpar(bv); } - if (clear) - lt = 0; } @@ -667,25 +651,24 @@ void InsetText::edit(BufferView * bv, int x, int y, unsigned int button) lt = getLyXText(bv); clear = true; } - if (!checkAndActivateInset(bv, x, tmp_y, button)) lt->setCursorFromCoordinates(bv, x - drawTextXOffset, y + insetAscent); lt->clearSelection(); finishUndo(); - showInsetCursor(bv); - updateLocal(bv, CURSOR, false); - // If the inset is empty set the language of the current font to the // language to the surronding text (if different). if (par->size() == 0 && !par->next() && - bv->getParentLanguage(this) != lt->current_font.language()) { + bv->getParentLanguage(this) != lt->current_font.language()) + { LyXFont font(LyXFont::ALL_IGNORE); font.setLanguage(bv->getParentLanguage(this)); setFont(bv, font, false); } + showInsetCursor(bv); if (clear) lt = 0; + updateLocal(bv, CURSOR, false); } @@ -712,16 +695,13 @@ void InsetText::edit(BufferView * bv, bool front) lt->setCursor(bv, par, 0); else { Paragraph * p = par; - while(p->next()) + while (p->next()) p = p->next(); // int const pos = (p->size() ? p->size()-1 : p->size()); lt->setCursor(bv, p, p->size()); } lt->clearSelection(); finishUndo(); - showInsetCursor(bv); - updateLocal(bv, CURSOR, false); - // If the inset is empty set the language of the current font to the // language to the surronding text (if different). if (par->size() == 0 && !par->next() && @@ -730,8 +710,10 @@ void InsetText::edit(BufferView * bv, bool front) font.setLanguage(bv->getParentLanguage(this)); setFont(bv, font, false); } + showInsetCursor(bv); if (clear) lt = 0; + updateLocal(bv, CURSOR, false); } @@ -764,9 +746,20 @@ void InsetText::insetUnlock(BufferView * bv) bv->owner()->setLayout(bv->text->cursor.par()->getLayout()); // hack for deleteEmptyParMech lt->setCursor(bv, par, 0); - updateLocal(bv, code, false); if (clear) lt = 0; + updateLocal(bv, code, false); +} + +void InsetText::lockInset(BufferView * bv, UpdatableInset * inset) +{ + the_locking_inset = inset; + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + inset_pos = cpos(bv); + inset_par = cpar(bv); + inset_boundary = cboundary(bv); + updateLocal(bv, CURSOR, false); } @@ -776,15 +769,32 @@ bool InsetText::lockInsetInInset(BufferView * bv, UpdatableInset * inset) << inset << "): "; if (!inset) return false; + if (!the_locking_inset) { + Paragraph * p = par; + int const id = inset->id(); + while(p) { + Paragraph::inset_iterator it = + p->inset_iterator_begin(); + Paragraph::inset_iterator const end = + p->inset_iterator_end(); + for (; it != end; ++it) { + if ((*it) == inset) { + getLyXText(bv)->setCursorIntern(bv, p, it.getPos()); + lockInset(bv, inset); + return true; + } + if ((*it)->getInsetFromID(id)) { + lockInset(bv, static_cast(*it)); + return the_locking_inset->lockInsetInInset(bv, inset); + } + } + p = p->next(); + } + return false; + } if (inset == cpar(bv)->getInset(cpos(bv))) { lyxerr[Debug::INSETS] << "OK" << endl; - the_locking_inset = inset; - inset_x = cx(bv) - top_x + drawTextXOffset; - inset_y = cy(bv) + drawTextYOffset; - inset_pos = cpos(bv); - inset_par = cpar(bv); - inset_boundary = cboundary(bv); - updateLocal(bv, CURSOR, false); + lockInset(bv, inset); return true; } else if (the_locking_inset && (the_locking_inset == inset)) { if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { @@ -827,20 +837,42 @@ bool InsetText::unlockInsetInInset(BufferView * bv, UpdatableInset * inset, bool InsetText::updateInsetInInset(BufferView * bv, Inset * inset) { - if (!the_locking_inset) - return false; + if (!autoBreakRows && par->next()) + collapseParagraphs(bv->buffer()->params); + if (inset == this) + return true; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + if (!the_locking_inset) { + bool found = lt->updateInset(bv, inset); + if (clear) + lt = 0; + if (found) + setUpdateStatus(bv, NONE); + return found; + } if (the_locking_inset != inset) { - getLyXText(bv)->updateInset(bv, the_locking_inset); - setUpdateStatus(bv, CURSOR_PAR); - return the_locking_inset->updateInsetInInset(bv, inset); + bool found = the_locking_inset->updateInsetInInset(bv, inset); + if (clear) + lt = 0; + if (found) + setUpdateStatus(bv, CURSOR_PAR); + return found; } - if (getLyXText(bv)->updateInset(bv, inset)) - updateLocal(bv, CURSOR_PAR, false); - if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { - inset_x = cx(bv) - top_x + drawTextXOffset; - inset_y = cy(bv) + drawTextYOffset; + bool found = lt->updateInset(bv, inset); + if (clear) + lt = 0; + if (found) { + setUpdateStatus(bv, CURSOR_PAR); + if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + } } - return true; + return found; } @@ -848,14 +880,21 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) { no_selection = true; + // use this to check mouse motion for selection! + mouse_x = x; + mouse_y = y; + int tmp_x = x - drawTextXOffset; int tmp_y = y + insetAscent - getLyXText(bv)->first; - Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y, button); + Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y); hideInsetCursor(bv); if (the_locking_inset) { if (the_locking_inset == inset) { - the_locking_inset->insetButtonPress(bv,x-inset_x,y-inset_y,button); + the_locking_inset->insetButtonPress(bv, + x - inset_x, + y - inset_y, + button); no_selection = false; return; } else if (inset) { @@ -864,7 +903,8 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) inset_x = cx(bv) - top_x + drawTextXOffset; inset_y = cy(bv) + drawTextYOffset; the_locking_inset = static_cast(inset); - inset->insetButtonPress(bv, x - inset_x, y - inset_y, button); + inset->insetButtonPress(bv, x - inset_x, + y - inset_y, button); inset->edit(bv, x - inset_x, y - inset_y, button); if (the_locking_inset) updateLocal(bv, CURSOR, false); @@ -904,12 +944,22 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) lt = getLyXText(bv); clear = true; } - lt->setCursorFromCoordinates(bv, x-drawTextXOffset, y + insetAscent); + + lt->setCursorFromCoordinates(bv, x - drawTextXOffset, + y + insetAscent); + // set the selection cursor! + lt->selection.cursor = lt->cursor; + lt->cursor.x_fix(lt->cursor.x()); + if (lt->selection.set()) { lt->clearSelection(); + if (clear) + lt = 0; updateLocal(bv, FULL, false); } else { lt->clearSelection(); + if (clear) + lt = 0; } bv->owner()->setLayout(cpar(bv)->getLayout()); old_par = cpar(bv); @@ -923,61 +973,73 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) localDispatch(bv, LFUN_PASTESELECTION, "paragraph"); } - if (clear) - lt = 0; + } else { + getLyXText(bv)->clearSelection(); } showInsetCursor(bv); no_selection = false; } -void InsetText::insetButtonRelease(BufferView * bv, int x, int y, int button) +bool InsetText::insetButtonRelease(BufferView * bv, int x, int y, int button) { - UpdatableInset * inset = 0; - if (the_locking_inset) { - the_locking_inset->insetButtonRelease(bv, - x - inset_x, y - inset_y, - button); - } else { - if (cpar(bv)->isInset(cpos(bv))) { - inset = static_cast(cpar(bv)->getInset(cpos(bv))); - if (isHighlyEditableInset(inset)) { - inset->insetButtonRelease(bv, - x - inset_x, - y - inset_y, button); - } else { - inset_x = cx(bv) - top_x + drawTextXOffset; - inset_y = cy(bv) + drawTextYOffset; - inset->insetButtonRelease(bv, - x - inset_x, - y - inset_y, button); - inset->edit(bv, - x - inset_x, y - inset_y, button); - } - updateLocal(bv, CURSOR_PAR, false); + return the_locking_inset->insetButtonRelease(bv, + x - inset_x, y - inset_y, + button); + } + int tmp_x = x - drawTextXOffset; + int tmp_y = y + insetAscent - getLyXText(bv)->first; + Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y); + bool ret = false; + if (inset) { + if (isHighlyEditableInset(inset)) { + ret = inset->insetButtonRelease(bv, x - inset_x, + y - inset_y, button); + } else { + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + ret = inset->insetButtonRelease(bv, x - inset_x, + y - inset_y, button); + inset->edit(bv, x - inset_x, + y - inset_y, button); } + updateLocal(bv, CURSOR_PAR, false); } - no_selection = false; + return ret; } void InsetText::insetMotionNotify(BufferView * bv, int x, int y, int state) { - if (no_selection) + if (no_selection || ((mouse_x == x) && (mouse_y == y))) return; if (the_locking_inset) { the_locking_inset->insetMotionNotify(bv, x - inset_x, - y - inset_y,state); + y - inset_y,state); return; } - LyXText * t = getLyXText(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } hideInsetCursor(bv); - t->setCursorFromCoordinates(bv, x - drawTextXOffset, y + insetAscent); - t->setSelection(bv); - if (t->toggle_cursor.par() != t->toggle_end_cursor.par() || - t->toggle_cursor.pos() != t->toggle_end_cursor.pos()) + LyXCursor cur = lt->cursor; + lt->setCursorFromCoordinates(bv, x - drawTextXOffset, y + insetAscent); + if (cur == lt->cursor) { + if (clear) + lt = 0; + return; + } + lt->setSelection(bv); + bool flag = (lt->toggle_cursor.par() != lt->toggle_end_cursor.par() || + lt->toggle_cursor.pos() != lt->toggle_end_cursor.pos()); + if (clear) + lt = 0; + if (flag) { updateLocal(bv, SELECTION, false); + } showInsetCursor(bv); } @@ -1049,6 +1111,8 @@ InsetText::localDispatch(BufferView * bv, lt = getLyXText(bv); clear = true; } + int updwhat = 0; + int updflag = false; switch (action) { // Normal chars case LFUN_SELFINSERT: @@ -1077,7 +1141,8 @@ InsetText::localDispatch(BufferView * bv, } } lt->selection.cursor = lt->cursor; - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; result = DISPATCHED_NOUPDATE; break; // --- Cursor Movements ----------------------------------- @@ -1085,54 +1150,54 @@ InsetText::localDispatch(BufferView * bv, finishUndo(); moveRight(bv, false, true); lt->setSelection(bv); - updateLocal(bv, SELECTION, false); + updwhat = SELECTION; break; case LFUN_RIGHT: result = moveRight(bv); finishUndo(); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_LEFTSEL: finishUndo(); moveLeft(bv, false, true); lt->setSelection(bv); - updateLocal(bv, SELECTION, false); + updwhat = SELECTION; break; case LFUN_LEFT: finishUndo(); result = moveLeft(bv); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_DOWNSEL: finishUndo(); moveDown(bv); lt->setSelection(bv); - updateLocal(bv, SELECTION, false); + updwhat = SELECTION; break; case LFUN_DOWN: finishUndo(); result = moveDown(bv); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_UPSEL: finishUndo(); moveUp(bv); lt->setSelection(bv); - updateLocal(bv, SELECTION, false); + updwhat = SELECTION; break; case LFUN_UP: finishUndo(); result = moveUp(bv); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_HOME: finishUndo(); lt->cursorHome(bv); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_END: lt->cursorEnd(bv); - updateLocal(bv, CURSOR, false); + updwhat = CURSOR; break; case LFUN_BACKSPACE: { setUndo(bv, Undo::DELETE, @@ -1141,7 +1206,8 @@ InsetText::localDispatch(BufferView * bv, lt->cutSelection(bv); else lt->backspace(bv); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } break; @@ -1153,7 +1219,8 @@ InsetText::localDispatch(BufferView * bv, } else { lt->Delete(bv); } - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } break; @@ -1161,14 +1228,15 @@ InsetText::localDispatch(BufferView * bv, setUndo(bv, Undo::DELETE, lt->cursor.par(), lt->cursor.par()->next()); lt->cutSelection(bv); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } break; case LFUN_COPY: finishUndo(); lt->copySelection(bv); - updateLocal(bv, CURSOR_PAR, false); + updwhat = CURSOR_PAR; break; case LFUN_PASTESELECTION: { @@ -1181,7 +1249,8 @@ InsetText::localDispatch(BufferView * bv, } else { lt->insertStringAsLines(bv, clip); } - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; break; } case LFUN_PASTE: { @@ -1197,7 +1266,8 @@ InsetText::localDispatch(BufferView * bv, setUndo(bv, Undo::INSERT, lt->cursor.par(), lt->cursor.par()->next()); lt->pasteSelection(bv); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } break; @@ -1207,7 +1277,8 @@ InsetText::localDispatch(BufferView * bv, break; } lt->breakParagraph(bv, 0); - updateLocal(bv, FULL, true); + updwhat = FULL; + updflag = true; break; case LFUN_BREAKPARAGRAPHKEEPLAYOUT: if (!autoBreakRows) { @@ -1215,7 +1286,8 @@ InsetText::localDispatch(BufferView * bv, break; } lt->breakParagraph(bv, 1); - updateLocal(bv, FULL, true); + updwhat = FULL; + updflag = true; break; case LFUN_BREAKLINE: { @@ -1226,20 +1298,20 @@ InsetText::localDispatch(BufferView * bv, setUndo(bv, Undo::INSERT, lt->cursor.par(), lt->cursor.par()->next()); lt->insertChar(bv, Paragraph::META_NEWLINE); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } break; case LFUN_LAYOUT: // do not set layouts on non breakable textinsets if (autoBreakRows) { - LyXTextClass::size_type cur_layout = cpar(bv)->layout; + layout_type cur_layout = cpar(bv)->layout; // Derive layout number from given argument (string) // and current buffer's textclass (number). */ - LyXTextClassList::ClassList::size_type tclass = - bv->buffer()->params.textclass; - std::pair layout = + textclass_type tclass = bv->buffer()->params.textclass; + std::pair layout = textclasslist.NumberOfLayout(tclass, arg); // If the entry is obsolete, use the new one instead. @@ -1261,7 +1333,8 @@ InsetText::localDispatch(BufferView * bv, cur_layout = layout.second; lt->setLayout(bv, layout.second); bv->owner()->setLayout(cpar(bv)->getLayout()); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } } else { // reset the layout box @@ -1309,7 +1382,8 @@ InsetText::localDispatch(BufferView * bv, } if (cur_spacing != new_spacing || cur_value != new_value) { par->params().spacing(Spacing(new_spacing, new_value)); - updateLocal(bv, CURSOR_PAR, true); + updwhat = CURSOR_PAR; + updflag = true; } } break; @@ -1320,6 +1394,10 @@ InsetText::localDispatch(BufferView * bv, break; } + if (clear) + lt = 0; + if (updwhat > 0) + updateLocal(bv, updwhat, updflag); /// If the action has deleted all text in the inset, we need to change the // language to the language of the surronding text. if (!was_empty && par->size() == 0 && !par->next()) { @@ -1332,8 +1410,6 @@ InsetText::localDispatch(BufferView * bv, showInsetCursor(bv); } else bv->unlockInset(this); - if (clear) - lt = 0; return result; } @@ -1743,25 +1819,30 @@ bool InsetText::insertInset(BufferView * bv, Inset * inset) clear = true; } lt->insertInset(bv, inset); -#if 0 - if ((!cpar(bv)->isInset(cpos(bv))) || - (cpar(bv)->getInset(cpos(bv)) != inset)) - lt->cursorLeft(bv); -#endif bv->fitCursor(); - updateLocal(bv, CURSOR_PAR|CURSOR, true); - showInsetCursor(bv); if (clear) lt = 0; + updateLocal(bv, CURSOR_PAR|CURSOR, true); return true; } bool InsetText::insetAllowed(Inset::Code code) const { + // in_insetAllowed is a really gross hack, + // to allow us to call the owner's insetAllowed + // without stack overflow, which can happen + // when the owner uses InsetCollapsable::insetAllowed() + bool ret = true; + if (in_insetAllowed) + return ret; + in_insetAllowed = true; if (the_locking_inset) - return the_locking_inset->insetAllowed(code); - return true; + ret = the_locking_inset->insetAllowed(code); + else if (owner()) + ret = owner()->insetAllowed(code); + in_insetAllowed = false; + return ret; } @@ -1833,12 +1914,13 @@ void InsetText::setFont(BufferView * bv, LyXFont const & font, bool toggleall, if (selectall) lt->clearSelection(); bv->fitCursor(); - if (selectall || lt->selection.set()) + bool flag = (selectall || lt->selection.set()); + if (clear) + lt = 0; + if (flag) updateLocal(bv, FULL, true); else updateLocal(bv, CURSOR_PAR, true); - if (clear) - lt = 0; } @@ -1878,7 +1960,7 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, x -= drawTextXOffset; int dummyx = x; int dummyy = y + insetAscent; - Inset * inset = bv->checkInsetHit(getLyXText(bv), dummyx, dummyy, button); + Inset * inset = bv->checkInsetHit(getLyXText(bv), dummyx, dummyy); if (inset) { if (x < 0) @@ -1916,7 +1998,7 @@ int InsetText::getMaxWidth(BufferView * bv, UpdatableInset const * inset) const } -void InsetText::setParagraphData(Paragraph * p) +void InsetText::setParagraphData(Paragraph * p, bool same_id) { // we have to unlock any locked inset otherwise we're in troubles the_locking_inset = 0; @@ -1926,16 +2008,17 @@ void InsetText::setParagraphData(Paragraph * p) par = tmp; } - par = new Paragraph(*p, false); + par = new Paragraph(*p, same_id); par->setInsetOwner(this); Paragraph * np = par; while (p->next()) { p = p->next(); - np->next(new Paragraph(*p, false)); + np->next(new Paragraph(*p, same_id)); np->next()->previous(np); np = np->next(); np->setInsetOwner(this); } + reinitLyXText(); need_update = INIT; } @@ -1982,21 +2065,15 @@ void InsetText::setFrameColor(BufferView * bv, LColor::color col) int InsetText::cx(BufferView * bv) const { - bool clear = false; - if (!lt) { - lt = getLyXText(bv); - clear = true; - } - int x = lt->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; + // we do nothing dangerous so we use a local cache + LyXText * llt = getLyXText(bv); + int x = llt->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; if (the_locking_inset) { - LyXFont font = lt->getFont(bv->buffer(), - lt->cursor.par(), - lt->cursor.pos()); + LyXFont font = llt->getFont(bv->buffer(), llt->cursor.par(), + llt->cursor.pos()); if (font.isVisibleRightToLeft()) x -= the_locking_inset->width(bv, font); } - if (clear) - lt = 0; return x; } @@ -2008,7 +2085,7 @@ int InsetText::cy(BufferView * bv) const } -Paragraph::pos_type InsetText::cpos(BufferView * bv) const +pos_type InsetText::cpos(BufferView * bv) const { return getLyXText(bv)->cursor.pos(); } @@ -2035,8 +2112,11 @@ Row * InsetText::crow(BufferView * bv) const LyXText * InsetText::getLyXText(BufferView const * lbv, bool const recursive) const { - if (!recursive && (cached_bview == lbv)) + if (!recursive && (cached_bview == lbv)) { + LyXText * lt = cached_text.get(); + lyx::Assert(lt && lt->firstRow()->par() == par); return cached_text.get(); + } // Super UGLY! (Lgb) BufferView * bv = const_cast(lbv); @@ -2111,8 +2191,14 @@ void InsetText::resizeLyXText(BufferView * bv, bool force) const } do_resize = 0; // lyxerr << "InsetText::resizeLyXText\n"; - if (!par->next() && !par->size()) // no data, resize not neccessary! + if (!par->next() && !par->size()) { // no data, resize not neccessary! + // we have to do this as a fixed width may have changed! + LyXText * t = getLyXText(bv); + saveLyXTextState(t); + t->init(bv, true); + restoreLyXTextState(bv, t); return; + } // one endless line, resize normally not necessary if (!force && getMaxWidth(bv, this) < 0) return; @@ -2191,12 +2277,18 @@ void InsetText::reinitLyXText() const void InsetText::removeNewlines() { + bool changed = false; + for (Paragraph * p = par; p; p = p->next()) { for (int i = 0; i < p->size(); ++i) { - if (p->getChar(i) == Paragraph::META_NEWLINE) + if (p->getChar(i) == Paragraph::META_NEWLINE) { + changed = true; p->erase(i); + } } } + if (changed) + reinitLyXText(); } @@ -2240,10 +2332,12 @@ void InsetText::clearSelection(BufferView * bv) } -void InsetText::clearInset(Painter & pain, int baseline, bool & cleared) const +void InsetText::clearInset(BufferView * bv, int baseline, bool & cleared) const { + LyXFont dummy; + Painter & pain = bv->painter(); int w = insetWidth; - int h = insetAscent + insetDescent; + int h = ascent(bv, dummy) + descent(bv, dummy); int ty = baseline - insetAscent; if (ty < 0) { @@ -2276,8 +2370,6 @@ Paragraph * InsetText::getParFromID(int id) const #else Paragraph * tmp = par; while (tmp) { - int tmp_id = tmp->id(); - lyxerr << "Looking at paragraph: " << tmp_id << endl; if (tmp->id() == id) { return tmp; } @@ -2324,14 +2416,19 @@ Paragraph * InsetText::paragraph() const void InsetText::paragraph(Paragraph * p) { + // GENERAL COMMENT: We don't have to free the old paragraphs as the + // caller of this function has to take care of it. This IS important + // as we could have to insert a paragraph before this one and just + // link the actual to a new ones next and set it with this function + // and are done! par = p; -#if 0 - // we now have to update/redraw all instances - for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit) { - delete cit->second; - cit->second = 0; + // set ourself as owner for all the paragraphs inserted! + Paragraph * np = par; + while (np) { + np->setInsetOwner(this); + np = np->next(); } -#endif + reinitLyXText(); // redraw myself when asked for need_update = INIT; } @@ -2344,7 +2441,7 @@ Inset * InsetText::getInsetFromID(int id_arg) const Paragraph * lp = par; - while(lp) { + while (lp) { for (Paragraph::inset_iterator it = lp->inset_iterator_begin(), en = lp->inset_iterator_end(); it != en; ++it) @@ -2418,10 +2515,9 @@ void InsetText::toggleSelection(BufferView * bv, bool kill_selection) int x = top_x + TEXT_TO_INSET_OFFSET; - int y = 0; - Row * row = lt->getRowNearY(y); + Row * row = lt->firstRow(); int y_offset = top_baseline - row->ascent_of_text(); - y = y_offset; + int y = y_offset; while ((row != 0) && ((y+row->height()) <= 0)) { y += row->height(); row = row->next(); @@ -2438,7 +2534,7 @@ void InsetText::toggleSelection(BufferView * bv, bool kill_selection) bool InsetText::searchForward(BufferView * bv, string const & str, - bool const & cs, bool const & mw) + bool cs, bool mw) { if (the_locking_inset) { if (the_locking_inset->searchForward(bv, str, cs, mw)) @@ -2449,7 +2545,7 @@ bool InsetText::searchForward(BufferView * bv, string const & str, clear = true; } Paragraph * lpar = lt->cursor.par(); - Paragraph::pos_type pos = lt->cursor.pos(); + pos_type pos = lt->cursor.pos(); if (pos < lpar->size() - 1) ++pos; else { @@ -2476,7 +2572,7 @@ bool InsetText::searchForward(BufferView * bv, string const & str, } bool InsetText::searchBackward(BufferView * bv, string const & str, - bool const & cs, bool const & mw) + bool cs, bool mw) { if (the_locking_inset) if (the_locking_inset->searchBackward(bv, str, cs, mw)) @@ -2496,3 +2592,14 @@ bool InsetText::checkInsertChar(LyXFont & font) return owner()->checkInsertChar(font); return true; } + + +void InsetText::collapseParagraphs(BufferParams const & bparams) const +{ + while(par->next()) { + if (!par->isSeparator(par->size()-1)) + par->insertChar(par->size()-1, ' '); + par->pasteParagraph(bparams); + } + reinitLyXText(); +}