X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=3355374259fdf4c345b553e51ce725933b41c29f;hb=8075064372c5361f2dfd91860003f0cb317b4e39;hp=c963880c597d4e92c9882ee2c31ece6d6012c67c;hpb=f52893a07d9ca5a796c5f9a0a95b87fdf456f1e7;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index c963880c59..3355374259 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -14,6 +14,7 @@ #include #include +//#include #ifdef __GNUG__ #pragma implementation @@ -39,6 +40,7 @@ #include "LColor.h" #include "support/textutils.h" #include "support/LAssert.h" +#include "support/lstrings.h" #include "lyxrow.h" #include "lyxrc.h" #include "intl.h" @@ -48,29 +50,86 @@ #include "gettext.h" #include "lyxfunc.h" #include "ParagraphParameters.h" +#include "undo_funcs.h" +#include "lyxfind.h" using std::ostream; using std::ifstream; using std::endl; using std::min; using std::max; +using std::make_pair; extern unsigned char getCurrentTextClass(Buffer *); extern bool math_insert_greek(BufferView *, char); extern int greek_kb_flag; + +#warning this functions should probably go into bufferview_funcs somehow (Jug) + +void InsetText::saveLyXTextState(LyXText * t) const +{ + sstate.lpar = t->cursor.par(); + sstate.pos = t->cursor.pos(); + sstate.boundary = t->cursor.boundary(); + sstate.selstartpar = t->selection.start.par(); + sstate.selstartpos = t->selection.start.pos(); + sstate.selstartboundary = t->selection.start.boundary(); + sstate.selendpar = t->selection.end.par(); + sstate.selendpos = t->selection.end.pos(); + sstate.selendboundary = t->selection.end.boundary(); + sstate.selection = t->selection.set(); + sstate.mark_set = t->selection.mark(); + sstate.refresh = t->refresh_row != 0; +} + +void InsetText::restoreLyXTextState(BufferView * bv, LyXText * t) const +{ + if (sstate.lpar) { + t->selection.set(true); + /* at this point just to avoid the Delete-Empty-Paragraph + * Mechanism when setting the cursor */ + t->selection.mark(sstate.mark_set); + if (sstate.selection) { + t->setCursor(bv, sstate.selstartpar, sstate.selstartpos, + true, sstate.selstartboundary); + t->selection.cursor = t->cursor; + t->setCursor(bv, sstate.selendpar, sstate.selendpos, + true, sstate.selendboundary); + t->setSelection(bv); + t->setCursor(bv, sstate.lpar, sstate.pos); + } else { + t->setCursor(bv, sstate.lpar, sstate.pos, true, sstate.boundary); + t->selection.cursor = t->cursor; + t->selection.set(false); + } + if (sstate.refresh) { + } + } +} + + +InsetText::InnerCache::InnerCache(boost::shared_ptr t) +{ + text = t; + remove = false; +} + + InsetText::InsetText() { par = new Paragraph; init(); + in_update = false; } -InsetText::InsetText(InsetText const & ins) +InsetText::InsetText(InsetText const & ins, bool same_id) : UpdatableInset() { par = 0; - init(&ins); + init(&ins, same_id); + in_update = false; autoBreakRows = ins.autoBreakRows; } @@ -83,7 +142,7 @@ InsetText & InsetText::operator=(InsetText const & it) } -void InsetText::init(InsetText const * ins) +void InsetText::init(InsetText const * ins, bool same_id) { top_y = 0; last_width = 0; @@ -100,31 +159,32 @@ void InsetText::init(InsetText const * ins) autoBreakRows = false; drawFrame_ = NEVER; xpos = 0.0; + frame_color = LColor::insetframe; if (ins) { setParagraphData(ins->par); autoBreakRows = ins->autoBreakRows; drawFrame_ = ins->drawFrame_; + frame_color = ins->frame_color; + if (same_id) + id_ = ins->id_; } par->setInsetOwner(this); - frame_color = LColor::insetframe; locked = false; old_par = 0; last_drawn_width = -1; frame_is_visible = false; cached_bview = 0; + sstate.lpar = 0; + lt = 0; } InsetText::~InsetText() { - // delete all instances of LyXText before deleting the paragraps used - // by it. cached_bview = 0; - for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit) { - delete (*cit).second; - (*cit).second = 0; - } + // NOTE + while (par) { Paragraph * tmp = par->next(); delete par; @@ -135,27 +195,19 @@ InsetText::~InsetText() void InsetText::clear() { - // delete all instances of LyXText before deleting the paragraps used - // by it. - cached_bview = 0; - for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit) { - delete (*cit).second; - (*cit).second = 0; - } - while (par) { Paragraph * tmp = par->next(); delete par; par = tmp; } par = new Paragraph; + reinitLyXText(); } -Inset * InsetText::clone(Buffer const &) const +Inset * InsetText::clone(Buffer const &, bool same_id) const { - InsetText * t = new InsetText(*this); - return t; + return new InsetText(*this, same_id); } @@ -182,13 +234,18 @@ void InsetText::read(Buffer const * buf, LyXLex & lex) clear(); - while (lex.IsOK()) { + while (lex.isOK()) { lex.nextToken(); - token = lex.GetString(); + token = lex.getString(); if (token.empty()) continue; - if (token == "\\end_inset") + if (token == "\\end_inset") { +#ifndef NO_COMPABILITY + const_cast(buf)->insertErtContents(par, pos, font, false); +#endif break; + } + if (const_cast(buf)-> parseSingleLyXformat2Token(lex, par, return_par, token, pos, depth, font)) { @@ -224,27 +281,45 @@ int InsetText::ascent(BufferView * bv, LyXFont const &) const int InsetText::descent(BufferView * bv, LyXFont const &) const { - LyXText * t = getLyXText(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } int y_temp = 0; - Row * row = t->getRowNearY(y_temp); - insetDescent = t->height - row->ascent_of_text() + + Row * row = lt->getRowNearY(y_temp); + insetDescent = lt->height - row->ascent_of_text() + TEXT_TO_INSET_OFFSET; + if (clear) + lt = 0; return insetDescent; } int InsetText::width(BufferView * bv, LyXFont const &) const { - insetWidth = max(textWidth(bv), - (int)getLyXText(bv)->width + (2 * TEXT_TO_INSET_OFFSET)); + insetWidth = max(textWidth(bv), (int)getLyXText(bv)->width) + + (2 * TEXT_TO_INSET_OFFSET); + insetWidth = max(insetWidth, 10); return insetWidth; } -int InsetText::textWidth(BufferView * bv) const +int InsetText::textWidth(BufferView * bv, bool fordraw) const { - int const w = getMaxWidth(bv, this); - return w; + int w; + if (!autoBreakRows) { + w = -1; + } else { + w = getMaxWidth(bv, this); + } + if (fordraw) { + return max(w - (2 * TEXT_TO_INSET_OFFSET), + (int)getLyXText(bv)->width); + } else if (w < 0) { + return -1; + } + return w - (2 * TEXT_TO_INSET_OFFSET); } @@ -255,33 +330,45 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, return; Painter & pain = bv->painter(); + + // this is the first thing we have to ask because if the x pos + // changed we have to do a complete rebreak of the text as we + // may have few space to draw in. Well we should check on this too + int old_x = top_x; + if (top_x != int(x)) { + top_x = int(x); + int nw = getMaxWidth(bv, this); + if (nw > 0 && old_max_width != nw) { + need_update = INIT; + old_max_width = nw; + bv->text->status(bv, LyXText::CHANGED_IN_DRAW); + return; + } else { + top_x = old_x; + } + } + + // repaint the background if needed + if (cleared && backgroundColor() != LColor::background) { + top_x = int(x); + clearInset(pain, baseline, cleared); + top_x = old_x; + } // no draw is necessary !!! if ((drawFrame_ == LOCKED) && !locked && !par->size()) { top_x = int(x); top_baseline = baseline; x += width(bv, f); - if (!cleared && (need_update & CLEAR_FRAME)) + if (need_update & CLEAR_FRAME) clearFrame(pain, cleared); - else if (cleared) - frame_is_visible = false; need_update = NONE; return; } xpos = x; -#if 0 - UpdatableInset::draw(bv, f, baseline, x, cleared); -#else if (!owner()) x += static_cast(scroll()); -#endif -#if 0 - // update insetWidth and insetHeight with dummy calls - (void)ascent(bv, f); - (void)descent(bv, f); - (void)width(bv, f); -#endif // if top_x differs we have a rule down and we don't have to clear anything if (!cleared && (top_x == int(x)) && @@ -289,56 +376,51 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, (last_drawn_width!=insetWidth))) { clearInset(pain, baseline, cleared); } + + top_x = int(x); if (cleared) frame_is_visible = false; - if (!cleared && (need_update == NONE)) + if (!cleared && (need_update == NONE)) { + if (locked) + drawFrame(pain, cleared); return; - - if (top_x != int(x)) { - if ((getMaxWidth(bv, this) > 0) && - (getLyXText(bv)->width != old_max_width)) { - resizeLyXText(bv); - need_update |= FULL; - old_max_width = getLyXText(bv)->width; - bv->text->status = LyXText::CHANGED_IN_DRAW; - } - top_x = int(x); -#if 1 - clearInset(pain, baseline, cleared); -#else - return; -#endif } -// lyxerr << "InsetText::draw[" << this << "](" << need_update << ":" << int(x) << ":" << top_x << ")\n"; + top_baseline = baseline; + top_y = baseline - ascent(bv, f); + last_width = width(bv, f); + last_height = ascent(bv, f) + descent(bv, f); if (cleared || (last_drawn_width != insetWidth)) { + if (!cleared) + clearInset(pain, baseline, cleared); need_update |= FULL; last_drawn_width = insetWidth; } - top_baseline = baseline; - top_y = baseline - ascent(bv, f); - last_width = width(bv, f); - last_height = ascent(bv, f) + descent(bv, f); - if (the_locking_inset && (cpar(bv) == inset_par) && (cpos(bv) == inset_pos)) { inset_x = cx(bv) - top_x + drawTextXOffset; inset_y = cy(bv) + drawTextYOffset; } if (!cleared && (need_update == CURSOR) - && !getLyXText(bv)->selection.set()) { + && !getLyXText(bv)->selection.set()) + { drawFrame(pain, cleared); x += last_width; // was width(bv, f); need_update = NONE; return; } + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } x += TEXT_TO_INSET_OFFSET; int y = 0; - Row * row = getLyXText(bv)->getRowNearY(y); + Row * row = lt->getRowNearY(y); int y_offset = baseline - row->ascent_of_text(); int ph = pain.paperHeight(); int first = 0; @@ -350,12 +432,12 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, } if (y_offset < 0) y_offset = y; - getLyXText(bv)->first = first; - if (cleared) { + lt->first = first; + if (cleared || (need_update&(INIT|FULL))) { int yf = y_offset; y = 0; while ((row != 0) && (yf < ph)) { - getLyXText(bv)->getVisibleRow(bv, y+y_offset, int(x), row, + lt->getVisibleRow(bv, y+y_offset, int(x), row, y+first, cleared); y += row->height(); yf += row->height(); @@ -363,44 +445,50 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, } } else if (!locked) { if (need_update & CURSOR) { - bv->screen()->ToggleSelection(getLyXText(bv), bv, true, y_offset,int(x)); - getLyXText(bv)->clearSelection(bv); - getLyXText(bv)->selection.cursor = getLyXText(bv)->cursor; + bv->screen()->toggleSelection(lt, bv, true, y_offset,int(x)); + lt->clearSelection(); + lt->selection.cursor = lt->cursor; } - bv->screen()->Update(getLyXText(bv), bv, y_offset, int(x)); + bv->screen()->update(lt, bv, y_offset, int(x)); } else { locked = false; if (need_update & SELECTION) - bv->screen()->ToggleToggle(getLyXText(bv), bv, y_offset, int(x)); + bv->screen()->toggleToggle(lt, bv, y_offset, int(x)); else if (need_update & CURSOR) { - bv->screen()->ToggleSelection(getLyXText(bv), bv, true, y_offset,int(x)); - getLyXText(bv)->clearSelection(bv); - getLyXText(bv)->selection.cursor = getLyXText(bv)->cursor; + bv->screen()->toggleSelection(lt, bv, true, y_offset,int(x)); + lt->clearSelection(); + lt->selection.cursor = lt->cursor; } - bv->screen()->Update(getLyXText(bv), bv, y_offset, int(x)); + bv->screen()->update(lt, bv, y_offset, int(x)); locked = true; } - getLyXText(bv)->refresh_y = 0; - getLyXText(bv)->status = LyXText::UNCHANGED; + lt->refresh_y = 0; + lt->status(bv, LyXText::UNCHANGED); if ((need_update != CURSOR_PAR) && ((drawFrame_ == ALWAYS) || ((drawFrame_ == LOCKED) && locked))) drawFrame(pain, cleared); else if (need_update & CLEAR_FRAME) clearFrame(pain, cleared); x += last_width /* was width(bv, f) */ - TEXT_TO_INSET_OFFSET; - if (bv->text->status==LyXText::CHANGED_IN_DRAW) { + if (bv->text->status() == LyXText::CHANGED_IN_DRAW) { need_update |= INIT; } else if (need_update != INIT) need_update = NONE; + if (clear) + lt = 0; } void InsetText::drawFrame(Painter & pain, bool cleared) const { + static int const ttoD2 = TEXT_TO_INSET_OFFSET / 2; if (!frame_is_visible || cleared) { - pain.rectangle(top_x + 1, top_baseline - insetAscent + 1, - insetWidth - 1, insetAscent + insetDescent - 1, + frame_x = top_x + ttoD2; + frame_y = top_baseline - insetAscent + ttoD2; + frame_w = last_width - TEXT_TO_INSET_OFFSET; + frame_h = insetAscent + insetDescent - TEXT_TO_INSET_OFFSET; + pain.rectangle(frame_x, frame_y, frame_w, frame_h, frame_color); frame_is_visible = true; } @@ -411,9 +499,8 @@ void InsetText::clearFrame(Painter & pain, bool cleared) const { if (frame_is_visible) { if (!cleared) { - pain.rectangle(top_x + 1, top_baseline - insetAscent + 1, - insetWidth - 1, insetAscent + insetDescent - 1, - LColor::background); + pain.rectangle(frame_x, frame_y, frame_w, frame_h, + backgroundColor()); } frame_is_visible = false; } @@ -422,19 +509,15 @@ void InsetText::clearFrame(Painter & pain, bool cleared) const void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) { - LyXText * t = getLyXText(bv); - -#if 0 - int ww = t->width; - t->BreakParagraph(bv); - if (ww != t->width) - reinit = true; -#endif + if (in_update) + return; + in_update = true; if (reinit) { need_update |= INIT; resizeLyXText(bv); if (owner()) owner()->update(bv, font, true); + in_update = false; return; } if (the_locking_inset) { @@ -442,64 +525,88 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) inset_y = cy(bv) + drawTextYOffset; the_locking_inset->update(bv, font, reinit); } -#if 0 - if (need_update == INIT) { - resizeLyXText(bv); - need_update |= FULL; + + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; } -#endif int oldw = insetWidth; - insetWidth = t->width + (2 * TEXT_TO_INSET_OFFSET); + insetWidth = lt->width + (2 * TEXT_TO_INSET_OFFSET); if (oldw != insetWidth) { resizeLyXText(bv); need_update |= FULL; -// update(bv, font, reinit); + if (clear) + lt = 0; + in_update = false; return; } - if ((need_update & CURSOR_PAR) && t->status == LyXText::UNCHANGED && - the_locking_inset) { - t->updateInset(bv, the_locking_inset); + if ((need_update & CURSOR_PAR) && (lt->status() == LyXText::UNCHANGED) && + the_locking_inset) + { + lt->updateInset(bv, the_locking_inset); } - - if (t->status == LyXText::NEED_MORE_REFRESH) + if (lt->status() == LyXText::NEED_MORE_REFRESH) need_update |= FULL; -#if 0 - int y_temp = 0; - Row * row = t->GetRowNearY(y_temp); - insetAscent = row->ascent_of_text() + TEXT_TO_INSET_OFFSET; - insetDescent = t->height - row->ascent_of_text() + TEXT_TO_INSET_OFFSET; -#endif + if (clear) + lt = 0; + in_update = false; } void InsetText::setUpdateStatus(BufferView * bv, int what) const { - LyXText * t = getLyXText(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } need_update |= what; - if (t->status == LyXText::NEED_MORE_REFRESH) + // 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) || + (!autoBreakRows && + (lt->status() == LyXText::NEED_VERY_LITTLE_REFRESH))) + { need_update |= FULL; - else if (t->status == LyXText::NEED_VERY_LITTLE_REFRESH) + } else if (lt->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 & (INIT|FULL)) && (need_update & CURSOR)) - t->clearSelection(bv); + if (need_update & CURSOR && !(need_update & SELECTION)) { + if (lt->selection.set()) + need_update = FULL; + lt->clearSelection(); + } + if (clear) + lt = 0; } -void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) +void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) const { - LyXText * t = getLyXText(bv); - t->fullRebreak(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + lt->fullRebreak(bv); setUpdateStatus(bv, what); - if (need_update != CURSOR || t->status != LyXText::UNCHANGED || - t->selection.set()) - bv->updateInset(this, mark_dirty); + if (((need_update != CURSOR) && (need_update != NONE)) || + (lt->status() != LyXText::UNCHANGED) || lt->selection.set()) + { + bv->updateInset(const_cast(this), mark_dirty); + } + if (need_update == CURSOR) + need_update = NONE; bv->owner()->showState(); if (old_par != cpar(bv)) { bv->owner()->setLayout(cpar(bv)->getLayout()); old_par = cpar(bv); } + if (clear) + lt = 0; } @@ -511,7 +618,6 @@ string const InsetText::editMessage() const void InsetText::edit(BufferView * bv, int x, int y, unsigned int button) { -// par->SetInsetOwner(this); UpdatableInset::edit(bv, x, y, button); if (!bv->lockInset(this)) { @@ -525,26 +631,76 @@ void InsetText::edit(BufferView * bv, int x, int y, unsigned int button) inset_par = 0; old_par = 0; int tmp_y = (y < 0) ? 0 : y; - LyXText * t = getLyXText(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } - if (!checkAndActivateInset(bv, x, tmp_y, button)) { - t->setCursorFromCoordinates(bv, x - drawTextXOffset, - y + insetAscent); + 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()) { + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + setFont(bv, font, false); } + if (clear) + lt = 0; +} + + +void InsetText::edit(BufferView * bv, bool front) +{ + UpdatableInset::edit(bv, front); - t->selection.cursor = t->cursor; - bv->text->finishUndo(); + if (!bv->lockInset(this)) { + lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; + return; + } + locked = true; + the_locking_inset = 0; + inset_pos = inset_x = inset_y = 0; + inset_boundary = false; + inset_par = 0; + old_par = 0; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + if (front) + lt->setCursor(bv, par, 0); + else { + Paragraph * p = par; + while(p->next()) + p = p->next(); + int const pos = (p->size() ? p->size()-1 : p->size()); + lt->setCursor(bv, p, pos); + } + 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) != t->current_font.language()) { + bv->getParentLanguage(this) != lt->current_font.language()) { LyXFont font(LyXFont::ALL_IGNORE); font.setLanguage(bv->getParentLanguage(this)); setFont(bv, font, false); } + if (clear) + lt = 0; } @@ -557,10 +713,18 @@ void InsetText::insetUnlock(BufferView * bv) hideInsetCursor(bv); no_selection = false; locked = false; - int code = CURSOR|CLEAR_FRAME; - LyXText * t = getLyXText(bv); - if (t->selection.set()) { - t->clearSelection(bv); + int code; + if (drawFrame_ == LOCKED) + code = CURSOR|CLEAR_FRAME; + else + code = CURSOR; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + if (lt->selection.set()) { + lt->clearSelection(); code = FULL; } else if (owner()) { bv->owner()->setLayout(owner()->getLyXText(bv) @@ -568,6 +732,8 @@ void InsetText::insetUnlock(BufferView * bv) } else bv->owner()->setLayout(bv->text->cursor.par()->getLayout()); updateLocal(bv, code, false); + if (clear) + lt = 0; } @@ -585,13 +751,7 @@ bool InsetText::lockInsetInInset(BufferView * bv, UpdatableInset * inset) inset_pos = cpos(bv); inset_par = cpar(bv); inset_boundary = cboundary(bv); -#if 0 - getLyXText(bv)->clearSelection(bv); - getLyXText(bv)->sel_cursor = getLyXText(bv)->cursor; - getLyXText(bv)->UpdateInset(bv, the_locking_inset); -#else updateLocal(bv, CURSOR, false); -#endif return true; } else if (the_locking_inset && (the_locking_inset == inset)) { if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { @@ -641,7 +801,6 @@ bool InsetText::updateInsetInInset(BufferView * bv, Inset * inset) setUpdateStatus(bv, CURSOR_PAR); return the_locking_inset->updateInsetInInset(bv, inset); } -// updateLocal(bv, FULL, false); if (getLyXText(bv)->updateInset(bv, inset)) updateLocal(bv, CURSOR_PAR, false); if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { @@ -707,10 +866,18 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) localDispatch(bv, LFUN_COPY, ""); paste_internally = true; } - getLyXText(bv)->setCursorFromCoordinates(bv, x-drawTextXOffset, - y + insetAscent); - getLyXText(bv)->selection.cursor = getLyXText(bv)->cursor; - updateLocal(bv, CURSOR, false); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + lt->setCursorFromCoordinates(bv, x-drawTextXOffset, y + insetAscent); + if (lt->selection.set()) { + lt->clearSelection(); + updateLocal(bv, FULL, false); + } else { + lt->clearSelection(); + } bv->owner()->setLayout(cpar(bv)->getLayout()); old_par = cpar(bv); // Insert primary selection with middle mouse @@ -723,6 +890,8 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) localDispatch(bv, LFUN_PASTESELECTION, "paragraph"); } + if (clear) + lt = 0; } showInsetCursor(bv); no_selection = false; @@ -838,6 +1007,11 @@ InsetText::localDispatch(BufferView * bv, } } hideInsetCursor(bv); + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } switch (action) { // Normal chars case LFUN_SELFINSERT: @@ -852,128 +1026,111 @@ InsetText::localDispatch(BufferView * bv, * "auto_region_delete", which defaults to * true (on). */ - bv->text->setUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); + setUndo(bv, Undo::INSERT, + lt->cursor.par(), lt->cursor.par()->next()); bv->setState(); if (lyxrc.auto_region_delete) { - if (getLyXText(bv)->selection.set()) { - getLyXText(bv)->cutSelection(bv, false); + if (lt->selection.set()) { + lt->cutSelection(bv, false); } } - getLyXText(bv)->clearSelection(bv); + lt->clearSelection(); for (string::size_type i = 0; i < arg.length(); ++i) { - if (greek_kb_flag) { - if (!math_insert_greek(bv, arg[i])) { - bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], getLyXText(bv)); - } else if (!the_locking_inset) { - (void)moveRight(bv, false); - } - } else { - bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], getLyXText(bv)); - } + bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], lt); } } - getLyXText(bv)->selection.cursor = getLyXText(bv)->cursor; + lt->selection.cursor = lt->cursor; updateLocal(bv, CURSOR_PAR, true); result = DISPATCHED_NOUPDATE; break; // --- Cursor Movements ----------------------------------- case LFUN_RIGHTSEL: - bv->text->finishUndo(); + finishUndo(); moveRight(bv, false, true); - getLyXText(bv)->setSelection(bv); + lt->setSelection(bv); updateLocal(bv, SELECTION, false); break; case LFUN_RIGHT: result = moveRight(bv); - bv->text->finishUndo(); + finishUndo(); updateLocal(bv, CURSOR, false); break; case LFUN_LEFTSEL: - bv->text->finishUndo(); + finishUndo(); moveLeft(bv, false, true); - getLyXText(bv)->setSelection(bv); + lt->setSelection(bv); updateLocal(bv, SELECTION, false); break; case LFUN_LEFT: - bv->text->finishUndo(); + finishUndo(); result = moveLeft(bv); updateLocal(bv, CURSOR, false); break; case LFUN_DOWNSEL: - bv->text->finishUndo(); + finishUndo(); moveDown(bv); - getLyXText(bv)->setSelection(bv); + lt->setSelection(bv); updateLocal(bv, SELECTION, false); break; case LFUN_DOWN: - bv->text->finishUndo(); + finishUndo(); result = moveDown(bv); updateLocal(bv, CURSOR, false); break; case LFUN_UPSEL: - bv->text->finishUndo(); + finishUndo(); moveUp(bv); - getLyXText(bv)->setSelection(bv); + lt->setSelection(bv); updateLocal(bv, SELECTION, false); break; case LFUN_UP: - bv->text->finishUndo(); + finishUndo(); result = moveUp(bv); updateLocal(bv, CURSOR, false); break; case LFUN_HOME: - bv->text->finishUndo(); - getLyXText(bv)->cursorHome(bv); + finishUndo(); + lt->cursorHome(bv); updateLocal(bv, CURSOR, false); break; case LFUN_END: - getLyXText(bv)->cursorEnd(bv); + lt->cursorEnd(bv); updateLocal(bv, CURSOR, false); break; case LFUN_BACKSPACE: { - bv->text->setUndo(bv->buffer(), Undo::DELETE, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); - LyXText * t = getLyXText(bv); - - if (t->selection.set()) { - t->cutSelection(bv); - } else { - t->backspace(bv); - } - + setUndo(bv, Undo::DELETE, + lt->cursor.par(), lt->cursor.par()->next()); + if (lt->selection.set()) + lt->cutSelection(bv); + else + lt->backspace(bv); updateLocal(bv, CURSOR_PAR, true); } break; - case LFUN_DELETE: - { - bv->text->setUndo(bv->buffer(), Undo::DELETE, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); - LyXText * t = getLyXText(bv); - - if (t->selection.set()) { - t->cutSelection(bv); + case LFUN_DELETE: { + setUndo(bv, Undo::DELETE, + lt->cursor.par(), lt->cursor.par()->next()); + if (lt->selection.set()) { + lt->cutSelection(bv); } else { - t->Delete(bv); + lt->Delete(bv); } updateLocal(bv, CURSOR_PAR, true); } break; - case LFUN_CUT: - bv->text->setUndo(bv->buffer(), Undo::DELETE, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); - getLyXText(bv)->cutSelection(bv); + case LFUN_CUT: { + setUndo(bv, Undo::DELETE, + lt->cursor.par(), lt->cursor.par()->next()); + lt->cutSelection(bv); updateLocal(bv, CURSOR_PAR, true); - break; + } + break; + case LFUN_COPY: - bv->text->finishUndo(); - getLyXText(bv)->copySelection(bv); + finishUndo(); + lt->copySelection(bv); updateLocal(bv, CURSOR_PAR, false); break; case LFUN_PASTESELECTION: @@ -983,51 +1140,59 @@ InsetText::localDispatch(BufferView * bv, if (clip.empty()) break; if (arg == "paragraph") { - getLyXText(bv)->insertStringAsParagraphs(bv, clip); + lt->insertStringAsParagraphs(bv, clip); } else { - getLyXText(bv)->insertStringAsLines(bv, clip); + lt->insertStringAsLines(bv, clip); } updateLocal(bv, CURSOR_PAR, true); break; } - case LFUN_PASTE: + case LFUN_PASTE: { if (!autoBreakRows) { - CutAndPaste cap; - if (cap.nrOfParagraphs() > 1) { + if (CutAndPaste::nrOfParagraphs() > 1) { WriteAlert(_("Impossible operation"), _("Cannot include more than one paragraph!"), _("Sorry.")); break; } } - bv->text->setUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); - getLyXText(bv)->pasteSelection(bv); + setUndo(bv, Undo::INSERT, + lt->cursor.par(), lt->cursor.par()->next()); + lt->pasteSelection(bv); updateLocal(bv, CURSOR_PAR, true); - break; + } + break; + case LFUN_BREAKPARAGRAPH: - if (!autoBreakRows) - return DISPATCHED; - getLyXText(bv)->breakParagraph(bv, 0); + if (!autoBreakRows) { + result = DISPATCHED; + break; + } + lt->breakParagraph(bv, 0); updateLocal(bv, FULL, true); break; case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - if (!autoBreakRows) - return DISPATCHED; - getLyXText(bv)->breakParagraph(bv, 1); + if (!autoBreakRows) { + result = DISPATCHED; + break; + } + lt->breakParagraph(bv, 1); updateLocal(bv, FULL, true); break; - case LFUN_BREAKLINE: - if (!autoBreakRows) - return DISPATCHED; - bv->text->setUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); - getLyXText(bv)->insertChar(bv, Paragraph::META_NEWLINE); + + case LFUN_BREAKLINE: { + if (!autoBreakRows) { + result = DISPATCHED; + break; + } + setUndo(bv, Undo::INSERT, + lt->cursor.par(), lt->cursor.par()->next()); + lt->insertChar(bv, Paragraph::META_NEWLINE); updateLocal(bv, CURSOR_PAR, true); - break; + } + break; + case LFUN_LAYOUT: // do not set layouts on non breakable textinsets if (autoBreakRows) { @@ -1051,13 +1216,13 @@ InsetText::localDispatch(BufferView * bv, // see if we found the layout number: if (!layout.first) { string const msg = string(N_("Layout ")) + arg + N_(" not known"); - bv->owner()->getLyXFunc()->Dispatch(LFUN_MESSAGE, msg); + bv->owner()->getLyXFunc()->dispatch(LFUN_MESSAGE, msg); break; } if (cur_layout != layout.second) { cur_layout = layout.second; - getLyXText(bv)->setLayout(bv, layout.second); + lt->setLayout(bv, layout.second); bv->owner()->setLayout(cpar(bv)->getLayout()); updateLocal(bv, CURSOR_PAR, true); } @@ -1071,14 +1236,14 @@ InsetText::localDispatch(BufferView * bv, // it also seems to me that the paragraphs inside the insettext // inherit bufferparams/paragraphparams in a strange way. (Lgb) { - Paragraph * par = getLyXText(bv)->cursor.par(); + 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(); } - std::istringstream istr(arg.c_str()); + istringstream istr(arg.c_str()); string tmp; istr >> tmp; Spacing::Space new_spacing = cur_spacing; @@ -1107,9 +1272,7 @@ InsetText::localDispatch(BufferView * bv, } if (cur_spacing != new_spacing || cur_value != new_value) { par->params().spacing(Spacing(new_spacing, new_value)); - //getLyXText(bv)->RedoParagraph(owner->view()); updateLocal(bv, CURSOR_PAR, true); - //bv->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); } } break; @@ -1121,7 +1284,7 @@ InsetText::localDispatch(BufferView * bv, } /// If the action has deleted all text in the inset, we need to change the - // language to the language to the surronding text. + // language to the language of the surronding text. if (par->size() == 0 && !par->next()) { LyXFont font(LyXFont::ALL_IGNORE); font.setLanguage(bv->getParentLanguage(this)); @@ -1132,6 +1295,8 @@ InsetText::localDispatch(BufferView * bv, showInsetCursor(bv); } else bv->unlockInset(this); + if (clear) + lt = 0; return result; } @@ -1198,6 +1363,10 @@ int InsetText::beginningOfMainBody(Buffer const * buf, Paragraph * p) const void InsetText::getCursorPos(BufferView * bv, int & x, int & y) const { + if (the_locking_inset) { + the_locking_inset->getCursorPos(bv, x, y); + return; + } x = cx(bv); y = cy(bv); } @@ -1235,7 +1404,7 @@ void InsetText::toggleInsetCursor(BufferView * bv) void InsetText::showInsetCursor(BufferView * bv, bool show) { if (the_locking_inset) { - the_locking_inset->showInsetCursor(bv); + the_locking_inset->showInsetCursor(bv, show); return; } if (!isCursorVisible()) { @@ -1264,6 +1433,22 @@ void InsetText::hideInsetCursor(BufferView * bv) } +void InsetText::fitInsetCursor(BufferView * bv) const +{ + if (the_locking_inset) { + the_locking_inset->fitInsetCursor(bv); + return; + } + LyXFont const font = + getLyXText(bv)->getFont(bv->buffer(), cpar(bv), cpos(bv)); + + int const asc = lyxfont::maxAscent(font); + int const desc = lyxfont::maxDescent(font); + + bv->fitLockedInsetCursor(cx(bv), cy(bv), asc, desc); +} + + UpdatableInset::RESULT InsetText::moveRight(BufferView * bv, bool activate_inset, bool selecting) { @@ -1337,31 +1522,45 @@ InsetText::moveDown(BufferView * bv) bool InsetText::insertInset(BufferView * bv, Inset * inset) { if (the_locking_inset) { - if (the_locking_inset->insertInsetAllowed(inset)) + if (the_locking_inset->insetAllowed(inset)) return the_locking_inset->insertInset(bv, inset); return false; } - bv->text->setUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); inset->setOwner(this); hideInsetCursor(bv); - getLyXText(bv)->insertInset(bv, inset); + + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + lt->insertInset(bv, inset); #if 0 - if ((cpar(bv)->GetChar(cpos(bv)) != Paragraph::META_INSET) || - (cpar(bv)->GetInset(cpos(bv)) != inset)) - getLyXText(bv)->CursorLeft(bv); + if ((cpar(bv)->getChar(cpos(bv)) != Paragraph::META_INSET) || + (cpar(bv)->getInset(cpos(bv)) != inset)) + lt->cursorLeft(bv); #endif - bv->fitCursor(getLyXText(bv)); + bv->fitCursor(); updateLocal(bv, CURSOR_PAR|CURSOR, true); showInsetCursor(bv); + if (clear) + lt = 0; + return true; +} + + +bool InsetText::insetAllowed(Inset::Code code) const +{ + if (the_locking_inset) + return the_locking_inset->insetAllowed(code); return true; } -UpdatableInset * InsetText::getLockingInset() +UpdatableInset * InsetText::getLockingInset() const { - return the_locking_inset ? the_locking_inset->getLockingInset() : this; + return the_locking_inset ? the_locking_inset->getLockingInset() : + const_cast(this); } @@ -1408,21 +1607,30 @@ void InsetText::setFont(BufferView * bv, LyXFont const & font, bool toggleall, the_locking_inset->setFont(bv, font, toggleall, selectall); return; } - if (getLyXText(bv)->selection.set()) { - bv->text->setUndo(bv->buffer(), Undo::EDIT, - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next()); + if ((!par->next() && !par->size()) || !cpar(bv)->size()) { + getLyXText(bv)->setFont(bv, font, toggleall); + return; + } + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + if (lt->selection.set()) { + setUndo(bv, Undo::EDIT, lt->cursor.par(), lt->cursor.par()->next()); } if (selectall) selectAll(bv); - getLyXText(bv)->setFont(bv, font, toggleall); + lt->toggleFree(bv, font, toggleall); if (selectall) - getLyXText(bv)->clearSelection(bv); - bv->fitCursor(getLyXText(bv)); - if (selectall || getLyXText(bv)->selection.set()) + lt->clearSelection(); + bv->fitCursor(); + if (selectall || lt->selection.set()) updateLocal(bv, FULL, true); else updateLocal(bv, CURSOR_PAR, true); + if (clear) + lt = 0; } @@ -1493,20 +1701,11 @@ int InsetText::getMaxWidth(BufferView * bv, UpdatableInset const * inset) const } w -= (2 * TEXT_TO_INSET_OFFSET); return w - top_x; -// return w - (2*TEXT_TO_INSET_OFFSET); } void InsetText::setParagraphData(Paragraph * p) { - // delete all instances of LyXText before deleting the paragraps used - // by it. - cached_bview = 0; - for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit){ - delete (*cit).second; - (*cit).second = 0; - } - while (par) { Paragraph * tmp = par->next(); delete par; @@ -1523,8 +1722,7 @@ void InsetText::setParagraphData(Paragraph * p) np = np->next(); np->setInsetOwner(this); } - - need_update = INIT; + reinitLyXText(); } @@ -1544,6 +1742,7 @@ void InsetText::setAutoBreakRows(bool flag) need_update = FULL; if (!flag) removeNewlines(); + reinitLyXText(); } } @@ -1570,15 +1769,21 @@ void InsetText::setFrameColor(BufferView * bv, LColor::color col) int InsetText::cx(BufferView * bv) const { - LyXText * text = getLyXText(bv); - int x = text->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + int x = lt->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; if (the_locking_inset) { - LyXFont font = text->getFont(bv->buffer(), - text->cursor.par(), - text->cursor.pos()); + LyXFont font = lt->getFont(bv->buffer(), + lt->cursor.par(), + lt->cursor.pos()); if (font.isVisibleRightToLeft()) x -= the_locking_inset->width(bv, font); } + if (clear) + lt = 0; return x; } @@ -1615,39 +1820,44 @@ Row * InsetText::crow(BufferView * bv) const LyXText * InsetText::getLyXText(BufferView const * lbv, - bool const recursive) const + bool const recursive) const { if (!recursive && (cached_bview == lbv)) - return cached_text; + return cached_text.get(); // Super UGLY! (Lgb) BufferView * bv = const_cast(lbv); cached_bview = bv; Cache::iterator it = cache.find(bv); - + if (it != cache.end()) { - lyx::Assert(it->second); - - cached_text = it->second; - if (recursive && the_locking_inset) { - return the_locking_inset->getLyXText(bv); + if (lt || !it->second.remove) { + lyx::Assert(it->second.text.get()); + cached_text = it->second.text; + if (recursive && the_locking_inset) { + return the_locking_inset->getLyXText(bv, true); + } + return cached_text.get(); + } else if (it->second.remove) { + if (locked) { + saveLyXTextState(it->second.text.get()); + } else { + sstate.lpar = 0; + } } - return cached_text; } - cached_text = new LyXText(const_cast(this)); + + cached_text.reset(new LyXText(const_cast(this))); cached_text->init(bv); + restoreLyXTextState(bv, cached_text.get()); cache.insert(make_pair(bv, cached_text)); - if (the_locking_inset) { - cached_text->setCursor(bv, inset_par, inset_pos, - true, inset_boundary); - if (recursive) { - return the_locking_inset->getLyXText(bv); - } + if (the_locking_inset && recursive) { + return the_locking_inset->getLyXText(bv); } - return cached_text; + return cached_text.get(); } @@ -1661,10 +1871,9 @@ void InsetText::deleteLyXText(BufferView * bv, bool recursive) const return; } - lyx::Assert(it->second); - - delete it->second; - cache.erase(bv); + lyx::Assert(it->second.text.get()); + + it->second.remove = true; if (recursive) { /// then remove all LyXText in text-insets Paragraph * p = par; @@ -1687,74 +1896,60 @@ void InsetText::resizeLyXText(BufferView * bv, bool force) const if (it == cache.end()) { return; } - lyx::Assert(it->second); - - Paragraph * lpar = 0; - Paragraph * selstartpar = 0; - Paragraph * selendpar = 0; - Paragraph::size_type pos = 0; - Paragraph::size_type selstartpos = 0; - Paragraph::size_type selendpos = 0; - bool boundary = false; - bool selstartboundary = false; - bool selendboundary = false; - bool selection = false; - bool mark_set = false; - -// ProhibitInput(bv); - - if (locked) { - LyXText * t = getLyXText(bv); - lpar = t->cursor.par(); - pos = t->cursor.pos(); - boundary = t->cursor.boundary(); - selstartpar = t->selection.start.par(); - selstartpos = t->selection.start.pos(); - selstartboundary = t->selection.start.boundary(); - selendpar = t->selection.end.par(); - selendpos = t->selection.end.pos(); - selendboundary = t->selection.end.boundary(); - selection = t->selection.set(); - mark_set = t->selection.mark(); - } - deleteLyXText(bv, (the_locking_inset == 0) || force); - - if (lpar) { - LyXText * t = getLyXText(bv); - - t->selection.set(true); - /* at this point just to avoid the Delete-Empty-Paragraph - * Mechanism when setting the cursor */ - t->selection.mark(mark_set); - if (selection) { - t->setCursor(bv, selstartpar, selstartpos, true, selstartboundary); - t->selection.cursor = t->cursor; - t->setCursor(bv, selendpar, selendpos, true, selendboundary); - t->setSelection(bv); - t->setCursor(bv, lpar, pos); - } else { - t->setCursor(bv, lpar, pos, true, boundary); - t->selection.cursor = t->cursor; - t->selection.set(false); - } + lyx::Assert(it->second.text.get()); + + LyXText * t = it->second.text.get(); + saveLyXTextState(t); + for (Paragraph * p = par; p; p = p->next()) { + p->resizeInsetsLyXText(bv); } + t->init(bv, true); + restoreLyXTextState(bv, t); + if (the_locking_inset) { + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + } + if (bv->screen()) { - LyXText * t = getLyXText(bv); - t->first = bv->screen()->TopCursorVisible(t); + t->first = bv->screen()->topCursorVisible(t); } - + if (!owner()) + updateLocal(bv, FULL, false); + else + need_update |= FULL; // this will scroll the screen such that the cursor becomes visible bv->updateScrollbar(); -// AllowInput(bv); - if (the_locking_inset) { - /// then resize all LyXText in text-insets - inset_x = cx(bv) - top_x + drawTextXOffset; - inset_y = cy(bv) + drawTextYOffset; +} + + +void InsetText::reinitLyXText() const +{ + for(Cache::iterator it = cache.begin(); it != cache.end(); ++it) { + lyx::Assert(it->second.text.get()); + + LyXText * t = it->second.text.get(); + BufferView * bv = it->first; + + saveLyXTextState(t); for (Paragraph * p = par; p; p = p->next()) { p->resizeInsetsLyXText(bv); } + t->init(bv, true); + restoreLyXTextState(bv, t); + if (the_locking_inset) { + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + } + if (bv->screen()) { + t->first = bv->screen()->topCursorVisible(t); + } + if (!owner()) + updateLocal(bv, FULL, false); + else + need_update = FULL; + // this will scroll the screen such that the cursor becomes visible + bv->updateScrollbar(); } - need_update = FULL; } @@ -1805,13 +2000,13 @@ void InsetText::selectAll(BufferView * bv) void InsetText::clearSelection(BufferView * bv) { - getLyXText(bv)->clearSelection(bv); + getLyXText(bv)->clearSelection(); } void InsetText::clearInset(Painter & pain, int baseline, bool & cleared) const { - int w = insetWidth; + int w = insetWidth; int h = insetAscent + insetDescent; int ty = baseline - insetAscent; @@ -1823,13 +2018,228 @@ void InsetText::clearInset(Painter & pain, int baseline, bool & cleared) const h = pain.paperHeight(); if ((top_x + drawTextXOffset + w) > pain.paperWidth()) w = pain.paperWidth(); - pain.fillRectangle(top_x+drawTextXOffset, ty, w, h); +// w -= TEXT_TO_INSET_OFFSET; + pain.fillRectangle(top_x, ty, w+1, h+1, backgroundColor()); cleared = true; need_update = FULL; + frame_is_visible = false; +} + + +Paragraph * InsetText::getParFromID(int id) const +{ +#if 0 + Paragraph * result = par; + Paragraph * ires = 0; + while (result && result->id() != id) { + if ((ires = result->getParFromID(id))) + return ires; + result = result->next(); + } + return result; +#else + Paragraph * tmp = par; + while (tmp) { + int tmp_id = tmp->id(); + lyxerr << "Looking at paragraph: " << tmp_id << endl; + if (tmp->id() == id) { + return tmp; + } + Paragraph * tmp2 = tmp->getParFromID(id); + if (tmp2 != 0) { + return tmp2; + } + tmp = tmp->next(); + } + return 0; +#endif +} + + +Paragraph * InsetText::firstParagraph() const +{ + Paragraph * result; + if (the_locking_inset) + if ((result = the_locking_inset->firstParagraph())) + return result; + return par; +} + + +LyXCursor const & InsetText::cursor(BufferView * bv) const +{ + if (the_locking_inset) + return the_locking_inset->cursor(bv); + return getLyXText(bv)->cursor; +} + + +Paragraph * InsetText::paragraph() const +{ + return par; +} + + +void InsetText::paragraph(Paragraph * p) +{ + 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; + } +#endif + // redraw myself when asked for + need_update |= INIT; +} + + +Inset * InsetText::getInsetFromID(int id_arg) const +{ + if (id_arg == id()) + return const_cast(this); + + Paragraph * lp = par; + + while(lp) { + for (Paragraph::inset_iterator it = lp->inset_iterator_begin(), + en = lp->inset_iterator_end(); + it != en; ++it) + { + if ((*it)->id() == id_arg) + return *it; + Inset * in = (*it)->getInsetFromID(id_arg); + if (in) + return in; + } + lp = lp->next(); + } + return 0; +} + + +string const InsetText::selectNextWord(BufferView * bv, float & value) const +{ + bool clear = false; + string str; + + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + if (the_locking_inset) { + str = the_locking_inset->selectNextWord(bv, value); + if (!str.empty()) { + value += cy(bv); + if (clear) + lt = 0; + return str; + } +#warning Dekel please have a look on this one RTL? (Jug) + // we have to go on checking so move cusor to the right + lt->cursor.pos(lt->cursor.pos() + 1); + } + str = lt->selectNextWord(bv, value); + if (str.empty()) + bv->unlockInset(const_cast(this)); + else + value = cy(bv); + if (clear) + lt = 0; + return str; +} + + +void InsetText::selectSelectedWord(BufferView * bv) +{ + if (the_locking_inset) { + the_locking_inset->selectSelectedWord(bv); + return; + } + getLyXText(bv)->selectSelectedWord(bv); + updateLocal(bv, SELECTION, false); +} + + +void InsetText::toggleSelection(BufferView * bv, bool kill_selection) +{ + if (the_locking_inset) { + the_locking_inset->toggleSelection(bv, kill_selection); + } + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + + int x = top_x + TEXT_TO_INSET_OFFSET; + + int y = 0; + Row * row = lt->getRowNearY(y); + int y_offset = top_baseline - row->ascent_of_text(); + y = y_offset; + while ((row != 0) && ((y+row->height()) <= 0)) { + y += row->height(); + row = row->next(); + } + if (y_offset < 0) + y_offset = y; + + if (need_update & SELECTION) + need_update = NONE; + bv->screen()->toggleSelection(lt, bv, kill_selection, y_offset, x); + if (clear) + lt = 0; +} + + +bool InsetText::searchForward(BufferView * bv, string const & str, + bool const & cs, bool const & mw) +{ + if (the_locking_inset) { + if (the_locking_inset->searchForward(bv, str, cs, mw)) + return true; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + Paragraph * lpar = lt->cursor.par(); + Paragraph::size_type pos = lt->cursor.pos(); + if (pos < lpar->size() - 1) + ++pos; + else { + pos = 0; + lpar = lpar->next(); + } + if (!lpar) { + if (clear) + lt = 0; + return false; + } + lt->setCursor(bv, lpar, pos); + if (clear) + lt = 0; + } + if (LyXFind(bv, str, true, true, cs , mw)) { + return true; + } + // we have to unlock ourself in this function by default! + bv->unlockInset(const_cast(this)); + return false; +} + +bool InsetText::searchBackward(BufferView * bv, string const & str, + bool const & cs, bool const & mw) +{ + if (the_locking_inset) + if (the_locking_inset->searchBackward(bv, str, cs, mw)) + return true; + if (LyXFind(bv, str, false, true, cs, mw)) { + return true; + } + // we have to unlock ourself in this function by default! + bv->unlockInset(const_cast(this)); + return false; } -/* Emacs: - * Local variables: - * tab-width: 4 - * End: - * vi:set tabstop=4: - */