X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=9d414218ba572794709d44d5f915690177084739;hb=b95e8f250dca6264900d8aedf98e8a24411c36d4;hp=f05a18873458e2d82c46ad87a650634bc2539389;hpb=666140b7f20ad45d69b6c8aad25ae37f79ef03b1;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index f05a188734..9d414218ba 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -38,7 +38,6 @@ #include "CutAndPaste.h" #include "font.h" #include "minibuffer.h" -#include "toolbar.h" #include "LColor.h" #include "support/textutils.h" #include "support/LAssert.h" @@ -47,6 +46,7 @@ #include "intl.h" #include "trans_mgr.h" #include "lyxscreen.h" +#include "WorkArea.h" using std::ostream; using std::ifstream; @@ -55,6 +55,8 @@ using std::min; using std::max; extern unsigned char getCurrentTextClass(Buffer *); +extern bool math_insert_greek(BufferView *, char); +extern int greek_kb_flag; InsetText::InsetText() { @@ -79,16 +81,22 @@ InsetText & InsetText::operator=(InsetText const & it) return * this; } + void InsetText::init(InsetText const * ins) { - top_y = last_width = last_height = 0; - insetAscent = insetDescent = insetWidth = 0; + top_y = 0; + last_width = 0; + last_height = 0; + insetAscent = 0; + insetDescent = 0; + insetWidth = 0; the_locking_inset = 0; cursor_visible = false; interline_space = 1; no_selection = false; need_update = INIT; - drawTextXOffset = drawTextYOffset = 0; + drawTextXOffset = 0; + drawTextYOffset = 0; autoBreakRows = false; drawFrame = NEVER; xpos = 0.0; @@ -106,17 +114,62 @@ void InsetText::init(InsetText const * ins) InsetText::~InsetText() { - LyXParagraph * p = par->next; + // 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; + 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; @@ -142,17 +195,36 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex) 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); - LyXParagraph * p = par->next; + // 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; + 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; while (lex.IsOK()) { lex.nextToken(); @@ -161,10 +233,14 @@ 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; @@ -175,7 +251,11 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex) par = return_par; while(return_par) { return_par->SetInsetOwner(this); - return_par = return_par->next; +#ifndef NEW_INSETS + return_par = return_par->next_; +#else + return_par = return_par->next(); +#endif } if (token != "\\end_inset") { @@ -188,7 +268,7 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex) int InsetText::ascent(BufferView * bv, LyXFont const &) const { - long int y_temp = 0; + int y_temp = 0; Row * row = TEXT(bv)->GetRowNearY(y_temp); insetAscent = row->ascent_of_text() + TEXT_TO_INSET_OFFSET; return insetAscent; @@ -197,7 +277,7 @@ int InsetText::ascent(BufferView * bv, LyXFont const &) const int InsetText::descent(BufferView * bv, LyXFont const &) const { - long int y_temp = 0; + int y_temp = 0; Row * row = TEXT(bv)->GetRowNearY(y_temp); insetDescent = TEXT(bv)->height - row->ascent_of_text() + TEXT_TO_INSET_OFFSET; @@ -207,28 +287,16 @@ int InsetText::descent(BufferView * bv, LyXFont const &) const int InsetText::width(BufferView * bv, LyXFont const &) const { - insetWidth = TEXT(bv)->width + (2 * TEXT_TO_INSET_OFFSET); + insetWidth = max(textWidth(bv->painter()), + (int)TEXT(bv)->width + (2 * TEXT_TO_INSET_OFFSET)); return insetWidth; } int InsetText::textWidth(Painter & pain) const { - int w = getMaxWidth(pain, this); - if (w < 0) { -// printf("WW1: %d\n",w); - return w; - } -#if 1 - if (owner()) { - w = w - top_x + owner()->x(); -// printf("WW2: %d\n",w); - return w; // - top_x + owner()->x(); - } -#endif - w -= (2 * TEXT_TO_INSET_OFFSET); -// printf("WW2: %d\n",w); - return w - top_x; // - top_x - (2 * TEXT_TO_INSET_OFFSET); + int const w = getMaxWidth(pain, this); + return w; } @@ -237,17 +305,36 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, { 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); + } + top_x = int(x); + top_baseline = baseline; + x += width(bv, f); + need_update = NONE; + return; + } + xpos = x; UpdatableInset::draw(bv, f, baseline, x, cleared); - if (!cleared && ((need_update==FULL) || (top_x!=int(x)) || - (top_baseline!=baseline))) { + // 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))) + { int w = insetWidth; int h = insetAscent + insetDescent; int ty = baseline - insetAscent; - if (ty < 0) + if (ty < 0) { + h += ty; ty = 0; + } if ((ty + h) > pain.paperHeight()) h = pain.paperHeight(); if ((top_x + drawTextXOffset + w) > pain.paperWidth()) @@ -261,10 +348,12 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, if (top_x != int(x)) { need_update = INIT; + top_x = int(x); + bv->text->status = LyXText::CHANGED_IN_DRAW; + return; } top_baseline = baseline; - top_x = int(x); top_y = baseline - ascent(bv, f); last_width = width(bv, f); last_height = ascent(bv, f) + descent(bv, f); @@ -273,50 +362,94 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, inset_x = cx(bv) - top_x + drawTextXOffset; inset_y = cy(bv) + drawTextYOffset; } - if (!cleared && (need_update == CURSOR)) { + if (!cleared && (need_update == CURSOR) && !TEXT(bv)->selection) { x += width(bv, f); need_update = NONE; return; } - x += TEXT_TO_INSET_OFFSET; // place for border - long int y = 0; - Row * row = TEXT(bv)->GetRowNearY(y); - y += baseline - row->ascent_of_text() + 1; - if (cleared || !locked || (need_update == FULL)) { - while (row != 0) { - TEXT(bv)->GetVisibleRow(bv, y, x, row, y, cleared); + 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(); } - } else if (need_update == SELECTION) { - bv->screen()->ToggleToggle(getLyXText(bv), y, x); - } else { - locked = false; - bv->screen()->Update(TEXT(bv), y, x); - locked = true; + 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; + } } TEXT(bv)->refresh_y = 0; TEXT(bv)->status = LyXText::UNCHANGED; - if ((drawFrame == ALWAYS) || ((drawFrame == LOCKED) && locked)) { - pain.rectangle(top_x, baseline - insetAscent, insetWidth, - insetAscent + insetDescent, frame_color); - } else if (need_update == CLEAR_FRAME) { - pain.rectangle(top_x, baseline - insetAscent, insetWidth, - insetAscent + insetDescent, + 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 += insetWidth - TEXT_TO_INSET_OFFSET; - if (need_update != INIT) + 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::update(BufferView * bv, LyXFont const & font, bool dodraw) +void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) { - if (the_locking_inset) - the_locking_inset->update(bv, font, dodraw); + if (reinit) { // && (need_update != CURSOR)) { + need_update = INIT; + resizeLyXText(bv); + if (owner()) + owner()->update(bv, font, true); + return; + } + 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) { - deleteLyXText(bv); + resizeLyXText(bv); need_update = FULL; } int oldw = insetWidth; @@ -331,31 +464,13 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool dodraw) 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)); - deleteLyXText(bv); +// printf("TW(%p): %d-%d-%d-%d\n",this,insetWidth, oldw, +// textWidth(bv->painter()),static_cast(TEXT(bv)->width)); + resizeLyXText(bv); need_update = FULL; -#if 0 - if (owner()) { - owner()->update(bv, font, dodraw); - return; - } else { - update(bv, font, dodraw); - } -#else -#if 1 - update(bv, font, dodraw); -#else - UpdateLocal(bv, INIT, false); -#endif -#endif + update(bv, font, reinit); return; } - if (dodraw && (need_update != CURSOR)) - need_update = FULL; - - TEXT(bv)->FullRebreak(bv); - if ((need_update==CURSOR_PAR) && (TEXT(bv)->status==LyXText::UNCHANGED) && the_locking_inset) { @@ -365,31 +480,42 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool dodraw) if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH) need_update = FULL; - long int y_temp = 0; + 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, UpdateCodes what, bool mark_dirty) +void InsetText::UpdateLocal(BufferView * bv, int what, bool mark_dirty) { TEXT(bv)->FullRebreak(bv); - if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH) - need_update = FULL; - else if (!the_locking_inset || (what != CURSOR)) - need_update = what; - if ((need_update != CURSOR) || (TEXT(bv)->status != LyXText::UNCHANGED)) + 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()->getToolbar()->combox->select(cpar(bv)->GetLayout()+1); + bv->owner()->setLayout(cpar(bv)->GetLayout()); old_par = cpar(bv); } } -char const * InsetText::EditMessage() const +string const InsetText::EditMessage() const { return _("Opened Text Inset"); } @@ -407,12 +533,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; + inset_boundary = false; inset_par = 0; + old_par = 0; if (!checkAndActivateInset(bv, x, y, button)) - TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, y); + TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, + y+insetAscent); TEXT(bv)->sel_cursor = TEXT(bv)->cursor; bv->text->FinishUndo(); + 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->Last() == 0 && !par->next()) { +#endif + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + SetFont(bv, font, false); + } } @@ -425,9 +567,12 @@ void InsetText::InsetUnlock(BufferView * bv) HideInsetCursor(bv); no_selection = false; locked = false; - TEXT(bv)->selection = 0; - UpdateLocal(bv, CLEAR_FRAME, false); - bv->owner()->getToolbar()->combox->select(bv->text->cursor.par()->GetLayout()+1); + 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()); } @@ -443,7 +588,14 @@ bool InsetText::LockInsetInInset(BufferView * bv, UpdatableInset * inset) 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 (cpar(bv) == inset_par && cpos(bv) == inset_pos) { @@ -473,6 +625,7 @@ bool InsetText::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset, the_locking_inset = 0; if (lr) moveRight(bv, false); + old_par = 0; // force layout setting UpdateLocal(bv, CURSOR_PAR, false); return true; } @@ -486,7 +639,7 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset) return false; if (the_locking_inset != inset) { TEXT(bv)->UpdateInset(bv, the_locking_inset); - need_update = CURSOR_PAR; + SetUpdateStatus(bv, CURSOR_PAR); return the_locking_inset->UpdateInsetInInset(bv, inset); } // UpdateLocal(bv, FULL, false); @@ -502,53 +655,76 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset) void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) { - if (TEXT(bv)->selection) { - TEXT(bv)->selection = 0; - UpdateLocal(bv, FULL, false); - } - no_selection = false; + no_selection = true; int tmp_x = x - drawTextXOffset; -// int tmp_y = y + TEXT(bv)->first + insetAscent; - int tmp_y = y + insetAscent; + 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) { 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 = 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); if (the_locking_inset) - UpdateLocal(bv, CURSOR_PAR, false); + 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 (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_PAR, false); + UpdateLocal(bv, CURSOR, false); + no_selection = false; return; } } - if (!inset) + if (!inset) { + bool paste_internally = false; + if ((button == 2) && TEXT(bv)->selection) { + LocalDispatch(bv, LFUN_COPY, ""); + paste_internally = true; + } TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, - y+TEXT(bv)->first+insetAscent); + 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"); + } + } + ShowInsetCursor(bv); + no_selection = false; } @@ -557,7 +733,9 @@ 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 (cpar(bv)->GetChar(cpos(bv)) == LyXParagraph::META_INSET) { inset = static_cast(cpar(bv)->GetInset(cpos(bv))); @@ -569,6 +747,7 @@ void InsetText::InsetButtonRelease(BufferView * bv, int x, int y, int button) 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; @@ -577,22 +756,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; } -#warning REDO this (Jug) - 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, 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); } @@ -607,13 +785,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; } @@ -629,25 +806,36 @@ InsetText::LocalDispatch(BufferView * 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: - moveRight(bv, false); + if (!TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + moveRightIntern(bv, false, false); + dispatched = true; break; - case LFUN_DOWN: - moveDown(bv); + case LFUN_LEFT: + if (TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + moveRightIntern(bv, false, false); + dispatched = true; + break; + default: break; } the_locking_inset = 0; - return DISPATCHED; + if (dispatched) + return DISPATCHED; } } HideInsetCursor(bv); switch (action) { // Normal chars - case -1: + case LFUN_UNKNOWN_ACTION: if (bv->buffer()->isReadonly()) { - LyXBell(); // setErrorMessage(N_("Document is read only")); break; } @@ -658,105 +846,134 @@ InsetText::LocalDispatch(BufferView * bv, * "auto_region_delete", which defaults to * true (on). */ - 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); + 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(); + TEXT(bv)->ClearSelection(bv); for (string::size_type i = 0; i < arg.length(); ++i) { - bv->owner()->getIntl()->getTrans()->TranslateAndInsert(arg[i], TEXT(bv)); + 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); - TEXT(bv)->SetSelection(); + moveRight(bv, false, true); + TEXT(bv)->SetSelection(bv); UpdateLocal(bv, SELECTION, false); break; case LFUN_RIGHT: - bv->text->FinishUndo(); result = moveRight(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + bv->text->FinishUndo(); UpdateLocal(bv, CURSOR, false); break; case LFUN_LEFTSEL: bv->text->FinishUndo(); - moveLeft(bv, false); - TEXT(bv)->SetSelection(); + moveLeft(bv, false, true); + TEXT(bv)->SetSelection(bv); UpdateLocal(bv, SELECTION, false); break; case LFUN_LEFT: bv->text->FinishUndo(); - result= moveLeft(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + result = moveLeft(bv); UpdateLocal(bv, CURSOR, false); break; case LFUN_DOWNSEL: bv->text->FinishUndo(); moveDown(bv); - TEXT(bv)->SetSelection(); + TEXT(bv)->SetSelection(bv); UpdateLocal(bv, SELECTION, false); break; case LFUN_DOWN: bv->text->FinishUndo(); result = moveDown(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_UPSEL: bv->text->FinishUndo(); moveUp(bv); - TEXT(bv)->SetSelection(); + TEXT(bv)->SetSelection(bv); UpdateLocal(bv, SELECTION, false); break; case LFUN_UP: bv->text->FinishUndo(); result = moveUp(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_HOME: bv->text->FinishUndo(); TEXT(bv)->CursorHome(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_END: TEXT(bv)->CursorEnd(bv); - TEXT(bv)->selection = 0; - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_BACKSPACE: - 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); - TEXT(bv)->Backspace(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); - TEXT(bv)->Delete(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)->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); + 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; @@ -765,10 +982,40 @@ InsetText::LocalDispatch(BufferView * bv, TEXT(bv)->CopySelection(bv); UpdateLocal(bv, CURSOR_PAR, false); break; + case LFUN_PASTESELECTION: + { + string clip(bv->workarea()->getClipboard()); + + if (clip.empty()) + break; + if (arg == "paragraph") { + TEXT(bv)->InsertStringB(bv, clip); + } else { + TEXT(bv)->InsertStringA(bv, clip); + } + UpdateLocal(bv, CURSOR_PAR, true); + break; + } case LFUN_PASTE: - 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 (!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; @@ -778,67 +1025,79 @@ InsetText::LocalDispatch(BufferView * bv, 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); + 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 = cpar(bv)->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(bv)->SetLayout(bv, layout.second); - bv->owner()->getToolbar()->combox->select(cpar(bv)->GetLayout()+1); - UpdateLocal(bv, CURSOR_PAR, 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; + 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->spacing.getSpace(); + Spacing::Space cur_spacing = par->params.spacing().getSpace(); float cur_value = 1.0; if (cur_spacing == Spacing::Other) { - cur_value = par->spacing.getValue(); + cur_value = par->params.spacing().getValue(); } -#ifdef HAVE_SSTREAM - std::istringstream istr(arg); -#else - istrstream istr(arg.c_str()); -#endif + std::istringstream istr(arg.c_str()); string tmp; istr >> tmp; Spacing::Space new_spacing = cur_spacing; @@ -866,7 +1125,7 @@ InsetText::LocalDispatch(BufferView * bv, << arg << endl; } if (cur_spacing != new_spacing || cur_value != new_value) { - par->spacing.set(new_spacing, 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); @@ -875,9 +1134,23 @@ InsetText::LocalDispatch(BufferView * bv, 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->Last() == 0 && !par->next()) { +#endif + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + SetFont(bv, font, false); + } + if (result != FINISHED) { ShowInsetCursor(bv); } else @@ -894,12 +1167,56 @@ int InsetText::Latex(Buffer const * buf, ostream & os, bool, bool) const } +int InsetText::Ascii(Buffer const * buf, ostream & os, int linelen) const +{ + 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; +} + + +int InsetText::DocBook(Buffer const * buf, ostream & os) const +{ + LyXParagraph * p = par; + unsigned int lines = 0; + int desc=0; + + string tmp; + while (p) { + buf->SimpleDocBookOnePar(os,tmp,p,desc,0); +#ifndef NEW_INSETS + p = p->next_; +#else + p = p->next(); +#endif + } + + return lines; +} + + void InsetText::Validate(LaTeXFeatures & features) const { LyXParagraph * p = par; while(p) { p->validate(features); - p = p->next; +#ifndef NEW_INSETS + p = p->next_; +#else + p = p->next(); +#endif } } @@ -914,14 +1231,15 @@ int InsetText::BeginningOfMainBody(Buffer const * buf, LyXParagraph * p) const } -void InsetText::GetCursorPos(BufferView * bv, int & x, int & y) const +void InsetText::GetCursorPos(BufferView * bv, + int & x, int & y) const { x = cx(bv); y = cy(bv); } -int InsetText::InsetInInsetY() +unsigned int InsetText::InsetInInsetY() { if (!the_locking_inset) return 0; @@ -945,13 +1263,12 @@ void InsetText::ToggleInsetCursor(BufferView * bv) if (cursor_visible) bv->hideLockedInsetCursor(); else - bv->showLockedInsetCursor(cx(bv), cy(bv), - 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); @@ -964,7 +1281,8 @@ void InsetText::ShowInsetCursor(BufferView * bv) int desc = lyxfont::maxDescent(font); bv->fitLockedInsetCursor(cx(bv), cy(bv), asc, desc); - bv->showLockedInsetCursor(cx(bv), cy(bv), asc, desc); + if (show) + bv->showLockedInsetCursor(cx(bv), cy(bv), asc, desc); cursor_visible = true; } } @@ -982,24 +1300,57 @@ void InsetText::HideInsetCursor(BufferView * bv) UpdatableInset::RESULT -InsetText::moveRight(BufferView * bv, bool activate_inset) +InsetText::moveRight(BufferView * bv, bool activate_inset, bool selecting) +{ + if (TEXT(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params)) + return moveLeftIntern(bv, false, activate_inset, selecting); + else + return moveRightIntern(bv, false, activate_inset, selecting); +} + +UpdatableInset::RESULT +InsetText::moveLeft(BufferView * bv, bool activate_inset, bool selecting) +{ + 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::moveRightIntern(BufferView * bv, bool behind, + bool activate_inset, bool selecting) { - if (!cpar(bv)->next && (cpos(bv) >= cpar(bv)->Last())) +#ifndef NEW_INSETS + if (!cpar(bv)->next_ && (cpos(bv) >= cpar(bv)->Last())) +#else + if (!cpar(bv)->next() && (cpos(bv) >= cpar(bv)->Last())) +#endif return FINISHED; - if (activate_inset && checkAndActivateInset(bv, false)) + if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; 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 (!cpar(bv)->previous && (cpos(bv) <= 0)) +#ifndef NEW_INSETS + if (!cpar(bv)->previous_ && (cpos(bv) <= 0)) +#else + if (!cpar(bv)->previous() && (cpos(bv) <= 0)) +#endif return FINISHED; TEXT(bv)->CursorLeft(bv); - if (activate_inset && checkAndActivateInset(bv, true)) + if (!selecting) + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; return DISPATCHED_NOUPDATE; } @@ -1032,17 +1383,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)); - } - cpar(bv)->InsertInset(cpos(bv), inset); - TEXT(bv)->selection = 0; - UpdateLocal(bv, CURSOR_PAR, 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; } @@ -1065,28 +1425,44 @@ UpdatableInset * InsetText::GetFirstLockingInsetOfType(Inset::Code c) void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) { + 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 + ); + } 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) { - int x, y; + 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 font = TEXT(bv)->GetFont(bv->buffer(), cpar(bv), cpos(bv)); + LyXFont const font = + TEXT(bv)->GetFont(bv->buffer(), cpar(bv), cpos(bv)); if (behind) { x = inset->width(bv, font); - y = inset->descent(bv, font); + y = font.isRightToLeft() ? 0 : inset->descent(bv, font); } else { - x = y = 0; + 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-inset_x, y-inset_y, 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); @@ -1099,9 +1475,9 @@ bool InsetText::checkAndActivateInset(BufferView * bv, bool behind) bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, int button) { - int tmp_x = x - drawTextXOffset; - int tmp_y = y + insetAscent; - Inset * inset = bv->checkInsetHit(TEXT(bv), tmp_x, tmp_y, button); + x = x - drawTextXOffset; + y = y + insetAscent; + Inset * inset = bv->checkInsetHit(TEXT(bv), x, y, button); if (inset) { if (x < 0) @@ -1123,44 +1499,91 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, int InsetText::getMaxWidth(Painter & pain, UpdatableInset const * inset) const { int w = UpdatableInset::getMaxWidth(pain, inset); - if (w < 0) + if (w < 0) { + return w; + } + if (owner()) { + w = w - top_x + owner()->x(); return w; - return w - (2*TEXT_TO_INSET_OFFSET); + } + w -= (2 * TEXT_TO_INSET_OFFSET); + return w - top_x; +// return w - (2*TEXT_TO_INSET_OFFSET); } -void InsetText::SetParagraphData(LyXParagraph *p) +void InsetText::SetParagraphData(LyXParagraph * p) { - LyXParagraph * np; + // 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 * np; + if (par) { + np = par->next_; + delete par; + while (np) { + par = np; + np = np->next_; + delete par; + } + } + 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; + np = par->next(); delete par; while(np) { par = np; - np = np->next; + np = np->next(); delete par; } } 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; + 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::SetText(string const & data) +{ + clear(); + LyXFont font(LyXFont::ALL_SANE); + for(unsigned int i=0; i < data.length(); ++i) + par->InsertChar(i, data[i], font); +} + + void InsetText::SetAutoBreakRows(bool flag) { if (flag != autoBreakRows) { autoBreakRows = flag; need_update = FULL; + if (!flag) + removeNewlines(); } } @@ -1191,21 +1614,29 @@ LyXFont InsetText::GetDrawFont(BufferView * bv, LyXParagraph * p, int pos) const } #endif + int InsetText::cx(BufferView * bv) const { - return TEXT(bv)->cursor.x() + top_x + 1; + 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; } int InsetText::cy(BufferView * bv) const { - long int y_dummy = 0; - Row * tmprow = TEXT(bv)->GetRowNearY(y_dummy); - return TEXT(bv)->cursor.y() - tmprow->baseline(); + LyXFont font; + return TEXT(bv)->cursor.y() - ascent(bv, font) + TEXT_TO_INSET_OFFSET; } -int InsetText::cpos(BufferView * bv) const +LyXParagraph::size_type InsetText::cpos(BufferView * bv) const { return TEXT(bv)->cursor.pos(); } @@ -1216,6 +1647,11 @@ LyXParagraph * InsetText::cpar(BufferView * bv) const return TEXT(bv)->cursor.par(); } +bool InsetText::cboundary(BufferView * bv) const +{ + return TEXT(bv)->cursor.boundary(); +} + Row * InsetText::crow(BufferView * bv) const { @@ -1223,26 +1659,141 @@ Row * InsetText::crow(BufferView * bv) const } -LyXText * InsetText::getLyXText(BufferView * bv) const +LyXText * InsetText::getLyXText(BufferView const * lbv, bool const recursive) const { - if (cache.find(bv) != cache.end()) + // 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); + lt->SetCursor(bv, inset_par, inset_pos, true, inset_boundary); + if (recursive) + return the_locking_inset->getLyXText(bv); } return lt; } -void InsetText::deleteLyXText(BufferView * bv) const +void InsetText::deleteLyXText(BufferView * bv, bool recursive) const { + if ((cache.find(bv) == cache.end()) || !cache[bv]) + return; + delete cache[bv]; cache.erase(bv); - /// then remove all LyXText in text-insets - LyXParagraph * p = par; - for(;p;p = p->next) { + 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::resizeLyXText(BufferView * bv) const +{ +#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::removeNewlines() +{ +#ifndef NEW_INSETS + for (LyXParagraph * p = par; p; p = p->next_) { +#else + for (LyXParagraph * p = par; p; p = p->next()) { +#endif + for (int i = 0; i < p->Last(); ++i) { + if (p->GetChar(i) == LyXParagraph::META_NEWLINE) + p->Erase(i); + } } }