X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=c85c6be95f6b7667c69f05453e023ce78bb2e8dd;hb=4ec1fe07fed17fafde2b7cf38221c0ddbb6393a8;hp=a17efbd2aea1d2275169292c75f2f8e0a7f107f6;hpb=2c5ab94d010ed837a10eadade1a1bd6299a3d5d1;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index a17efbd2ae..c85c6be95f 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -32,7 +32,7 @@ #include "layout.h" #include "LaTeXFeatures.h" #include "Painter.h" -#include "lyx_gui_misc.h" +#include "frontends/Alert.h" #include "lyxtext.h" #include "lyxcursor.h" #include "CutAndPaste.h" @@ -40,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" @@ -50,6 +51,7 @@ #include "lyxfunc.h" #include "ParagraphParameters.h" #include "undo_funcs.h" +#include "lyxfind.h" using std::ostream; using std::ifstream; @@ -57,27 +59,43 @@ using std::endl; using std::min; using std::max; using std::make_pair; +using std::vector; + +using lyx::pos_type; 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) +// These 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(); + // check if my paragraphs are still valid + Paragraph * p = par; + while(p) { + if (p == t->cursor.par()) + break; + p = p->next(); + } + + if (p && t->cursor.pos() <= p->size()) { + 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; + } else { + sstate.lpar = 0; + } } void InsetText::restoreLyXTextState(BufferView * bv, LyXText * t) const @@ -100,6 +118,8 @@ void InsetText::restoreLyXTextState(BufferView * bv, LyXText * t) const t->selection.cursor = t->cursor; t->selection.set(false); } + if (sstate.refresh) { + } } } @@ -112,62 +132,68 @@ InsetText::InnerCache::InnerCache(boost::shared_ptr t) InsetText::InsetText() + : UpdatableInset(), lt(0), in_update(false), do_resize(0), + do_reinit(false) { par = new Paragraph; init(); } -InsetText::InsetText(InsetText const & ins, bool same_id) - : UpdatableInset() +InsetText::InsetText(InsetText const & in, bool same_id) + : UpdatableInset(in, same_id), lt(0), in_update(false), do_resize(0), + do_reinit(false) { par = 0; - init(&ins, same_id); - autoBreakRows = ins.autoBreakRows; + init(&in, same_id); } InsetText & InsetText::operator=(InsetText const & it) { init(&it); - autoBreakRows = it.autoBreakRows; return * this; } void InsetText::init(InsetText const * ins, bool same_id) { + if (ins) { + setParagraphData(ins->par); + autoBreakRows = ins->autoBreakRows; + drawFrame_ = ins->drawFrame_; + frame_color = ins->frame_color; + if (same_id) + id_ = ins->id_; + } else { + Paragraph * p = par; + while(p) { + p->setInsetOwner(this); + p = p->next(); + } + the_locking_inset = 0; + drawFrame_ = NEVER; + frame_color = LColor::insetframe; + autoBreakRows = false; + } top_y = 0; last_width = 0; last_height = 0; insetAscent = 0; insetDescent = 0; insetWidth = 0; - the_locking_inset = 0; old_max_width = 0; no_selection = false; - need_update = INIT; + need_update = FULL; drawTextXOffset = 0; drawTextYOffset = 0; - autoBreakRows = false; - drawFrame_ = NEVER; xpos = 0.0; - if (ins) { - setParagraphData(ins->par); - autoBreakRows = ins->autoBreakRows; - drawFrame_ = ins->drawFrame_; - 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; } @@ -187,24 +213,20 @@ InsetText::~InsetText() void InsetText::clear() { - cached_bview = 0; - - // now also delete all caches this should be safe, hopefully - cache.clear(); - while (par) { Paragraph * tmp = par->next(); delete par; par = tmp; } par = new Paragraph; + reinitLyXText(); + need_update = INIT; } Inset * InsetText::clone(Buffer const &, bool same_id) const { - InsetText * t = new InsetText(*this, same_id); - return t; + return new InsetText(*this, same_id); } @@ -231,13 +253,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)) { @@ -258,15 +285,20 @@ void InsetText::read(Buffer const * buf, LyXLex & lex) lex.printError("Missing \\end_inset at this point. " "Read: `$$Token'"); } - need_update = INIT; + need_update = FULL; } 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; + bool clear = false; + if (!lt) { + lt = getLyXText(bv); + clear = true; + } + insetAscent = lt->firstRow()->ascent_of_text() + TEXT_TO_INSET_OFFSET; + if (clear) + lt = 0; return insetAscent; } @@ -278,10 +310,8 @@ int InsetText::descent(BufferView * bv, LyXFont const &) const 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; + insetDescent = lt->height - lt->firstRow()->ascent_of_text() + + TEXT_TO_INSET_OFFSET; if (clear) lt = 0; return insetDescent; @@ -290,16 +320,28 @@ int InsetText::descent(BufferView * bv, LyXFont const &) const 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); } @@ -310,77 +352,85 @@ 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); + topx_set = true; + 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); + topx_set = true; 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 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); } + + top_x = int(x); + topx_set = true; 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(bv, LyXText::CHANGED_IN_DRAW); - } - top_x = int(x); - clearInset(pain, baseline, cleared); } -// 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; @@ -393,12 +443,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(); @@ -407,7 +456,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, if (y_offset < 0) y_offset = y; lt->first = first; - if (cleared) { + if (cleared || (need_update&(INIT|FULL))) { int yf = y_offset; y = 0; while ((row != 0) && (yf < ph)) { @@ -420,17 +469,17 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, } else if (!locked) { if (need_update & CURSOR) { bv->screen()->toggleSelection(lt, bv, true, y_offset,int(x)); - lt->clearSelection(bv); + lt->clearSelection(); lt->selection.cursor = lt->cursor; } bv->screen()->update(lt, bv, y_offset, int(x)); } else { locked = false; - if (need_update & SELECTION) + if (need_update & SELECTION) { bv->screen()->toggleToggle(lt, bv, y_offset, int(x)); - else if (need_update & CURSOR) { + } else if (need_update & CURSOR) { bv->screen()->toggleSelection(lt, bv, true, y_offset,int(x)); - lt->clearSelection(bv); + lt->clearSelection(); lt->selection.cursor = lt->cursor; } bv->screen()->update(lt, bv, y_offset, int(x)); @@ -440,15 +489,20 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, lt->refresh_y = 0; lt->status(bv, LyXText::UNCHANGED); if ((need_update != CURSOR_PAR) && - ((drawFrame_ == ALWAYS) || ((drawFrame_ == LOCKED) && locked))) + ((drawFrame_ == ALWAYS) || ((drawFrame_ == LOCKED) && locked))) { drawFrame(pain, cleared); - else if (need_update & CLEAR_FRAME) + } 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) { - need_update |= INIT; - } else if (need_update != INIT) + need_update |= FULL; + } else if (need_update != INIT) { need_update = NONE; + } + if (clear) lt = 0; } @@ -456,9 +510,14 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, 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; } @@ -469,9 +528,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; } @@ -480,11 +538,21 @@ void InsetText::clearFrame(Painter & pain, bool cleared) const void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) { - if (reinit) { - need_update |= INIT; - resizeLyXText(bv); + if (in_update) { + if (reinit && owner()) { + reinitLyXText(); + owner()->update(bv, font, true); + } + return; + } + 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); + in_update = false; return; } if (the_locking_inset) { @@ -498,6 +566,7 @@ 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) { @@ -505,8 +574,10 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) need_update |= FULL; if (clear) lt = 0; + in_update = false; return; } +#endif if ((need_update & CURSOR_PAR) && (lt->status() == LyXText::UNCHANGED) && the_locking_inset) { @@ -516,6 +587,7 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) need_update |= FULL; if (clear) lt = 0; + in_update = false; } @@ -527,20 +599,29 @@ void InsetText::setUpdateStatus(BufferView * bv, int what) const clear = true; } need_update |= what; - if (lt->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 (lt->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)) - lt->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 { bool clear = false; if (!lt) { @@ -549,11 +630,13 @@ void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) } lt->fullRebreak(bv); setUpdateStatus(bv, what); - if ((need_update != CURSOR) || (lt->status() != LyXText::UNCHANGED) || - lt->selection.set()) + if (((need_update != CURSOR) && (need_update != NONE)) || + (lt->status() != LyXText::UNCHANGED) || lt->selection.set()) { - bv->updateInset(this, mark_dirty); + 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()); @@ -572,7 +655,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)) { @@ -595,7 +677,53 @@ void InsetText::edit(BufferView * bv, int x, int y, unsigned int button) if (!checkAndActivateInset(bv, x, tmp_y, button)) lt->setCursorFromCoordinates(bv, x - drawTextXOffset, y + insetAscent); - lt->selection.cursor = lt->cursor; + 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); + + 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, p->size()); + } + lt->clearSelection(); finishUndo(); showInsetCursor(bv); updateLocal(bv, CURSOR, false); @@ -622,20 +750,26 @@ void InsetText::insetUnlock(BufferView * bv) hideInsetCursor(bv); no_selection = false; locked = false; - int code = CURSOR|CLEAR_FRAME; + 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(bv); + lt->clearSelection(); code = FULL; } else if (owner()) { bv->owner()->setLayout(owner()->getLyXText(bv) ->cursor.par()->getLayout()); } else bv->owner()->setLayout(bv->text->cursor.par()->getLayout()); + // hack for deleteEmptyParMech + lt->setCursor(bv, par, 0); updateLocal(bv, code, false); if (clear) lt = 0; @@ -706,7 +840,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) { @@ -749,7 +882,7 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) the_locking_inset = 0; } if (bv->theLockingInset()) { - if (inset && inset->editable() == Inset::HIGHLY_EDITABLE) { + if (isHighlyEditableInset(inset)) { UpdatableInset * uinset = static_cast(inset); inset_x = cx(bv) - top_x + drawTextXOffset; inset_y = cy(bv) + drawTextYOffset; @@ -758,7 +891,7 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) inset_boundary = cboundary(bv); the_locking_inset = uinset; uinset->insetButtonPress(bv, x - inset_x, y - inset_y, - button); + button); uinset->edit(bv, x - inset_x, y - inset_y, 0); if (the_locking_inset) updateLocal(bv, CURSOR, false); @@ -772,10 +905,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 @@ -786,8 +927,10 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) localDispatch(bv, LFUN_PASTE, ""); else localDispatch(bv, LFUN_PASTESELECTION, - "paragraph"); + "paragraph"); } + if (clear) + lt = 0; } showInsetCursor(bv); no_selection = false; @@ -803,9 +946,9 @@ void InsetText::insetButtonRelease(BufferView * bv, int x, int y, int button) x - inset_x, y - inset_y, button); } else { - if (cpar(bv)->getChar(cpos(bv)) == Paragraph::META_INSET) { + if (cpar(bv)->isInset(cpos(bv))) { inset = static_cast(cpar(bv)->getInset(cpos(bv))); - if (inset->editable() == Inset::HIGHLY_EDITABLE) { + if (isHighlyEditableInset(inset)) { inset->insetButtonRelease(bv, x - inset_x, y - inset_y, button); @@ -858,6 +1001,7 @@ UpdatableInset::RESULT InsetText::localDispatch(BufferView * bv, kb_action action, string const & arg) { + bool was_empty = par->size() == 0 && !par->next(); no_selection = false; UpdatableInset::RESULT result= UpdatableInset::localDispatch(bv, action, arg); @@ -876,30 +1020,33 @@ InsetText::localDispatch(BufferView * bv, else if (result == DISPATCHED) { updateLocal(bv, CURSOR_PAR, false); return result; - } else if (result == FINISHED) { - bool dispatched = false; - switch (action) { - case LFUN_UNKNOWN_ACTION: - case LFUN_BREAKPARAGRAPH: - case LFUN_BREAKLINE: + } else if (result >= FINISHED) { + switch(result) { + case FINISHED_RIGHT: moveRightIntern(bv, false, false); + result = DISPATCHED; break; - case LFUN_RIGHT: - if (!getLyXText(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) - moveRightIntern(bv, false, false); - dispatched = true; + case FINISHED_UP: + if ((result = moveUp(bv)) >= FINISHED) { + updateLocal(bv, CURSOR, false); + bv->unlockInset(this); + } break; - case LFUN_LEFT: - if (getLyXText(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) - moveRightIntern(bv, false, false); - dispatched = true; + case FINISHED_DOWN: + if ((result = moveDown(bv)) >= FINISHED) { + updateLocal(bv, CURSOR, false); + bv->unlockInset(this); + } break; default: + result = DISPATCHED; break; } the_locking_inset = 0; - if (dispatched) - return DISPATCHED; +#ifdef WITH_WARNINGS +#warning I changed this to always return Dispatched maybe it is wrong (20011001 Jug) +#endif + return result; } } hideInsetCursor(bv); @@ -930,17 +1077,9 @@ InsetText::localDispatch(BufferView * bv, lt->cutSelection(bv, false); } } - lt->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], lt); - } else if (!the_locking_inset) { - (void)moveRight(bv, false); - } - } else { - bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], lt); - } + bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], lt); } } lt->selection.cursor = lt->cursor; @@ -1055,7 +1194,7 @@ InsetText::localDispatch(BufferView * bv, if (!autoBreakRows) { if (CutAndPaste::nrOfParagraphs() > 1) { - WriteAlert(_("Impossible operation"), + Alert::alert(_("Impossible operation"), _("Cannot include more than one paragraph!"), _("Sorry.")); break; @@ -1189,13 +1328,13 @@ InsetText::localDispatch(BufferView * bv, /// If the action has deleted all text in the inset, we need to change the // language to the language of the surronding text. - if (par->size() == 0 && !par->next()) { + if (!was_empty && par->size() == 0 && !par->next()) { LyXFont font(LyXFont::ALL_IGNORE); font.setLanguage(bv->getParentLanguage(this)); setFont(bv, font, false); } - if (result != FINISHED) { + if (result < FINISHED) { showInsetCursor(bv); } else bv->unlockInset(this); @@ -1228,16 +1367,187 @@ int InsetText::ascii(Buffer const * buf, ostream & os, int linelen) const } -int InsetText::docBook(Buffer const * buf, ostream & os) const +int InsetText::docbook(Buffer const * buf, ostream & os) const { Paragraph * p = par; unsigned int lines = 0; - int desc = 0; + + vector environment_stack(10); + vector environment_inner(10); + + int const command_depth = 0; + string item_name; - string tmp; + Paragraph::depth_type depth = 0; // paragraph depth + while (p) { - buf->simpleDocBookOnePar(os, tmp, p, desc, 0); + string sgmlparam; + int desc_on = 0; // description mode + + LyXLayout const & style = + textclasslist.Style(buf->params.textclass, + p->layout); + + // environment tag closing + for (; depth > p->params().depth(); --depth) { + if (environment_inner[depth] != "!-- --") { + item_name = "listitem"; + buf->sgmlCloseTag(os, command_depth + depth, + item_name); + if (environment_inner[depth] == "varlistentry") + buf->sgmlCloseTag(os, depth+command_depth, + environment_inner[depth]); + } + buf->sgmlCloseTag(os, depth + command_depth, + environment_stack[depth]); + environment_stack[depth].erase(); + environment_inner[depth].erase(); + } + + if (depth == p->params().depth() + && environment_stack[depth] != style.latexname() + && !environment_stack[depth].empty()) { + if (environment_inner[depth] != "!-- --") { + item_name= "listitem"; + buf->sgmlCloseTag(os, command_depth+depth, + item_name); + if (environment_inner[depth] == "varlistentry") + buf->sgmlCloseTag(os, + depth + command_depth, + environment_inner[depth]); + } + + buf->sgmlCloseTag(os, depth + command_depth, + environment_stack[depth]); + + environment_stack[depth].erase(); + environment_inner[depth].erase(); + } + + // Write opening SGML tags. + switch (style.latextype) { + case LATEX_PARAGRAPH: + buf->sgmlOpenTag(os, depth + command_depth, + style.latexname()); + break; + + case LATEX_COMMAND: + buf->sgmlError(p, 0, + _("Error : LatexType Command not allowed here.\n")); + return -1; + break; + + case LATEX_ENVIRONMENT: + case LATEX_ITEM_ENVIRONMENT: + if (depth < p->params().depth()) { + depth = p->params().depth(); + environment_stack[depth].erase(); + } + + if (environment_stack[depth] != style.latexname()) { + if(environment_stack.size() == depth + 1) { + environment_stack.push_back("!-- --"); + environment_inner.push_back("!-- --"); + } + environment_stack[depth] = style.latexname(); + environment_inner[depth] = "!-- --"; + buf->sgmlOpenTag(os, depth + command_depth, + environment_stack[depth]); + } else { + if (environment_inner[depth] != "!-- --") { + item_name= "listitem"; + buf->sgmlCloseTag(os, + command_depth + depth, + item_name); + if (environment_inner[depth] == "varlistentry") + buf->sgmlCloseTag(os, + depth + command_depth, + environment_inner[depth]); + } + } + + if (style.latextype == LATEX_ENVIRONMENT) { + if (!style.latexparam().empty()) { + if(style.latexparam() == "CDATA") + os << "sgmlOpenTag(os, depth + command_depth, + style.latexparam()); + } + break; + } + + desc_on = (style.labeltype == LABEL_MANUAL); + + if (desc_on) + environment_inner[depth]= "varlistentry"; + else + environment_inner[depth]= "listitem"; + + buf->sgmlOpenTag(os, depth + 1 + command_depth, + environment_inner[depth]); + + if (desc_on) { + item_name= "term"; + buf->sgmlOpenTag(os, depth + 1 + command_depth, + item_name); + } else { + item_name= "para"; + buf->sgmlOpenTag(os, depth + 1 + command_depth, + item_name); + } + break; + default: + buf->sgmlOpenTag(os, depth + command_depth, + style.latexname()); + break; + } + + buf->simpleDocBookOnePar(os, p, desc_on, + depth + 1 + command_depth); p = p->next(); + + string end_tag; + // write closing SGML tags + switch (style.latextype) { + case LATEX_ENVIRONMENT: + if (!style.latexparam().empty()) { + if(style.latexparam() == "CDATA") + os << "]]>"; + else + buf->sgmlCloseTag(os, depth + command_depth, + style.latexparam()); + } + break; + case LATEX_ITEM_ENVIRONMENT: + if (desc_on == 1) break; + end_tag= "para"; + buf->sgmlCloseTag(os, depth + 1 + command_depth, end_tag); + break; + case LATEX_PARAGRAPH: + buf->sgmlCloseTag(os, depth + command_depth, style.latexname()); + break; + default: + buf->sgmlCloseTag(os, depth + command_depth, style.latexname()); + break; + } + } + + // Close open tags + for (int d = depth; d >= 0; --d) { + if (!environment_stack[depth].empty()) { + if (environment_inner[depth] != "!-- --") { + item_name = "listitem"; + buf->sgmlCloseTag(os, command_depth + depth, + item_name); + if (environment_inner[depth] == "varlistentry") + buf->sgmlCloseTag(os, depth + command_depth, + environment_inner[depth]); + } + + buf->sgmlCloseTag(os, depth + command_depth, + environment_stack[depth]); + } } return lines; @@ -1308,7 +1618,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()) { @@ -1337,6 +1647,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) { @@ -1359,10 +1685,10 @@ InsetText::moveLeft(BufferView * bv, bool activate_inset, bool selecting) UpdatableInset::RESULT InsetText::moveRightIntern(BufferView * bv, bool behind, - bool activate_inset, bool selecting) + bool activate_inset, bool selecting) { if (!cpar(bv)->next() && (cpos(bv) >= cpar(bv)->size())) - return FINISHED; + return FINISHED_RIGHT; if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; getLyXText(bv)->cursorRight(bv); @@ -1374,7 +1700,7 @@ InsetText::moveRightIntern(BufferView * bv, bool behind, UpdatableInset::RESULT InsetText::moveLeftIntern(BufferView * bv, bool behind, - bool activate_inset, bool selecting) + bool activate_inset, bool selecting) { if (!cpar(bv)->previous() && (cpos(bv) <= 0)) return FINISHED; @@ -1391,7 +1717,7 @@ UpdatableInset::RESULT InsetText::moveUp(BufferView * bv) { if (!crow(bv)->previous()) - return FINISHED; + return FINISHED_UP; getLyXText(bv)->cursorUp(bv); return DISPATCHED_NOUPDATE; } @@ -1401,7 +1727,7 @@ UpdatableInset::RESULT InsetText::moveDown(BufferView * bv) { if (!crow(bv)->next()) - return FINISHED; + return FINISHED_DOWN; getLyXText(bv)->cursorDown(bv); return DISPATCHED_NOUPDATE; } @@ -1410,7 +1736,7 @@ 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; } @@ -1423,10 +1749,12 @@ bool InsetText::insertInset(BufferView * bv, Inset * inset) clear = true; } lt->insertInset(bv, inset); - if ((cpar(bv)->getChar(cpos(bv)) != Paragraph::META_INSET) || +#if 0 + if ((!cpar(bv)->isInset(cpos(bv))) || (cpar(bv)->getInset(cpos(bv)) != inset)) lt->cursorLeft(bv); - bv->fitCursor(lt); +#endif + bv->fitCursor(); updateLocal(bv, CURSOR_PAR|CURSOR, true); showInsetCursor(bv); if (clear) @@ -1435,17 +1763,10 @@ bool InsetText::insertInset(BufferView * bv, Inset * inset) } -bool InsetText::insertInsetAllowed(Inset * in) const -{ - if (the_locking_inset) - return the_locking_inset->insertInsetAllowed(in); - return true; -} - -bool InsetText::insertInsetAllowed(Inset::Code code) const +bool InsetText::insetAllowed(Inset::Code code) const { if (the_locking_inset) - return the_locking_inset->insertInsetAllowed(code); + return the_locking_inset->insetAllowed(code); return true; } @@ -1500,6 +1821,10 @@ void InsetText::setFont(BufferView * bv, LyXFont const & font, bool toggleall, the_locking_inset->setFont(bv, font, toggleall, selectall); return; } + if ((!par->next() && !par->size()) || !cpar(bv)->size()) { + getLyXText(bv)->setFont(bv, font, toggleall); + return; + } bool clear = false; if (!lt) { lt = getLyXText(bv); @@ -1510,14 +1835,10 @@ void InsetText::setFont(BufferView * bv, LyXFont const & font, bool toggleall, } if (selectall) selectAll(bv); -#if 1 lt->toggleFree(bv, font, toggleall); -#else - lt->setFont(bv, font, toggleall); -#endif if (selectall) - lt->clearSelection(bv); - bv->fitCursor(lt); + lt->clearSelection(); + bv->fitCursor(); if (selectall || lt->selection.set()) updateLocal(bv, FULL, true); else @@ -1529,12 +1850,12 @@ void InsetText::setFont(BufferView * bv, LyXFont const & font, bool toggleall, bool InsetText::checkAndActivateInset(BufferView * bv, bool behind) { - if (cpar(bv)->getChar(cpos(bv)) == Paragraph::META_INSET) { + if (cpar(bv)->isInset(cpos(bv))) { unsigned int x; unsigned int y; Inset * inset = static_cast(cpar(bv)->getInset(cpos(bv))); - if (!inset || inset->editable() != Inset::HIGHLY_EDITABLE) + if (!isHighlyEditableInset(inset)) return false; LyXFont const font = getLyXText(bv)->getFont(bv->buffer(), cpar(bv), cpos(bv)); @@ -1584,9 +1905,10 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, int InsetText::getMaxWidth(BufferView * bv, UpdatableInset const * inset) const { +#if 0 int w = UpdatableInset::getMaxWidth(bv, inset); if (w < 0) { - return w; + return -1; } if (owner()) { w = w - top_x + owner()->x(); @@ -1594,34 +1916,33 @@ 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); +#else + return UpdatableInset::getMaxWidth(bv, inset); +#endif } void InsetText::setParagraphData(Paragraph * p) { - cached_bview = 0; - - // now also delete all caches this should be safe, hopefully - cache.clear(); - + // we have to unlock any locked inset otherwise we're in troubles + the_locking_inset = 0; while (par) { Paragraph * tmp = par->next(); delete par; par = tmp; } - par = new Paragraph(*p); + par = new Paragraph(*p, false); par->setInsetOwner(this); Paragraph * np = par; while (p->next()) { p = p->next(); - np->next(new Paragraph(*p)); + np->next(new Paragraph(*p, false)); np->next()->previous(np); np = np->next(); np->setInsetOwner(this); } - + reinitLyXText(); need_update = INIT; } @@ -1639,9 +1960,9 @@ void InsetText::setAutoBreakRows(bool flag) { if (flag != autoBreakRows) { autoBreakRows = flag; - need_update = FULL; if (!flag) removeNewlines(); + need_update = INIT; } } @@ -1694,7 +2015,7 @@ int InsetText::cy(BufferView * bv) const } -Paragraph::size_type InsetText::cpos(BufferView * bv) const +pos_type InsetText::cpos(BufferView * bv) const { return getLyXText(bv)->cursor.pos(); } @@ -1719,35 +2040,41 @@ 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)) + 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); cached_bview = bv; Cache::iterator it = cache.find(bv); - - if (it != cache.end() && (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); - } - return cached_text.get(); - } else if (it->second.remove) { - if (locked) { - saveLyXTextState(it->second.text.get()); - } else { - sstate.lpar = 0; + + if (it != cache.end()) { + if (do_reinit) + reinitLyXText(); + else if (do_resize) + resizeLyXText(do_resize); + 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; + } } - cache.erase(bv); -// raise(SIGSTOP); } - + cached_text.reset(new LyXText(const_cast(this))); cached_text->init(bv); restoreLyXTextState(bv, cached_text.get()); @@ -1786,6 +2113,14 @@ void InsetText::deleteLyXText(BufferView * bv, bool recursive) const void InsetText::resizeLyXText(BufferView * bv, bool force) const { + if (lt) { + // we cannot resize this because we are in use! + // so do this on the next possible getLyXText() + do_resize = bv; + return; + } + do_resize = 0; +// lyxerr << "InsetText::resizeLyXText\n"; if (!par->next() && !par->size()) // no data, resize not neccessary! return; // one endless line, resize normally not necessary @@ -1798,24 +2133,69 @@ void InsetText::resizeLyXText(BufferView * bv, bool force) const } lyx::Assert(it->second.text.get()); - deleteLyXText(bv, (the_locking_inset == 0) || force); - - if (bv->screen()) { - LyXText * t = getLyXText(bv); - t->first = bv->screen()->topCursorVisible(t); + LyXText * t = it->second.text.get(); + saveLyXTextState(t); + for (Paragraph * p = par; p; p = p->next()) { + p->resizeInsetsLyXText(bv); } - - // this will scroll the screen such that the cursor becomes visible - bv->updateScrollbar(); + t->init(bv, true); + restoreLyXTextState(bv, t); if (the_locking_inset) { - /// then resize all LyXText in text-insets 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); + // this will scroll the screen such that the cursor becomes visible + bv->updateScrollbar(); + } else { + need_update |= FULL; + } +} + + +void InsetText::reinitLyXText() const +{ + if (lt) { + // we cannot resize this because we are in use! + // so do this on the next possible getLyXText() + do_reinit = true; + return; + } + do_reinit = false; + do_resize = 0; +// lyxerr << "InsetText::reinitLyXText\n"; + 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); + // this will scroll the screen such that the cursor becomes visible + bv->updateScrollbar(); + } else { + need_update = FULL; + } } - need_update = FULL; } @@ -1866,13 +2246,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; @@ -1884,14 +2264,17 @@ 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) { @@ -1900,6 +2283,22 @@ Paragraph * InsetText::getParFromID(int id) const 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 } @@ -1913,6 +2312,12 @@ Paragraph * InsetText::firstParagraph() const } +Paragraph * InsetText::getFirstParagraph(int i) const +{ + return (i == 0) ? par : 0; +} + + LyXCursor const & InsetText::cursor(BufferView * bv) const { if (the_locking_inset) @@ -1930,15 +2335,9 @@ Paragraph * InsetText::paragraph() const 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 + reinitLyXText(); // redraw myself when asked for - need_update |= INIT; + need_update = INIT; } @@ -1966,7 +2365,7 @@ Inset * InsetText::getInsetFromID(int id_arg) const } -string InsetText::selectNextWord(BufferView * bv, float & value) const +string const InsetText::selectNextWordToSpellcheck(BufferView * bv, float & value) const { bool clear = false; string str; @@ -1976,7 +2375,7 @@ string InsetText::selectNextWord(BufferView * bv, float & value) const clear = true; } if (the_locking_inset) { - str = the_locking_inset->selectNextWord(bv, value); + str = the_locking_inset->selectNextWordToSpellcheck(bv, value); if (!str.empty()) { value += cy(bv); if (clear) @@ -1984,10 +2383,11 @@ string InsetText::selectNextWord(BufferView * bv, float & value) const return str; } #warning Dekel please have a look on this one RTL? (Jug) +#warning DEKEL! // we have to go on checking so move cusor to the right lt->cursor.pos(lt->cursor.pos() + 1); } - str = lt->selectNextWord(bv, value); + str = lt->selectNextWordToSpellcheck(bv, value); if (str.empty()) bv->unlockInset(const_cast(this)); else @@ -2022,10 +2422,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(); @@ -2033,7 +2432,70 @@ void InsetText::toggleSelection(BufferView * bv, bool kill_selection) 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(); + pos_type pos = lt->cursor.pos(); + if (pos < lpar->size() - 1) + ++pos; + else { + pos = 0; + lpar = lpar->next(); + } + if (!lpar) { + if (clear) + lt = 0; + // we have to unlock ourself in this function by default! + bv->unlockInset(const_cast(this)); + 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; +} + + +bool InsetText::checkInsertChar(LyXFont & font) +{ + if (owner()) + return owner()->checkInsertChar(font); + return true; +}