X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=833eb64c621b705b31d4007e9b76d99bc5ebb9a1;hb=b14052f6a5823878733a72f6d8e565cedd5f8c96;hp=b69c8c6fd363783098ccf74353338cbacc7e50e3;hpb=6bba977f42b0cde753ac2ffd26f3f9c6b32ba0b6;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index b69c8c6fd3..833eb64c62 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -38,11 +38,15 @@ #include "CutAndPaste.h" #include "font.h" #include "minibuffer.h" -#include "toolbar.h" #include "LColor.h" #include "support/textutils.h" #include "support/LAssert.h" #include "lyxrow.h" +#include "lyxrc.h" +#include "intl.h" +#include "trans_mgr.h" +#include "lyxscreen.h" +#include "WorkArea.h" using std::ostream; using std::ifstream; @@ -51,23 +55,21 @@ using std::min; using std::max; extern unsigned char getCurrentTextClass(Buffer *); -#warning BAAAAAAAADDDDDDD current_view (but Lars wanted it :) !!! -extern BufferView * current_view; - +extern bool math_insert_greek(BufferView *, char); +extern int greek_kb_flag; InsetText::InsetText() { par = new LyXParagraph(); init(); - text = new LyXText(this); } -InsetText::InsetText(InsetText const & ins) : UpdatableInset() +InsetText::InsetText(InsetText const & ins) + : UpdatableInset() { par = 0; init(&ins); - text = new LyXText(this); autoBreakRows = ins.autoBreakRows; } @@ -75,44 +77,100 @@ InsetText::InsetText(InsetText const & ins) : UpdatableInset() InsetText & InsetText::operator=(InsetText const & it) { init(&it); - text = new LyXText(this); autoBreakRows = it.autoBreakRows; return * this; } + void InsetText::init(InsetText const * ins) { + top_y = 0; + last_width = 0; + last_height = 0; + insetAscent = 0; + insetDescent = 0; + insetWidth = 0; the_locking_inset = 0; cursor_visible = false; - cursor.x_fix(-1); interline_space = 1; no_selection = false; - init_inset = true; - maxAscent = maxDescent = insetWidth = 0; - drawTextXOffset = drawTextYOffset = 0; - autoBreakRows = drawLockedFrame = false; + need_update = INIT; + drawTextXOffset = 0; + drawTextYOffset = 0; + autoBreakRows = false; + drawFrame = NEVER; xpos = 0.0; if (ins) { SetParagraphData(ins->par); autoBreakRows = ins->autoBreakRows; - drawLockedFrame = ins->drawLockedFrame; + drawFrame = ins->drawFrame; } par->SetInsetOwner(this); - cursor.par(par); - cursor.pos(0); - selection_start_cursor = selection_end_cursor = cursor; frame_color = LColor::insetframe; locked = false; + old_par = 0; + last_drawn_width = -1; } InsetText::~InsetText() { + // delete all instances of LyXText before deleting the paragraps used + // by it. + for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit){ + delete (*cit).second; + (*cit).second = 0; + } +#ifndef NEW_INSETS + LyXParagraph * p = par->next_; delete par; + while(p) { + par = p; + p = p->next_; + delete par; + } +#else + LyXParagraph * p = par->next(); + delete par; + while(p) { + par = p; + p = p->next(); + delete par; + } +#endif } -Inset * InsetText::Clone() const +void InsetText::clear() +{ + // delete all instances of LyXText before deleting the paragraps used + // by it. + for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit){ + delete (*cit).second; + (*cit).second = 0; + } +#ifndef NEW_INSETS + LyXParagraph * p = par->next_; + delete par; + while(p) { + par = p; + p = p->next_; + delete par; + } +#else + LyXParagraph * p = par->next(); + delete par; + while(p) { + par = p; + p = p->next(); + delete par; + } +#endif + par = new LyXParagraph(); +} + + +Inset * InsetText::Clone(Buffer const &) const { InsetText * t = new InsetText(*this); return t; @@ -134,18 +192,41 @@ void InsetText::WriteParagraphData(Buffer const * buf, ostream & os) const void InsetText::Read(Buffer const * buf, LyXLex & lex) { - string token, tmptok; + string token; int pos = 0; LyXParagraph * return_par = 0; char depth = 0; // signed or unsigned? +#ifndef NEW_INSETS LyXParagraph::footnote_flag footnoteflag = LyXParagraph::NO_FOOTNOTE; LyXParagraph::footnote_kind footnotekind = LyXParagraph::FOOTNOTE; +#endif LyXFont font(LyXFont::ALL_INHERIT); + // delete all instances of LyXText before deleting the paragraps used + // by it. + for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit){ + delete (*cit).second; + (*cit).second = 0; + } + +#ifndef NEW_INSETS + LyXParagraph * p = par->next_; delete par; + while(p) { + par = p; + p = p->next_; + delete par; + } +#else + LyXParagraph * p = par->next(); + delete par; + while(p) { + par = p; + p = p->next(); + delete par; + } +#endif par = new LyXParagraph; - par->SetInsetOwner(this); - while (lex.IsOK()) { lex.nextToken(); token = lex.GetString(); @@ -153,210 +234,299 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex) continue; if (token == "\\end_inset") break; - if (const_cast(buf)->parseSingleLyXformat2Token(lex, par, return_par, - token, pos, depth, - font, footnoteflag, - footnotekind)) { + if (const_cast(buf)-> + parseSingleLyXformat2Token(lex, par, return_par,token, pos, depth, + font +#ifndef NEW_INSETS + , footnoteflag, footnotekind +#endif + )) + { // the_end read this should NEVER happen lex.printError("\\the_end read in inset! Error in document!"); return; } } + if (!return_par) + return_par = par; + par = return_par; + while(return_par) { + return_par->SetInsetOwner(this); +#ifndef NEW_INSETS + return_par = return_par->next_; +#else + return_par = return_par->next(); +#endif + } + if (token != "\\end_inset") { lex.printError("Missing \\end_inset at this point. " "Read: `$$Token'"); } - init_inset = true; + need_update = INIT; } -int InsetText::ascent(Painter & pain, LyXFont const & font) const +int InsetText::ascent(BufferView * bv, LyXFont const &) const { - if (init_inset) { - text->init(current_view); - computeTextRows(pain); - init_inset = false; - } - long int y_temp = 0; - Row * row = text->GetRowNearY(y_temp); - return row->ascent_of_text(); + int y_temp = 0; + Row * row = TEXT(bv)->GetRowNearY(y_temp); + insetAscent = row->ascent_of_text() + TEXT_TO_INSET_OFFSET; + return insetAscent; } -int InsetText::descent(Painter & pain, LyXFont const & font) const +int InsetText::descent(BufferView * bv, LyXFont const &) const { - if (init_inset) { - text->init(current_view); - computeTextRows(pain); - init_inset = false; - } - long int y = 0; - Row * row = text->GetRowNearY(y); - return text->height - row->ascent_of_text(); + int y_temp = 0; + Row * row = TEXT(bv)->GetRowNearY(y_temp); + insetDescent = TEXT(bv)->height - row->ascent_of_text() + + TEXT_TO_INSET_OFFSET; + return insetDescent; } -int InsetText::width(Painter & pain, LyXFont const &) const +int InsetText::width(BufferView * bv, LyXFont const &) const { - if (init_inset) { - text->init(current_view); - computeTextRows(pain); - init_inset = false; - } - return text->width; -// return insetWidth; + insetWidth = max(textWidth(bv->painter()), + (int)TEXT(bv)->width + (2 * TEXT_TO_INSET_OFFSET)); + return insetWidth; } -void InsetText::draw(Painter & pain, LyXFont const & f, - int baseline, float & x) const +int InsetText::textWidth(Painter & pain) const { - xpos = x; - UpdatableInset::draw(pain, f, baseline, x); - - if (init_inset) { - text->init(current_view); - computeTextRows(pain); - init_inset = false; + int const w = getMaxWidth(pain, this); + return w; +} + + +void InsetText::draw(BufferView * bv, LyXFont const & f, + int baseline, float & x, bool cleared) const +{ + Painter & pain = bv->painter(); + + // no draw is necessary !!! + if ((drawFrame == LOCKED) && !locked && !par->size()) { + if (!cleared && (need_update & CLEAR_FRAME)) { + pain.rectangle(top_x + 1, baseline - insetAscent + 1, + width(bv, f) - 1, + insetAscent + insetDescent - 1, + LColor::background); } - if ((baseline != top_baseline) || (top_x != int(x))) { + top_x = int(x); top_baseline = baseline; + x += width(bv, f); + need_update = NONE; + return; + } + + xpos = x; + UpdatableInset::draw(bv, f, baseline, x, cleared); + + // update insetWidth and insetHeight with dummy calls + (void)ascent(bv, f); + (void)descent(bv, f); + (void)width(bv, f); + + // if top_x differs we have a rule down and we don't have to clear anything + if (!cleared && (top_x == int(x)) && + ((need_update==INIT)||(need_update==FULL)||(top_baseline!=baseline)|| + (last_drawn_width!=insetWidth))) + { + int w = insetWidth; + int h = insetAscent + insetDescent; + int ty = baseline - insetAscent; + + if (ty < 0) { + h += ty; + ty = 0; + } + if ((ty + h) > pain.paperHeight()) + h = pain.paperHeight(); + if ((top_x + drawTextXOffset + w) > pain.paperWidth()) + w = pain.paperWidth(); + pain.fillRectangle(top_x+drawTextXOffset, ty, w, h); + cleared = true; + need_update = FULL; + } + if (!cleared && (need_update == NONE)) + return; + + if (top_x != int(x)) { + need_update = INIT; top_x = int(x); - computeBaselines(baseline); + bv->text->status = LyXText::CHANGED_IN_DRAW; + return; } - if (the_locking_inset && (text->cursor.pos() == inset_pos)) { - resetPos(pain); - inset_x = text->cursor.x() - top_x + drawTextXOffset; - inset_y = text->cursor.y() + drawTextYOffset; + if (cleared || (last_drawn_width != insetWidth)) { + need_update |= FULL; + last_drawn_width = insetWidth; } - if (drawLockedFrame && locked) { - pain.rectangle(int(x), baseline - ascent(pain, f), insetWidth, - ascent(pain,f) + descent(pain, f), frame_color); + + 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; } - x += TEXT_TO_INSET_OFFSET; // place for border -#if 1 - long int y = 0; - Row * row = text->GetRowNearY(y); - y += baseline - row->ascent_of_text(); - text->width = 0; - while (row != 0) { - text->GetVisibleRow(current_view, y, top_x, row, y); - y += row->height(); - row = row->next(); + if (!cleared && (need_update == CURSOR) && !TEXT(bv)->selection) { + x += width(bv, f); + need_update = NONE; + return; } -#else - for(RowList::size_type r = 0; r < rows.size() - 1; ++r) { - drawRowSelection(pain, rows[r].pos, rows[r + 1].pos, r, - rows[r].baseline, x); - drawRowText(pain, rows[r].pos, rows[r + 1].pos, rows[r].baseline, x); + x += TEXT_TO_INSET_OFFSET; + { + int y = 0; + Row * row = TEXT(bv)->GetRowNearY(y); + int y_offset = baseline - row->ascent_of_text(); + int ph = pain.paperHeight(); + int first = 0; + y = y_offset; + while ((row != 0) && ((y+row->height()) <= 0)) { + y += row->height(); + first += row->height(); + row = row->next(); + } + if (y_offset < 0) + y_offset = y; + TEXT(bv)->first = first; + if (cleared) { // (need_update&FULL) || (need_update&INIT) + int yf = y_offset; + y = 0; + while ((row != 0) && (yf < ph)) { + TEXT(bv)->GetVisibleRow(bv, y+y_offset, int(x), row, + y+first, cleared); + y += row->height(); + yf += row->height(); + row = row->next(); + } + } else if (!locked) { + if (need_update & CURSOR) { + bv->screen()->ToggleSelection(TEXT(bv), bv, true, y_offset,int(x)); + TEXT(bv)->ClearSelection(bv); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + } + bv->screen()->Update(TEXT(bv), bv, y_offset, int(x)); + } else { + locked = false; + if (need_update & SELECTION) + bv->screen()->ToggleToggle(TEXT(bv), bv, y_offset, int(x)); + else if (need_update & CURSOR) { + bv->screen()->ToggleSelection(TEXT(bv), bv, true, y_offset,int(x)); + TEXT(bv)->ClearSelection(bv); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + } + bv->screen()->Update(TEXT(bv), bv, y_offset, int(x)); + locked = true; + } } -#endif - x += insetWidth - TEXT_TO_INSET_OFFSET; + TEXT(bv)->refresh_y = 0; + TEXT(bv)->status = LyXText::UNCHANGED; + if ((need_update != CURSOR_PAR) && + ((drawFrame == ALWAYS) || ((drawFrame == LOCKED) && locked))) + { + pain.rectangle(top_x + 1, baseline - insetAscent + 1, + width(bv, f) - 1, insetAscent + insetDescent - 1, + frame_color); + } else if (need_update & CLEAR_FRAME) { + pain.rectangle(top_x + 1, baseline - insetAscent + 1, + width(bv, f) - 1, insetAscent + insetDescent - 1, + LColor::background); + } + x += 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 = NONE; } -void InsetText::drawRowSelection(Painter & pain, int startpos, int endpos, - int row, int baseline, float x) const +void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) { - if (!hasSelection()) + if (reinit) { // && (need_update != CURSOR)) { + need_update = INIT; + resizeLyXText(bv); + if (owner()) + owner()->update(bv, font, true); return; - - int s_start, s_end; - if (selection_start_cursor.pos() > selection_end_cursor.pos()) { - s_start = selection_end_cursor.pos(); - s_end = selection_start_cursor.pos(); - } else { - s_start = selection_start_cursor.pos(); - s_end = selection_end_cursor.pos(); } - if ((s_start > endpos) || (s_end < startpos)) + if (the_locking_inset) { + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + the_locking_inset->update(bv, font, reinit); + } + if (need_update == INIT) { + resizeLyXText(bv); + need_update = FULL; + } + int oldw = insetWidth; +#if 1 + insetWidth = TEXT(bv)->width + (2 * TEXT_TO_INSET_OFFSET); + // max(textWidth(bv->painter()), + // static_cast(TEXT(bv)->width) + drawTextXOffset) + + // (2 * TEXT_TO_INSET_OFFSET); +#else + insetWidth = textWidth(bv->painter()); + if (insetWidth < 0) + insetWidth = static_cast(TEXT(bv)->width); +#endif + if (oldw != insetWidth) { +// printf("TW(%p): %d-%d-%d-%d\n",this,insetWidth, oldw, +// textWidth(bv->painter()),static_cast(TEXT(bv)->width)); + resizeLyXText(bv); + need_update = FULL; + update(bv, font, reinit); return; - - int esel_x; - int ssel_x = esel_x = int(x); - LyXFont font; - int p = startpos; - for(; p < endpos; ++p) { - if (p == s_start) - ssel_x = int(x); - if ((p >= s_start) && (p <= s_end)) - esel_x = int(x); - char ch = par->GetChar(p); - font = GetDrawFont(current_view->buffer(), par, p); - if (IsFloatChar(ch)) { - // skip for now - } else if (ch == LyXParagraph::META_INSET) { - Inset const * tmpinset = par->GetInset(p); - x += tmpinset->width(pain, font); - } else { - x += lyxfont::width(ch, font); - } } - if (p == s_start) - ssel_x = int(x); - if ((p >= s_start) && (p <= s_end)) - esel_x = int(x); - if (ssel_x < esel_x) { - pain.fillRectangle(int(ssel_x), baseline-rows[row].asc, - int(esel_x - ssel_x), - rows[row].asc + rows[row].desc, - LColor::selection); - } -} - - -void InsetText::drawRowText(Painter & pain, int startpos, int endpos, - int baseline, float x) const -{ - Assert(endpos <= par->Last()); - - for(int p = startpos; p < endpos; ++p) { - char ch = par->GetChar(p); - LyXFont font = GetDrawFont(current_view->buffer(), par, p); - if (IsFloatChar(ch)) { - // skip for now - } else if (par->IsNewline(p)) { - // Draw end-of-line marker - int wid = lyxfont::width('n', font); - int asc = lyxfont::maxAscent(font); - int y = baseline; - int xp[3], yp[3]; - - xp[0] = int(x + wid * 0.375); - yp[0] = int(y - 0.875 * asc * 0.75); - - xp[1] = int(x); - yp[1] = int(y - 0.500 * asc * 0.75); - - xp[2] = int(x + wid * 0.375); - yp[2] = int(y - 0.125 * asc * 0.75); - - pain.lines(xp, yp, 3, LColor::eolmarker); - - xp[0] = int(x); - yp[0] = int(y - 0.500 * asc * 0.75); - - xp[1] = int(x + wid); - yp[1] = int(y - 0.500 * asc * 0.75); - - xp[2] = int(x + wid); - yp[2] = int(y - asc * 0.75); - - pain.lines(xp, yp, 3, LColor::eolmarker); - x += wid; - } else if (ch == LyXParagraph::META_INSET) { - Inset * tmpinset = par->GetInset(p); - if (tmpinset) - tmpinset->draw(pain, font, baseline, x); - } else { - pain.text(int(x), baseline, ch, font); - x += lyxfont::width(ch, font); - } + if ((need_update==CURSOR_PAR) && (TEXT(bv)->status==LyXText::UNCHANGED) && + the_locking_inset) + { + TEXT(bv)->UpdateInset(bv, the_locking_inset); + } + + if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH) + need_update = FULL; + + int y_temp = 0; + Row * row = TEXT(bv)->GetRowNearY(y_temp); + insetAscent = row->ascent_of_text() + TEXT_TO_INSET_OFFSET; + insetDescent = TEXT(bv)->height - row->ascent_of_text() + + TEXT_TO_INSET_OFFSET; +} + +void InsetText::SetUpdateStatus(BufferView * bv, int what) +{ + need_update |= what; + if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH) + need_update |= FULL; + else if (TEXT(bv)->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)) + TEXT(bv)->ClearSelection(bv); +} + +void InsetText::UpdateLocal(BufferView * bv, int what, bool mark_dirty) +{ + TEXT(bv)->FullRebreak(bv); + SetUpdateStatus(bv, what); + if ((need_update != CURSOR) || (TEXT(bv)->status != LyXText::UNCHANGED) || + TEXT(bv)->selection) + bv->updateInset(this, mark_dirty); + bv->owner()->showState(); + if (old_par != cpar(bv)) { + bv->owner()->setLayout(cpar(bv)->GetLayout()); + old_par = cpar(bv); } } -char const * InsetText::EditMessage() const +string const InsetText::EditMessage() const { return _("Opened Text Inset"); } @@ -364,7 +534,7 @@ char const * InsetText::EditMessage() const void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button) { - par->SetInsetOwner(this); +// par->SetInsetOwner(this); UpdatableInset::Edit(bv, x, y, button); if (!bv->lockInset(this)) { @@ -374,12 +544,28 @@ void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button) locked = true; the_locking_inset = 0; inset_pos = inset_x = inset_y = 0; - setPos(bv->painter(), x, y); - checkAndActivateInset(bv, x, y, button); - selection_start_cursor = selection_end_cursor = cursor; - current_font = real_current_font =GetFont(bv->buffer(), par, cursor.pos()); + inset_boundary = false; + inset_par = 0; + old_par = 0; + if (!checkAndActivateInset(bv, x, y, button)) + TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, + y+insetAscent); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; bv->text->FinishUndo(); - UpdateLocal(bv, true); + ShowInsetCursor(bv); + UpdateLocal(bv, FULL, false); + + // If the inset is empty set the language of the current font to the + // language to the surronding text. +#ifndef NEW_INSETS + if (par->Last() == 0 && !par->next_) { +#else + if (par->size() == 0 && !par->next()) { +#endif + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + SetFont(bv, font, false); + } } @@ -390,12 +576,14 @@ void InsetText::InsetUnlock(BufferView * bv) the_locking_inset = 0; } HideInsetCursor(bv); - lyxerr[Debug::INSETS] << "InsetText::InsetUnlock(" << this << - ")" << endl; - selection_start_cursor = selection_end_cursor = cursor; no_selection = false; locked = false; - UpdateLocal(bv, true); + UpdateLocal(bv, CLEAR_FRAME|CURSOR, false); + if (owner()) + bv->owner()->setLayout(owner()->getLyXText(bv) + ->cursor.par()->GetLayout()); + else + bv->owner()->setLayout(bv->text->cursor.par()->GetLayout()); } @@ -404,20 +592,27 @@ bool InsetText::LockInsetInInset(BufferView * bv, UpdatableInset * inset) lyxerr[Debug::INSETS] << "InsetText::LockInsetInInset(" << inset << "): "; if (!inset) return false; - if (inset == par->GetInset(text->cursor.pos())) { + if (inset == cpar(bv)->GetInset(cpos(bv))) { lyxerr[Debug::INSETS] << "OK" << endl; the_locking_inset = inset; - resetPos(bv->painter()); - inset_x = text->cursor.x() - top_x + drawTextXOffset; - inset_y = text->cursor.y() + drawTextYOffset; - inset_pos = text->cursor.pos(); + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + inset_pos = cpos(bv); + inset_par = cpar(bv); + inset_boundary = cboundary(bv); +#if 0 + TEXT(bv)->ClearSelection(bv); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + TEXT(bv)->UpdateInset(bv, the_locking_inset); +#else + UpdateLocal(bv, CURSOR, false); +#endif return true; } else if (the_locking_inset && (the_locking_inset == inset)) { - if (text->cursor.pos() == inset_pos) { + if (cpar(bv) == inset_par && cpos(bv) == inset_pos) { lyxerr[Debug::INSETS] << "OK" << endl; - resetPos(bv->painter()); - inset_x = text->cursor.x() - top_x + drawTextXOffset; - inset_y = text->cursor.y() + drawTextYOffset; + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; } else { lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl; } @@ -437,9 +632,12 @@ bool InsetText::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset, return false; if (the_locking_inset == inset) { the_locking_inset->InsetUnlock(bv); + TEXT(bv)->UpdateInset(bv, inset); the_locking_inset = 0; if (lr) moveRight(bv, false); + old_par = 0; // force layout setting + UpdateLocal(bv, CURSOR_PAR, false); return true; } return the_locking_inset->UnlockInsetInInset(bv, inset, lr); @@ -450,14 +648,17 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset) { if (!the_locking_inset) return false; - if (the_locking_inset != inset) + if (the_locking_inset != inset) { + TEXT(bv)->UpdateInset(bv, the_locking_inset); + SetUpdateStatus(bv, CURSOR_PAR); return the_locking_inset->UpdateInsetInInset(bv, inset); - lyxerr[Debug::INSETS] << "InsetText::UpdateInsetInInset(" << inset << - ")" << endl; - UpdateLocal(bv, true); - if (text->cursor.pos() == inset_pos) { - inset_x = text->cursor.x() - top_x + drawTextXOffset; - inset_y = text->cursor.y() + drawTextYOffset; + } +// UpdateLocal(bv, FULL, false); + if (TEXT(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; } return true; } @@ -465,48 +666,76 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset) void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) { - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } - no_selection = false; - setPos(bv->painter(), x, y); - cursor.x_fix(-1); + no_selection = true; + + int tmp_x = x - drawTextXOffset; + int tmp_y = y + insetAscent - TEXT(bv)->first; + Inset * inset = bv->checkInsetHit(TEXT(bv), tmp_x, tmp_y, button); + + HideInsetCursor(bv); if (the_locking_inset) { - UpdatableInset * inset = 0; - if (par->GetChar(cursor.pos()) == LyXParagraph::META_INSET) - inset = static_cast(par->GetInset(cursor.pos())); if (the_locking_inset == inset) { the_locking_inset->InsetButtonPress(bv,x-inset_x,y-inset_y,button); + no_selection = false; return; } else if (inset) { // otherwise unlock the_locking_inset and lock the new inset the_locking_inset->InsetUnlock(bv); - inset_x = cursor.x() - top_x + drawTextXOffset; - inset_y = cursor.y() + drawTextYOffset; + 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->Edit(bv, x - inset_x, y - inset_y, button); - UpdateLocal(bv, true); + if (the_locking_inset) + UpdateLocal(bv, CURSOR, false); + no_selection = false; return; } // otherwise only unlock the_locking_inset the_locking_inset->InsetUnlock(bv); the_locking_inset = 0; } - if (bv->the_locking_inset) { - if ((par->GetChar(cursor.pos()) == LyXParagraph::META_INSET) && - par->GetInset(cursor.pos()) && - (par->GetInset(cursor.pos())->Editable() == Inset::HIGHLY_EDITABLE)) { - UpdatableInset * inset = - static_cast(par->GetInset(cursor.pos())); - inset_x = cursor.x() - top_x + drawTextXOffset; - inset_y = cursor.y() + drawTextYOffset; - inset->InsetButtonPress(bv, x - inset_x, y - inset_y, button); - inset->Edit(bv, x - inset_x, y - inset_y, 0); - UpdateLocal(bv, true); + if (bv->theLockingInset()) { + if (inset && inset->Editable() == Inset::HIGHLY_EDITABLE) { + UpdatableInset * uinset = static_cast(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); + the_locking_inset = uinset; + uinset->InsetButtonPress(bv, x - inset_x, y - inset_y, button); + uinset->Edit(bv, x - inset_x, y - inset_y, 0); + if (the_locking_inset) + UpdateLocal(bv, CURSOR, false); + no_selection = false; + return; + } + } + if (!inset && (button == 2)) { + bool paste_internally = false; + if ((button == 2) && TEXT(bv)->selection) { + LocalDispatch(bv, LFUN_COPY, ""); + paste_internally = true; + } + TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, + y + insetAscent); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + UpdateLocal(bv, CURSOR, false); + bv->owner()->setLayout(cpar(bv)->GetLayout()); + old_par = cpar(bv); + // Insert primary selection with middle mouse + // if there is a local selection in the current buffer, + // insert this + if (button == 2) { + if (paste_internally) + LocalDispatch(bv, LFUN_PASTE, ""); + else + LocalDispatch(bv, LFUN_PASTESELECTION, "paragraph"); } } - selection_start_cursor = selection_end_cursor = cursor; + ShowInsetCursor(bv); + no_selection = false; } @@ -515,18 +744,21 @@ void 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); + the_locking_inset->InsetButtonRelease(bv, + x - inset_x, y - inset_y, + button); } else { - if (par->GetChar(cursor.pos()) == LyXParagraph::META_INSET) { - inset = static_cast(par->GetInset(cursor.pos())); + if (cpar(bv)->GetChar(cpos(bv)) == LyXParagraph::META_INSET) { + inset = static_cast(cpar(bv)->GetInset(cpos(bv))); if (inset->Editable() == Inset::HIGHLY_EDITABLE) { inset->InsetButtonRelease(bv, x - inset_x, y - inset_y,button); } else { - inset_x = cursor.x() - top_x + drawTextXOffset; - inset_y = cursor.y() + drawTextYOffset; + 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); } } no_selection = false; @@ -535,21 +767,21 @@ void InsetText::InsetButtonRelease(BufferView * bv, int x, int y, int button) void InsetText::InsetMotionNotify(BufferView * bv, int x, int y, int state) { + if (no_selection) + return; if (the_locking_inset) { the_locking_inset->InsetMotionNotify(bv, x - inset_x, y - inset_y,state); return; } - if (!no_selection) { - LyXCursor old = selection_end_cursor; - HideInsetCursor(bv); - setPos(bv->painter(), x, y); - selection_end_cursor = cursor; - if (old != selection_end_cursor) - UpdateLocal(bv, false); - ShowInsetCursor(bv); - } - no_selection = false; + HideInsetCursor(bv); + TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, + y+insetAscent); + TEXT(bv)->SetSelection(bv); + if (TEXT(bv)->toggle_cursor.par()!=TEXT(bv)->toggle_end_cursor.par() || + TEXT(bv)->toggle_cursor.pos()!=TEXT(bv)->toggle_end_cursor.pos()) + UpdateLocal(bv, SELECTION, false); + ShowInsetCursor(bv); } @@ -564,13 +796,12 @@ void InsetText::InsetKeyPress(XKeyEvent * xke) UpdatableInset::RESULT InsetText::LocalDispatch(BufferView * bv, - int action, string const & arg) + kb_action action, string const & arg) { no_selection = false; UpdatableInset::RESULT result= UpdatableInset::LocalDispatch(bv, action, arg); if (result != UNDISPATCHED) { - resetPos(bv->painter()); return DISPATCHED; } @@ -578,271 +809,359 @@ InsetText::LocalDispatch(BufferView * bv, if ((action < 0) && arg.empty()) return FINISHED; - if ((action != LFUN_DOWN) && (action != LFUN_UP) && - (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL)) - cursor.x_fix(-1); if (the_locking_inset) { result = the_locking_inset->LocalDispatch(bv, action, arg); if (result == DISPATCHED_NOUPDATE) return result; else if (result == DISPATCHED) { - the_locking_inset->ToggleInsetCursor(bv); - UpdateLocal(bv, false); - the_locking_inset->ToggleInsetCursor(bv); + UpdateLocal(bv, CURSOR_PAR, false); return result; } else if (result == FINISHED) { - switch(action) { - case -1: + bool dispatched = false; + switch (action) { + case LFUN_UNKNOWN_ACTION: + case LFUN_BREAKPARAGRAPH: + case LFUN_BREAKLINE: + moveRightIntern(bv, false, false); + break; case LFUN_RIGHT: - cursor.pos(inset_pos + 1); - resetPos(bv->painter()); + if (!TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + moveRightIntern(bv, false, false); + dispatched = true; + break; + case LFUN_LEFT: + if (TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + moveRightIntern(bv, false, false); + dispatched = true; break; - case LFUN_DOWN: - moveDown(bv); + default: break; } the_locking_inset = 0; - return DISPATCHED; + if (dispatched) + return DISPATCHED; } } HideInsetCursor(bv); switch (action) { // Normal chars - case -1: - bv->text->SetUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - cutSelection(bv->buffer()); - cursor = selection_start_cursor; - par->InsertChar(cursor.pos(), arg[0]); - SetCharFont(bv->buffer(), cursor.pos(), current_font); - cursor.pos(cursor.pos() + 1); - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, true); + case LFUN_UNKNOWN_ACTION: + if (bv->buffer()->isReadonly()) { +// setErrorMessage(N_("Document is read only")); + break; + } + if (!arg.empty()) { + /* Automatically delete the currently selected + * text and replace it with what is being + * typed in now. Depends on lyxrc settings + * "auto_region_delete", which defaults to + * true (on). */ + + bv->text->SetUndo(bv->buffer(), Undo::INSERT, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + bv->setState(); + if (lyxrc.auto_region_delete) { + if (TEXT(bv)->selection){ + TEXT(bv)->CutSelection(bv, false); + } + } + TEXT(bv)->ClearSelection(bv); + 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], TEXT(bv)); + } else if (!the_locking_inset) { + (void)moveRight(bv, false); + } + } else { + bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], TEXT(bv)); + } + } + } + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + UpdateLocal(bv, CURSOR_PAR, true); + result=DISPATCHED_NOUPDATE; break; // --- Cursor Movements --------------------------------------------- case LFUN_RIGHTSEL: bv->text->FinishUndo(); - moveRight(bv, false); - selection_end_cursor = cursor; - UpdateLocal(bv, false); + moveRight(bv, false, true); + TEXT(bv)->SetSelection(bv); + UpdateLocal(bv, SELECTION, false); break; case LFUN_RIGHT: - bv->text->FinishUndo(); result = moveRight(bv); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } else { - selection_start_cursor = selection_end_cursor = cursor; - } + bv->text->FinishUndo(); + UpdateLocal(bv, CURSOR, false); break; case LFUN_LEFTSEL: bv->text->FinishUndo(); - moveLeft(bv, false); - selection_end_cursor = cursor; - UpdateLocal(bv, false); + moveLeft(bv, false, true); + TEXT(bv)->SetSelection(bv); + UpdateLocal(bv, SELECTION, false); break; case LFUN_LEFT: bv->text->FinishUndo(); - result= moveLeft(bv); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } else { - selection_start_cursor = selection_end_cursor = cursor; - } + result = moveLeft(bv); + UpdateLocal(bv, CURSOR, false); break; case LFUN_DOWNSEL: bv->text->FinishUndo(); moveDown(bv); - selection_end_cursor = cursor; - UpdateLocal(bv, false); + TEXT(bv)->SetSelection(bv); + UpdateLocal(bv, SELECTION, false); break; case LFUN_DOWN: bv->text->FinishUndo(); result = moveDown(bv); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } else { - selection_start_cursor = selection_end_cursor = cursor; - } + UpdateLocal(bv, CURSOR, false); break; case LFUN_UPSEL: bv->text->FinishUndo(); moveUp(bv); - selection_end_cursor = cursor; - UpdateLocal(bv, false); + TEXT(bv)->SetSelection(bv); + UpdateLocal(bv, SELECTION, false); break; case LFUN_UP: bv->text->FinishUndo(); result = moveUp(bv); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } else { - selection_start_cursor = selection_end_cursor = cursor; - } + UpdateLocal(bv, CURSOR, false); + break; + case LFUN_HOME: + bv->text->FinishUndo(); + TEXT(bv)->CursorHome(bv); + UpdateLocal(bv, CURSOR, false); + break; + case LFUN_END: + TEXT(bv)->CursorEnd(bv); + UpdateLocal(bv, CURSOR, false); break; case LFUN_BACKSPACE: - if (!cursor.pos()) { - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } - break; - } - moveLeft(bv); + bv->text->SetUndo(bv->buffer(), Undo::DELETE, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + if (TEXT(bv)->selection) + TEXT(bv)->CutSelection(bv); + else + TEXT(bv)->Backspace(bv); + UpdateLocal(bv, CURSOR_PAR, true); + break; case LFUN_DELETE: - { - bv->text->SetUndo(bv->buffer(), Undo::DELETE, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - bool ret = true; - if (hasSelection()) { - LyXParagraph::size_type i = selection_start_cursor.pos(); - for (; i < selection_end_cursor.pos(); ++i) { - par->Erase(selection_start_cursor.pos()); - } - } else - ret = Delete(); - if (ret) { // we need update - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, true); - } else if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } - } - resetPos(bv->painter()); - break; + bv->text->SetUndo(bv->buffer(), Undo::DELETE, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + if (TEXT(bv)->selection) + TEXT(bv)->CutSelection(bv); + else + TEXT(bv)->Delete(bv); + UpdateLocal(bv, CURSOR_PAR, true); + break; case LFUN_CUT: - bv->text->SetUndo(bv->buffer(), Undo::DELETE, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - - if (cutSelection(bv->buffer())) { - // we need update - cursor = selection_end_cursor = selection_start_cursor; - UpdateLocal(bv, true); - } else if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } - resetPos(bv->painter()); + bv->text->SetUndo(bv->buffer(), Undo::DELETE, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + TEXT(bv)->CutSelection(bv); + UpdateLocal(bv, CURSOR_PAR, true); break; case LFUN_COPY: bv->text->FinishUndo(); - if (copySelection(bv->buffer())) { - // we need update - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, true); - } else if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } + TEXT(bv)->CopySelection(bv); + UpdateLocal(bv, CURSOR_PAR, false); break; - case LFUN_PASTE: + case LFUN_PASTESELECTION: { - bv->text->SetUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - if (pasteSelection(bv->buffer())) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, true); - } - } - resetPos(bv->painter()); - break; - case LFUN_HOME: - bv->text->FinishUndo(); - for(; cursor.pos() > rows[actrow].pos;) { - cursor.x(cursor.x() - SingleWidth(bv->painter(), par, cursor.pos())); - cursor.pos(cursor.pos() - 1); - } + string clip(bv->workarea()->getClipboard()); - cursor.x(cursor.x() - SingleWidth(bv->painter(), par, cursor.pos())); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); + if (clip.empty()) + break; + if (arg == "paragraph") { + TEXT(bv)->InsertStringB(bv, clip); } else { - selection_start_cursor = selection_end_cursor = cursor; + TEXT(bv)->InsertStringA(bv, clip); } - resetPos(bv->painter()); + UpdateLocal(bv, CURSOR_PAR, true); break; - case LFUN_END: - { - bv->text->FinishUndo(); - int checkpos = (int)rows[actrow + 1].pos; - if ((actrow + 2) < (int)rows.size()) - --checkpos; - for(; cursor.pos() < checkpos;) { - cursor.x(cursor.x() + SingleWidth(bv->painter(), par, cursor.pos())); - cursor.pos(cursor.pos() + 1); - } - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } else { - selection_start_cursor = selection_end_cursor = cursor; - } } - resetPos(bv->painter()); - break; + case LFUN_PASTE: + if (!autoBreakRows) { + CutAndPaste cap; + + if (cap.nrOfParagraphs() > 1) { + WriteAlert(_("Impossible operation"), + _("Cannot include more than one paragraph!"), + _("Sorry.")); + break; + } + } + bv->text->SetUndo(bv->buffer(), Undo::INSERT, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + TEXT(bv)->PasteSelection(bv); + UpdateLocal(bv, CURSOR_PAR, true); + break; case LFUN_BREAKPARAGRAPH: + if (!autoBreakRows) + return DISPATCHED; + TEXT(bv)->BreakParagraph(bv, 0); + UpdateLocal(bv, FULL, true); + break; + case LFUN_BREAKPARAGRAPHKEEPLAYOUT: + if (!autoBreakRows) + return DISPATCHED; + TEXT(bv)->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()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - par->InsertChar(cursor.pos(),LyXParagraph::META_NEWLINE); - SetCharFont(bv->buffer(), cursor.pos(),current_font); - UpdateLocal(bv, true); - cursor.pos(cursor.pos() + 1); - selection_start_cursor = selection_end_cursor = cursor; - resetPos(bv->painter()); + bv->text->SetUndo(bv->buffer(), Undo::INSERT, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + TEXT(bv)->InsertChar(bv, LyXParagraph::META_NEWLINE); + UpdateLocal(bv, CURSOR_PAR, true); break; case LFUN_LAYOUT: - { - static LyXTextClass::size_type cur_layout = par->layout; + // do not set layouts on non breakable textinsets + if (autoBreakRows) { + LyXTextClass::size_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 = - textclasslist.NumberOfLayout(tclass, arg); - - // If the entry is obsolete, use the new one instead. - if (layout.first) { - string obs = textclasslist.Style(tclass,layout.second). - obsoleted_by(); - if (!obs.empty()) - layout = textclasslist.NumberOfLayout(tclass, obs); - } + // 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 = + textclasslist.NumberOfLayout(tclass, arg); + + // If the entry is obsolete, use the new one instead. + if (layout.first) { + string obs = textclasslist.Style(tclass,layout.second). + obsoleted_by(); + if (!obs.empty()) + layout = textclasslist.NumberOfLayout(tclass, obs); + } - // see if we found the layout number: - if (!layout.first) { - string msg = string(N_("Layout ")) + arg + N_(" not known"); + // see if we found the layout number: + if (!layout.first) { + string msg = string(N_("Layout ")) + arg + N_(" not known"); - bv->owner()->getMiniBuffer()->Set(msg); - break; - } + bv->owner()->getMiniBuffer()->Set(msg); + break; + } - if (cur_layout != layout.second) { - cur_layout = layout.second; - text->SetLayout(bv, layout.second); - bv->owner()->getToolbar()->combox->select(cursor.par()->GetLayout()+1); - UpdateLocal(bv, true); + if (cur_layout != layout.second) { + cur_layout = layout.second; + TEXT(bv)->SetLayout(bv, layout.second); + bv->owner()->setLayout(cpar(bv)->GetLayout()); + UpdateLocal(bv, CURSOR_PAR, true); + } + } else { + // reset the layout box + bv->owner()->setLayout(cpar(bv)->GetLayout()); } + break; + case LFUN_PARAGRAPH_SPACING: + // This one is absolutely not working. When fiddling with this + // it also seems to me that the paragraphs inside the insettext + // inherit bufferparams/paragraphparams in a strange way. (Lgb) + { + LyXParagraph * par = TEXT(bv)->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()); + string tmp; + istr >> tmp; + Spacing::Space new_spacing = cur_spacing; + float new_value = cur_value; + if (tmp.empty()) { + lyxerr << "Missing argument to `paragraph-spacing'" + << endl; + } else if (tmp == "single") { + new_spacing = Spacing::Single; + } else if (tmp == "onehalf") { + new_spacing = Spacing::Onehalf; + } else if (tmp == "double") { + new_spacing = Spacing::Double; + } else if (tmp == "other") { + new_spacing = Spacing::Other; + float tmpval = 0.0; + istr >> tmpval; + lyxerr << "new_value = " << tmpval << endl; + if (tmpval != 0.0) + new_value = tmpval; + } else if (tmp == "default") { + new_spacing = Spacing::Default; + } else { + lyxerr << _("Unknown spacing argument: ") + << arg << endl; + } + if (cur_spacing != new_spacing || cur_value != new_value) { + par->params.spacing(Spacing(new_spacing, new_value)); + //TEXT(bv)->RedoParagraph(owner->view()); + UpdateLocal(bv, CURSOR_PAR, true); + //bv->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); + } } break; + default: - result = UNDISPATCHED; + if (!bv->Dispatch(action, arg)) + result = UNDISPATCHED; break; } + + /// If the action has deleted all text in the inset, we need to change the + // language to the language to the surronding text. +#ifndef NEW_INSETS + if (par->Last() == 0 && !par->next_) { +#else + if (par->size() == 0 && !par->next()) { +#endif + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + SetFont(bv, font, false); + } + if (result != FINISHED) { ShowInsetCursor(bv); } else @@ -859,135 +1178,57 @@ int InsetText::Latex(Buffer const * buf, ostream & os, bool, bool) const } -void InsetText::Validate(LaTeXFeatures & features) const +int InsetText::Ascii(Buffer const * buf, ostream & os, int linelen) const { - par->validate(features); -} - - -// Returns the width of a character at a certain spot -int InsetText::SingleWidth(Painter & pain, LyXParagraph * p, int pos) const -{ - LyXFont font = GetDrawFont(current_view->buffer(), p, pos); - char c = p->GetChar(pos); - - if (IsPrintable(c)) { - return lyxfont::width(c, font); - } else if (c == LyXParagraph::META_INSET) { - Inset const * tmpinset = p->GetInset(pos); - if (tmpinset) - return tmpinset->width(pain, font); - else - return 0; - } else if (IsSeparatorChar(c)) - c = ' '; - else if (IsNewlineChar(c)) - c = 'n'; - return lyxfont::width(c, font); + LyXParagraph * p = par; + unsigned int lines = 0; + + string tmp; + while (p) { + tmp = buf->asciiParagraph(p, linelen); + lines += countChar(tmp, '\n'); + os << tmp; +#ifndef NEW_INSETS + p = p->next(); +#else + p = p->next(); +#endif + } + return lines; } -// Returns the width of a character at a certain spot -void InsetText::SingleHeight(Painter & pain, LyXParagraph * p,int pos, - int & asc, int & desc) const +int InsetText::DocBook(Buffer const * buf, ostream & os) const { - LyXFont font = GetDrawFont(current_view->buffer(), p, pos); - char c = p->GetChar(pos); - - asc = desc = 0; - if (c == LyXParagraph::META_INSET) { - Inset const * tmpinset=p->GetInset(pos); - if (tmpinset) { - asc = tmpinset->ascent(pain, font); - desc = tmpinset->descent(pain, font); - } - } else { - asc = lyxfont::maxAscent(font); - desc = lyxfont::maxDescent(font); - } - return; -} - - -// Gets the fully instantiated font at a given position in a paragraph -// Basically the same routine as LyXParagraph::getFont() in paragraph.C. -// The difference is that this one is used for displaying, and thus we -// are allowed to make cosmetic improvements. For instance make footnotes -// smaller. (Asger) -// If position is -1, we get the layout font of the paragraph. -// If position is -2, we get the font of the manual label of the paragraph. -LyXFont InsetText::GetFont(Buffer const * buf, LyXParagraph * p, int pos) const -{ - char par_depth = p->GetDepth(); - - LyXLayout const & layout = - textclasslist.Style(buf->params.textclass, p->GetLayout()); - - // We specialize the 95% common case: - if (p->footnoteflag == LyXParagraph::NO_FOOTNOTE && !par_depth) { - if (pos >= 0) { - // 95% goes here - if (layout.labeltype == LABEL_MANUAL - && pos < BeginningOfMainBody(buf, p)) { - // 1% goes here - return p->GetFontSettings(buf->params, - pos).realize(layout.reslabelfont); - } else - return p->GetFontSettings(buf->params, - pos).realize(layout.resfont); - } else { - // 5% goes here. - // process layoutfont for pos == -1 and labelfont for pos < -1 - if (pos == -1) - return layout.resfont; - else - return layout.reslabelfont; - } - } - // The uncommon case need not be optimized as much - - LyXFont layoutfont, tmpfont; - - if (pos >= 0){ - // 95% goes here - if (pos < BeginningOfMainBody(buf, p)) { - // 1% goes here - layoutfont = layout.labelfont; - } else { - // 99% goes here - layoutfont = layout.font; - } - tmpfont = p->GetFontSettings(buf->params, pos); - tmpfont.realize(layoutfont); - } else{ - // 5% goes here. - // process layoutfont for pos == -1 and labelfont for pos < -1 - if (pos == -1) - tmpfont = layout.font; - else - tmpfont = layout.labelfont; - } + LyXParagraph * p = par; + unsigned int lines = 0; + int desc=0; - // Resolve against environment font information - //if (par->GetDepth()){ // already in while condition - while (p && par_depth && !tmpfont.resolved()) { - p = p->DepthHook(par_depth - 1); - if (p) { - tmpfont.realize(textclasslist.Style(buf->params.textclass, - p->GetLayout()).font); - par_depth = p->GetDepth(); - } + string tmp; + while (p) { + buf->SimpleDocBookOnePar(os,tmp,p,desc,0); +#ifndef NEW_INSETS + p = p->next_; +#else + p = p->next(); +#endif } - tmpfont.realize((textclasslist.TextClass(buf->params.textclass). - defaultfont())); - return tmpfont; + + return lines; } -// the font for drawing may be different from the real font -LyXFont InsetText::GetDrawFont(Buffer const * buf, LyXParagraph * p, int pos) const +void InsetText::Validate(LaTeXFeatures & features) const { - return GetFont(buf, p, pos); + LyXParagraph * p = par; + while(p) { + p->validate(features); +#ifndef NEW_INSETS + p = p->next_; +#else + p = p->next(); +#endif + } } @@ -1001,14 +1242,15 @@ int InsetText::BeginningOfMainBody(Buffer const * buf, LyXParagraph * p) const } -void InsetText::GetCursorPos(int & x, int & y) const +void InsetText::GetCursorPos(BufferView * bv, + int & x, int & y) const { - x = cursor.x(); - y = cursor.y(); + x = cx(bv); + y = cy(bv); } -int InsetText::InsetInInsetY() +unsigned int InsetText::InsetInInsetY() { if (!the_locking_inset) return 0; @@ -1024,37 +1266,34 @@ void InsetText::ToggleInsetCursor(BufferView * bv) return; } - LyXFont font = GetDrawFont(bv->buffer(), par, text->cursor.pos()); + LyXFont font = TEXT(bv)->GetFont(bv->buffer(), cpar(bv), cpos(bv)); int asc = lyxfont::maxAscent(font); int desc = lyxfont::maxDescent(font); - asc = text->cursor.row()->ascent_of_text(); - desc = text->cursor.row()->height() - asc; if (cursor_visible) bv->hideLockedInsetCursor(); else - bv->showLockedInsetCursor(text->cursor.x(), text->cursor.y(), - asc, desc); + bv->showLockedInsetCursor(cx(bv), cy(bv), asc, desc); cursor_visible = !cursor_visible; } -void InsetText::ShowInsetCursor(BufferView * bv) +void InsetText::ShowInsetCursor(BufferView * bv, bool show) { if (the_locking_inset) { the_locking_inset->ShowInsetCursor(bv); return; } if (!cursor_visible) { - LyXFont font = GetDrawFont(bv->buffer(), par, cursor.pos()); + LyXFont font = TEXT(bv)->GetFont(bv->buffer(), cpar(bv), cpos(bv)); int asc = lyxfont::maxAscent(font); int desc = lyxfont::maxDescent(font); - asc = text->cursor.row()->ascent_of_text(); - desc = text->cursor.row()->height() - asc; - bv->fitLockedInsetCursor(text->cursor.x(), text->cursor.y(), asc, desc); - bv->showLockedInsetCursor(text->cursor.x(), text->cursor.y(), asc, desc); + + bv->fitLockedInsetCursor(cx(bv), cy(bv), asc, desc); + if (show) + bv->showLockedInsetCursor(cx(bv), cy(bv), asc, desc); cursor_visible = true; } } @@ -1071,95 +1310,59 @@ void InsetText::HideInsetCursor(BufferView * bv) } -void InsetText::setPos(Painter & pain, int x, int y) const +UpdatableInset::RESULT +InsetText::moveRight(BufferView * bv, bool activate_inset, bool selecting) { - x -= drawTextXOffset; - y -= drawTextYOffset; - // search right X-pos x==0 -> top_x - cursor.pos(0); - actrow = 0; - cursor.y(top_baseline); - y += cursor.y(); - for(unsigned int i = 1; - (long(cursor.y() + rows[i - 1].desc) < y) - && (i < rows.size() - 1); ++i) { - cursor.y(rows[i].baseline); - cursor.pos(rows[i].pos); - actrow = i; - } - cursor.y(cursor.y() - top_baseline); - cursor.x(top_x + 2); // 2 = frame width - x += cursor.x(); - - int swh; - int sw = swh = SingleWidth(pain, par, cursor.pos()); - if (par->GetChar(cursor.pos()) != LyXParagraph::META_INSET) - swh /= 2; - int checkpos = rows[actrow + 1].pos; - if ((actrow + 2) < (int)rows.size()) - --checkpos; - while ((cursor.pos() < checkpos) && ((cursor.x() + swh) < x)) { - cursor.x(cursor.x() + sw); - cursor.pos(cursor.pos() + 1); - sw = swh = SingleWidth(pain, par, cursor.pos()); - if (par->GetChar(cursor.pos())!=LyXParagraph::META_INSET) - swh /= 2; - } + if (TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + return moveLeftIntern(bv, false, activate_inset, selecting); + else + return moveRightIntern(bv, false, activate_inset, selecting); } - -void InsetText::resetPos(Painter & pain) const +UpdatableInset::RESULT +InsetText::moveLeft(BufferView * bv, bool activate_inset, bool selecting) { - cursor.par(par); - - if (!rows.size()) - return; - - int old_pos = cursor.pos(); - - cursor.y(top_baseline); - actrow = 0; - for(unsigned int i = 0; - i < (rows.size() - 1) && rows[i].pos <= cursor.pos(); - ++i) { - cursor.y(rows[i].baseline); - actrow = i; - } - cursor.y(cursor.y() - top_baseline); - setPos(pain, 0, cursor.y()); - cursor.x(top_x + 2); // 2 = frame width - while(cursor.pos() < old_pos) { - cursor.x(cursor.x() + SingleWidth(pain, par,cursor.pos())); - cursor.pos(cursor.pos() + 1); - } + if (TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + return moveRightIntern(bv, true, activate_inset, selecting); + else + return moveLeftIntern(bv, true, activate_inset, selecting); } UpdatableInset::RESULT -InsetText::moveRight(BufferView * bv, bool activate_inset) +InsetText::moveRightIntern(BufferView * bv, bool behind, + bool activate_inset, bool selecting) { - if (cursor.pos() >= par->Last()) +#ifndef NEW_INSETS + if (!cpar(bv)->next_ && (cpos(bv) >= cpar(bv)->Last())) +#else + if (!cpar(bv)->next() && (cpos(bv) >= cpar(bv)->size())) +#endif return FINISHED; - if (activate_inset && checkAndActivateInset(bv)) { + if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; - } - cursor.pos(cursor.pos() + 1); - resetPos(bv->painter()); - real_current_font = current_font =GetFont(bv->buffer(), par, cursor.pos()); + TEXT(bv)->CursorRight(bv); + if (!selecting) + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; return DISPATCHED_NOUPDATE; } UpdatableInset::RESULT -InsetText::moveLeft(BufferView * bv, bool activate_inset) +InsetText::moveLeftIntern(BufferView * bv, bool behind, + bool activate_inset, bool selecting) { - if (cursor.pos() <= 0) +#ifndef NEW_INSETS + if (!cpar(bv)->previous_ && (cpos(bv) <= 0)) +#else + if (!cpar(bv)->previous() && (cpos(bv) <= 0)) +#endif return FINISHED; - cursor.pos(cursor.pos() - 1); - resetPos(bv->painter()); - if (activate_inset) - if (checkAndActivateInset(bv, -1, -1)) - return DISPATCHED; + TEXT(bv)->CursorLeft(bv); + if (!selecting) + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + if (activate_inset && checkAndActivateInset(bv, behind)) + return DISPATCHED; return DISPATCHED_NOUPDATE; } @@ -1167,13 +1370,9 @@ InsetText::moveLeft(BufferView * bv, bool activate_inset) UpdatableInset::RESULT InsetText::moveUp(BufferView * bv) { - if (!actrow) + if (!crow(bv)->previous()) return FINISHED; - cursor.y(rows[actrow - 1].baseline - top_baseline); - if (cursor.x_fix() < 0) - cursor.x_fix(cursor.x()); - setPos(bv->painter(), - cursor.x_fix() - top_x + drawTextXOffset, cursor.y()); + TEXT(bv)->CursorUp(bv); return DISPATCHED_NOUPDATE; } @@ -1181,28 +1380,13 @@ InsetText::moveUp(BufferView * bv) UpdatableInset::RESULT InsetText::moveDown(BufferView * bv) { - if (actrow >= int(rows.size() - 2)) + if (!crow(bv)->next()) return FINISHED; - cursor.y(rows[actrow + 1].baseline - top_baseline); - if (cursor.x_fix() < 0) - cursor.x_fix(cursor.x()); - setPos(bv->painter(), - cursor.x_fix() - top_x + drawTextXOffset, cursor.y()); + TEXT(bv)->CursorDown(bv); return DISPATCHED_NOUPDATE; } -bool InsetText::Delete() -{ - if ((par->GetChar(cursor.pos())==LyXParagraph::META_INSET) && - !par->GetInset(cursor.pos())->Deletable()) { - return false; - } - par->Erase(cursor.pos()); - return true; -} - - bool InsetText::InsertInset(BufferView * bv, Inset * inset) { if (the_locking_inset) { @@ -1210,22 +1394,26 @@ bool InsetText::InsertInset(BufferView * bv, Inset * inset) return the_locking_inset->InsertInset(bv, inset); return false; } - bv->text->SetUndo(bv->buffer(), Undo::INSERT, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next); - if (inset->Editable() == Inset::IS_EDITABLE) { - UpdatableInset * i = static_cast(inset); - i->setOwner(static_cast(this)); - } - par->InsertChar(cursor.pos(), LyXParagraph::META_INSET); - par->InsertInset(cursor.pos(), inset); - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - } else { - selection_start_cursor = selection_end_cursor = cursor; - } - UpdateLocal(bv, true); - static_cast(inset)->Edit(bv, 0, 0, 0); + bv->text->SetUndo(bv->buffer(), Undo::INSERT, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); + inset->setOwner(this); + HideInsetCursor(bv); + TEXT(bv)->InsertInset(bv, inset); +#if 0 + if ((cpar(bv)->GetChar(cpos(bv)) != LyXParagraph::META_INSET) || + (cpar(bv)->GetInset(cpos(bv)) != inset)) + TEXT(bv)->CursorLeft(bv); +#endif + bv->fitCursor(TEXT(bv)); + UpdateLocal(bv, CURSOR_PAR|CURSOR, true); + ShowInsetCursor(bv); return true; } @@ -1246,381 +1434,388 @@ UpdatableInset * InsetText::GetFirstLockingInsetOfType(Inset::Code c) } +bool InsetText::ShowInsetDialog(BufferView * bv) const +{ + if (the_locking_inset) + return the_locking_inset->ShowInsetDialog(bv); + return false; +} + + void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) { - // if there is no selection just set the current_font - if (!hasSelection()) { - // Determine basis font - LyXFont layoutfont; - if (cursor.pos() < BeginningOfMainBody(bv->buffer(), par)) - layoutfont = GetFont(bv->buffer(), par, -2); - else - layoutfont = GetFont(bv->buffer(), par, -1); - - // Update current font - real_current_font.update(font, bv->buffer()->params.language_info, - toggleall); - - // Reduce to implicit settings - current_font = real_current_font; - current_font.reduce(layoutfont); - // And resolve it completely - real_current_font.realize(layoutfont); - return; + if (TEXT(bv)->selection) { + bv->text->SetUndo(bv->buffer(), Undo::EDIT, +#ifndef NEW_INSETS + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, + bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ +#else + bv->text->cursor.par()->previous(), + bv->text->cursor.par()->next() +#endif + ); } - - int s_start, s_end; - if (selection_start_cursor.pos() > selection_end_cursor.pos()) { - s_start = selection_end_cursor.pos(); - s_end = selection_start_cursor.pos(); - } else { - s_start = selection_start_cursor.pos(); - s_end = selection_end_cursor.pos(); + TEXT(bv)->SetFont(bv, font, toggleall); + bv->fitCursor(TEXT(bv)); + UpdateLocal(bv, CURSOR_PAR, true); +} + + +bool InsetText::checkAndActivateInset(BufferView * bv, bool behind) +{ + if (cpar(bv)->GetChar(cpos(bv)) == LyXParagraph::META_INSET) { + unsigned int x; + unsigned int y; + Inset * inset = + static_cast(cpar(bv)->GetInset(cpos(bv))); + if (!inset || inset->Editable() != Inset::HIGHLY_EDITABLE) + return false; + LyXFont const font = + TEXT(bv)->GetFont(bv->buffer(), cpar(bv), cpos(bv)); + if (behind) { + x = inset->width(bv, font); + y = font.isRightToLeft() ? 0 : inset->descent(bv, font); + } else { + x = 0; + y = font.isRightToLeft() ? inset->descent(bv, font) : 0; + } + //inset_x = cx(bv) - top_x + drawTextXOffset; + //inset_y = cy(bv) + drawTextYOffset; + inset->Edit(bv, x, y, 0); + if (!the_locking_inset) + return false; + UpdateLocal(bv, CURSOR_PAR, false); + return true; } - LyXFont newfont; - while(s_start < s_end) { - newfont = GetFont(bv->buffer(), par,s_start); - newfont.update(font, bv->buffer()->params.language_info, toggleall); - SetCharFont(bv->buffer(), s_start, newfont); - ++s_start; + return false; +} + + +bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, + int button) +{ + int dummyx, dummyy; + + dummyx = x = x - drawTextXOffset; + dummyy = y + insetAscent; + Inset * inset = bv->checkInsetHit(TEXT(bv), dummyx, dummyy, button); + + if (inset) { + if (x < 0) + x = insetWidth; + if (y < 0) + y = insetDescent; + inset_x = cx(bv) - top_x + drawTextXOffset; + inset_y = cy(bv) + drawTextYOffset; + inset->Edit(bv, x - inset_x, y - inset_y, button); + if (!the_locking_inset) + return false; + UpdateLocal(bv, CURSOR_PAR, false); + return true; } - UpdateLocal(bv, true); + return false; } -void InsetText::SetCharFont(Buffer const * buf, int pos, LyXFont const & f) // +int InsetText::getMaxWidth(Painter & pain, UpdatableInset const * inset) const { - /* let the insets convert their font */ - LyXFont font(f); - - if (par->GetChar(pos) == LyXParagraph::META_INSET) { - if (par->GetInset(pos)) - font = par->GetInset(pos)->ConvertFont(font); + int w = UpdatableInset::getMaxWidth(pain, inset); + if (w < 0) { + return w; + } + if (owner()) { + w = w - top_x + owner()->x(); + return w; } - LyXLayout const & layout = - textclasslist.Style(buf->params.textclass,par->GetLayout()); + w -= (2 * TEXT_TO_INSET_OFFSET); + return w - top_x; +// return w - (2*TEXT_TO_INSET_OFFSET); +} - // Get concrete layout font to reduce against - LyXFont layoutfont; - if (pos < BeginningOfMainBody(buf, par)) - layoutfont = layout.labelfont; - else - layoutfont = layout.font; - - - layoutfont.realize((textclasslist.TextClass(buf->params.textclass). - defaultfont())); - - // Now, reduce font against full layout font - font.reduce(layoutfont); - - par->SetFont(pos, font); -} - - -void InsetText::computeTextRows(Painter & pain) const -{ - int p, - nwp = 0, - asc = 0, - desc = 0, - oasc = 0, - odesc = 0, - wordAscent, - wordDescent; - row_struct row; - - if (rows.size()) - rows.clear(); - int width = wordAscent = wordDescent = 0; - insetWidth = maxAscent = maxDescent = 0; - row.asc = 0; - row.desc = 0; - row.pos = 0; - row.baseline = 0; - rows.push_back(row); - if (!autoBreakRows || (getMaxTextWidth(pain, this) < 0)) { - for(p = 0; p < par->Last(); ++p) { - insetWidth += SingleWidth(pain, par, p); - SingleHeight(pain, par, p, asc, desc); - maxAscent = max(maxAscent, asc); - maxDescent = max(maxDescent, desc); - } - insetWidth += (2 * TEXT_TO_INSET_OFFSET); - rows[0].asc = maxAscent; - rows[0].desc = maxDescent; - // alocate a dummy row for the endpos - row.pos = par->Last(); - rows.push_back(row); - return; +void InsetText::SetParagraphData(LyXParagraph * p) +{ + // delete all instances of LyXText before deleting the paragraps used + // by it. + for (Cache::iterator cit = cache.begin(); cit != cache.end(); ++cit){ + delete (*cit).second; + (*cit).second = 0; } - bool is_first_word_in_row = true; - int cw, lastWordWidth = 0; - int maxWidth = getMaxTextWidth(pain, this); - // if we auto break rows than the insetwidth should be always the max - // width as the display is stable it may get larger if we have a really - // large word below and we draw it!!! - insetWidth = maxWidth; - - for(p = 0; p < par->Last(); ++p) { - if (par->IsNewline(p)) { - rows.back().asc = wordAscent; - rows.back().desc = wordDescent; - row.pos = p+1; - rows.push_back(row); - nwp = p+1; - width = lastWordWidth = 0; - oasc = odesc = wordAscent = wordDescent = 0; - is_first_word_in_row = true; - continue; - } - cw = SingleWidth(pain, par, p); - Inset * inset = 0; - if (par->GetChar(p) == LyXParagraph::META_INSET) - inset = par->GetInset(p); - if (inset && inset->display()) { - inset->setOwner(const_cast(this)); - if (cw > insetWidth) - insetWidth = cw; - if (!is_first_word_in_row || (p != nwp)) { - oasc = max(oasc, wordAscent); - odesc = max(odesc, wordDescent); - rows.back().asc = oasc; - rows.back().desc = odesc; - row.pos = p; - rows.push_back(row); - } - SingleHeight(pain, par, p, asc, desc); - rows.back().asc = asc; - rows.back().desc = desc; - row.pos = nwp = p + 1; - rows.push_back(row); - width = lastWordWidth = 0; - oasc = odesc = wordAscent = wordDescent = 0; - is_first_word_in_row = true; - continue; - } - SingleHeight(pain, par, p, asc, desc); - width += cw; - lastWordWidth += cw; - if (width > maxWidth) { - if (is_first_word_in_row) { - if (!(width-cw)) { // only this character in word - rows.back().asc = asc; - rows.back().desc = desc; - row.pos = p+1; - rows.push_back(row); - oasc = 0; - odesc = 0; - wordAscent = 0; - wordDescent = 0; - nwp = p + 1; - lastWordWidth = width = 0; - } else { - rows.back().asc = wordAscent; - rows.back().desc = wordDescent; - row.pos = p; - rows.push_back(row); - oasc = 0; - odesc = 0; - wordAscent = asc; - wordDescent = desc; - lastWordWidth = width = cw; - nwp = p; - } - } else { - rows.back().asc = oasc; - rows.back().desc = odesc; - row.pos = nwp; - rows.push_back(row); - oasc = wordAscent; - odesc = wordDescent; - width = lastWordWidth; - wordAscent = max(wordAscent, asc); - wordDescent = max(wordDescent, desc); - is_first_word_in_row = true; - } - } else { - wordAscent = max(wordAscent, asc); - wordDescent = max(wordDescent, desc); - } - if (par->IsSeparator(p) || inset) { - if (inset) { - inset->setOwner(const_cast(this)); - if (cw > maxWidth) - insetWidth = cw; - } - oasc = max(oasc, wordAscent); - odesc = max(odesc, wordDescent); - wordAscent = wordDescent = lastWordWidth = 0; - nwp = p + 1; - is_first_word_in_row = false; +#ifndef NEW_INSETS + LyXParagraph * np; + if (par) { + np = par->next_; + delete par; + while (np) { + par = np; + np = np->next_; + delete par; } } - // if we have some data in the paragraph we have ascent/descent - if (p) { - // assign last row data - rows.back().asc = max(oasc, wordAscent); - rows.back().desc = max(odesc, wordDescent); + par = p->Clone(); + par->SetInsetOwner(this); + np = par; + while (p->next_) { + p = p->next_; + np->next(p->Clone()); + np->next_->previous(np); + np = np->next_; + np->SetInsetOwner(this); + } +#else + LyXParagraph * np; + if (par) { + np = par->next(); + delete par; + while(np) { + par = np; + np = np->next(); + delete par; + } } - insetWidth += (2 * TEXT_TO_INSET_OFFSET); - // alocate a dummy row for the endpos - row.pos = par->Last(); - rows.push_back(row); - // calculate maxAscent/Descent - maxAscent = rows[0].asc; - maxDescent = rows[0].desc; - for (RowList::size_type i = 1; i < rows.size() - 1; ++i) { - maxDescent += rows[i].asc + rows[i].desc + interline_space; + par = p->Clone(); + par->SetInsetOwner(this); + np = par; + while(p->next()) { + p = p->next(); + np->next(p->Clone()); + np->next()->previous(np); + np = np->next(); + np->SetInsetOwner(this); } +#endif + need_update = INIT; } -void InsetText::computeBaselines(int baseline) const +void InsetText::SetText(string const & data) { - rows[0].baseline = baseline; - for (unsigned int i = 1; i < rows.size() - 1; i++) { - rows[i].baseline = rows[i - 1].baseline + rows[i - 1].desc + - rows[i].asc + interline_space; - } + clear(); + LyXFont font(LyXFont::ALL_SANE); + for(unsigned int i=0; i < data.length(); ++i) + par->InsertChar(i, data[i], font); } -void InsetText::UpdateLocal(BufferView * bv, bool flag) +void InsetText::SetAutoBreakRows(bool flag) { - if (flag) { - text->FullRebreak(bv); - computeTextRows(bv->painter()); - computeBaselines(top_baseline); + if (flag != autoBreakRows) { + autoBreakRows = flag; + need_update = FULL; + if (!flag) + removeNewlines(); } - bv->updateInset(this, flag); - if (flag) - resetPos(bv->painter()); - bv->owner()->getToolbar()->combox->select(cursor.par()->GetLayout()+1); } -bool InsetText::cutSelection(Buffer const * buf) +void InsetText::SetDrawFrame(BufferView * bv, DrawFrame how) { - if (!hasSelection()) - return false; + if (how != drawFrame) { + drawFrame = how; + if (bv) + UpdateLocal(bv, DRAW_FRAME, false); + } +} - CutAndPaste cap; - LyXParagraph * endpar = par; - int start, end; - if (selection_start_cursor.pos() > selection_end_cursor.pos()) { - start = selection_end_cursor.pos(); - end = selection_start_cursor.pos(); - } else { - start = selection_start_cursor.pos(); - end = selection_end_cursor.pos(); +void InsetText::SetFrameColor(BufferView * bv, LColor::color col) +{ + if (frame_color != col) { + frame_color = col; + if (bv) + UpdateLocal(bv, DRAW_FRAME, false); } +} - return cap.cutSelection(par, &endpar, start, end, buf->params.textclass); +#if 0 +LyXFont InsetText::GetDrawFont(BufferView * bv, LyXParagraph * p, int pos) const +{ + return TEXT(bv)->GetFont(bv->buffer(), p, pos); } +#endif -bool InsetText::copySelection(Buffer const * buf) +int InsetText::cx(BufferView * bv) const { - if (!hasSelection()) - return false; + LyXText * text = TEXT(bv); + int x = text->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; + if (the_locking_inset) { + LyXFont font = text->GetFont(bv->buffer(), + text->cursor.par(), text->cursor.pos()); + if (font.isVisibleRightToLeft()) + x -= the_locking_inset->width(bv, font); + } + return x; +} - CutAndPaste cap; - int start, end; - if (selection_start_cursor.pos() > selection_end_cursor.pos()) { - start = selection_end_cursor.pos(); - end = selection_start_cursor.pos(); - } else { - start = selection_start_cursor.pos(); - end = selection_end_cursor.pos(); - } - return cap.copySelection(par, par, start, end, buf->params.textclass); +int InsetText::cy(BufferView * bv) const +{ + LyXFont font; + return TEXT(bv)->cursor.y() - ascent(bv, font) + TEXT_TO_INSET_OFFSET; } -bool InsetText::pasteSelection(Buffer const * buf) +LyXParagraph::size_type InsetText::cpos(BufferView * bv) const { - CutAndPaste cap; + return TEXT(bv)->cursor.pos(); +} - if (cap.nrOfParagraphs() > 1) { - WriteAlert(_("Impossible operation"), - _("Cannot include more than one paragraph!"), - _("Sorry.")); - return false; - } - LyXParagraph * endpar; - LyXParagraph * actpar = par; - int pos = cursor.pos(); - bool ret = cap.pasteSelection(&actpar, &endpar, pos,buf->params.textclass); - cursor.pos(pos); - return ret; +LyXParagraph * InsetText::cpar(BufferView * bv) const +{ + return TEXT(bv)->cursor.par(); } - -bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, - int button) +bool InsetText::cboundary(BufferView * bv) const { - if (par->GetChar(cursor.pos()) == LyXParagraph::META_INSET) { - UpdatableInset * inset = - static_cast(par->GetInset(cursor.pos())); - LyXFont font = GetFont(bv->buffer(), par, cursor.pos()); - if (x < 0) - x = inset->width(bv->painter(), font); - if (y < 0) - y = inset->descent(bv->painter(), font); - inset_x = cursor.x() - top_x + drawTextXOffset; - inset_y = cursor.y() + drawTextYOffset; - inset->Edit(bv, x - inset_x, y - inset_y, button); - if (!the_locking_inset) - return false; - UpdateLocal(bv, true); - return true; - } - return false; + return TEXT(bv)->cursor.boundary(); } -int InsetText::getMaxTextWidth(Painter & pain, UpdatableInset const * inset) const +Row * InsetText::crow(BufferView * bv) const { -// int w=getMaxWidth(pain, inset); -// return (w - x); - return getMaxWidth(pain, inset) - 4; // 2+2 width of eventual border + return TEXT(bv)->cursor.row(); } -void InsetText::SetParagraphData(LyXParagraph *p) + +LyXText * InsetText::getLyXText(BufferView const * lbv, bool const recursive) const { - if (par) - delete par; - par = p->Clone(); - par->SetInsetOwner(this); - init_inset = true; + // Super UGLY! (Lgb) + BufferView * bv = const_cast(lbv); + + if ((cache.find(bv) != cache.end()) && cache[bv]) { + if (recursive && the_locking_inset) + return the_locking_inset->getLyXText(bv); + return cache[bv]; + } + LyXText * lt = new LyXText(const_cast(this)); + lt->init(bv); + cache[bv] = lt; + if (the_locking_inset) { + lt->SetCursor(bv, inset_par, inset_pos, true, inset_boundary); + if (recursive) + return the_locking_inset->getLyXText(bv); + } + return lt; } -void InsetText::SetAutoBreakRows(bool flag) + +void InsetText::deleteLyXText(BufferView * bv, bool recursive) const { - if (flag != autoBreakRows) { - autoBreakRows = flag; - init_inset = true; + if ((cache.find(bv) == cache.end()) || !cache[bv]) + return; + delete cache[bv]; + cache.erase(bv); + if (recursive) { + /// then remove all LyXText in text-insets + LyXParagraph * p = par; +#ifndef NEW_INSETS + for (; p; p = p->next_) { + p->deleteInsetsLyXText(bv); + } +#else + for (; p; p = p->next()) { + p->deleteInsetsLyXText(bv); + } +#endif } } -void InsetText::SetDrawLockedFrame(bool flag) + +void InsetText::resizeLyXText(BufferView * bv) const { - if (flag != drawLockedFrame) { - drawLockedFrame = flag; - init_inset = true; +#ifndef NEW_INSETS + if (!par->next_ && !par->size()) // resize not neccessary! +#else + if (!par->next() && !par->size()) // resize not neccessary! +#endif + return; + if ((cache.find(bv) == cache.end()) || !cache[bv]) + return; + + LyXParagraph * lpar = 0; + LyXParagraph * selstartpar = 0; + LyXParagraph * selendpar = 0; + LyXParagraph::size_type pos = 0; + LyXParagraph::size_type selstartpos = 0; + LyXParagraph::size_type selendpos = 0; + bool boundary = false; + bool selstartboundary = false; + bool selendboundary = false; + int selection = 0; + int mark_set = 0; + +// ProhibitInput(bv); + + if (locked) { + lpar = TEXT(bv)->cursor.par(); + pos = TEXT(bv)->cursor.pos(); + boundary = TEXT(bv)->cursor.boundary(); + selstartpar = TEXT(bv)->sel_start_cursor.par(); + selstartpos = TEXT(bv)->sel_start_cursor.pos(); + selstartboundary = TEXT(bv)->sel_start_cursor.boundary(); + selendpar = TEXT(bv)->sel_end_cursor.par(); + selendpos = TEXT(bv)->sel_end_cursor.pos(); + selendboundary = TEXT(bv)->sel_end_cursor.boundary(); + selection = TEXT(bv)->selection; + mark_set = TEXT(bv)->mark_set; + } + deleteLyXText(bv, (the_locking_inset == 0)); + + if (lpar) { + TEXT(bv)->selection = true; + /* at this point just to avoid the Delete-Empty-Paragraph + * Mechanism when setting the cursor */ + TEXT(bv)->mark_set = mark_set; + if (selection) { + TEXT(bv)->SetCursor(bv, selstartpar, selstartpos,true, + selstartboundary); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + TEXT(bv)->SetCursor(bv, selendpar, selendpos, true, selendboundary); + TEXT(bv)->SetSelection(bv); + TEXT(bv)->SetCursor(bv, lpar, pos); + } else { + TEXT(bv)->SetCursor(bv, lpar, pos, true, boundary); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + TEXT(bv)->selection = false; + } + } + if (bv->screen()) + TEXT(bv)->first = bv->screen()->TopCursorVisible(TEXT(bv)); + // 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; +#ifndef NEW_INSETS + for (LyXParagraph * p = par; p; p = p->next_) { + p->resizeInsetsLyXText(bv); + } +#else + for (LyXParagraph * p = par; p; p = p->next()) { + p->resizeInsetsLyXText(bv); + } +#endif } + need_update = FULL; } -void InsetText::SetFrameColor(LColor::color col) + +void InsetText::removeNewlines() { - if (frame_color != col) { - frame_color = col; - init_inset = true; +#ifndef NEW_INSETS + for (LyXParagraph * p = par; p; p = p->next_) { + for (int i = 0; i < p->Last(); ++i) { +#else + for (LyXParagraph * p = par; p; p = p->next()) { + for (int i = 0; i < p->size(); ++i) { +#endif + if (p->GetChar(i) == LyXParagraph::META_NEWLINE) + p->Erase(i); + } } }