X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettext.C;h=a1f98b51634c6bc2a35215c4e8b531167776bfec;hb=716cd578ae8def1b71b806bbf15c21e1dfa9a1fc;hp=cf3c5805e35016a8d640323aa6ed523c77708038;hpb=4ad21513e9dfd8d0b8c557e6d850d9bf3234c1e1;p=lyx.git diff --git a/src/insets/insettext.C b/src/insets/insettext.C index cf3c5805e3..a1f98b5163 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -6,8 +6,6 @@ * * Copyright 1998-2000 The LyX Team. * - * @author: Jürgen Vigna - * * ====================================================== */ @@ -48,6 +46,7 @@ #include "intl.h" #include "trans_mgr.h" #include "lyxscreen.h" +#include "WorkArea.h" using std::ostream; using std::ifstream; @@ -56,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() { @@ -80,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; @@ -107,6 +114,12 @@ void InsetText::init(InsetText const * ins) 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; + } LyXParagraph * p = par->next; delete par; while(p) { @@ -119,6 +132,12 @@ InsetText::~InsetText() 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; + } LyXParagraph * p = par->next; delete par; while(p) { @@ -130,7 +149,7 @@ void InsetText::clear() } -Inset * InsetText::Clone() const +Inset * InsetText::Clone(Buffer const &) const { InsetText * t = new InsetText(*this); return t; @@ -162,6 +181,13 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex) #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; + } + LyXParagraph * p = par->next; delete par; while(p) { @@ -208,7 +234,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; @@ -217,7 +243,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; @@ -227,7 +253,8 @@ 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; } @@ -262,8 +289,10 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, 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==FULL) || (top_baseline!=baseline))) + { int w = insetWidth; int h = insetAscent + insetDescent; int ty = baseline - insetAscent; @@ -284,6 +313,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, return; if (top_x != int(x)) { +// printf("InsetText::draw1 -> INIT(%d)\n",insetWidth); need_update = INIT; top_x = int(x); bv->text->status = LyXText::CHANGED_IN_DRAW; @@ -305,30 +335,49 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, return; } x += TEXT_TO_INSET_OFFSET; - long int y = 0; - Row * row = TEXT(bv)->GetRowNearY(y); - y += baseline - row->ascent_of_text(); - if (cleared || !locked || (need_update == FULL)) { - while (row != 0) { - TEXT(bv)->GetVisibleRow(bv, y, int(x), row, y, cleared); + { + 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(TEXT(bv), y, int(x)); - } else { - locked = false; - if (need_update == CURSOR) { - bv->screen()->ToggleSelection(TEXT(bv), true, y, int(x)); - TEXT(bv)->ClearSelection(); - TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + if (y_offset < 0) + y_offset = y; + TEXT(bv)->first = first; + if (cleared || !locked || (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 (need_update == SELECTION) { + bv->screen()->ToggleToggle(TEXT(bv), bv, y_offset, int(x)); + } else { + locked = false; + if (need_update == CURSOR) { + bv->screen()->ToggleSelection(TEXT(bv), bv, true, y_offset,int(x)); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; + } + bv->screen()->Update(TEXT(bv), bv, y_offset, int(x)); + locked = true; } - bv->screen()->Update(TEXT(bv), y, int(x)); - locked = true; } TEXT(bv)->refresh_y = 0; TEXT(bv)->status = LyXText::UNCHANGED; - if ((drawFrame == ALWAYS) || ((drawFrame == LOCKED) && locked)) { + 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); @@ -339,7 +388,10 @@ void InsetText::draw(BufferView * bv, LyXFont const & f, } x += width(bv, f) - TEXT_TO_INSET_OFFSET; if (bv->text->status==LyXText::CHANGED_IN_DRAW) + { need_update = INIT; +// printf("InsetText::draw2 -> INIT(%d)\n",insetWidth); + } else if (need_update != INIT) need_update = NONE; } @@ -362,8 +414,6 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) if (need_update == INIT) { resizeLyXText(bv); need_update = FULL; -// if (!owner() && bv->text) -// bv->text->UpdateInset(bv, this); } int oldw = insetWidth; #if 1 @@ -381,20 +431,7 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) // textWidth(bv->painter()),static_cast(TEXT(bv)->width)); resizeLyXText(bv); need_update = FULL; -#if 0 - if (owner()) { - owner()->update(bv, font, reinit); - return; - } else { - update(bv, font, reinit); - } -#else -#if 1 update(bv, font, reinit); -#else - UpdateLocal(bv, INIT, false); -#endif -#endif return; } if ((need_update==CURSOR_PAR) && (TEXT(bv)->status==LyXText::UNCHANGED) && @@ -406,7 +443,7 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) 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() + @@ -416,6 +453,8 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit) void InsetText::UpdateLocal(BufferView * bv, UpdateCodes what, bool mark_dirty) { +// if (what == INIT) +// printf("InsetText::UpdateLocal -> INIT(%d)\n",insetWidth); TEXT(bv)->FullRebreak(bv); if (need_update != INIT) { if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH) @@ -434,7 +473,7 @@ void InsetText::UpdateLocal(BufferView * bv, UpdateCodes what, bool mark_dirty) } -char const * InsetText::EditMessage() const +string const InsetText::EditMessage() const { return _("Opened Text Inset"); } @@ -452,14 +491,24 @@ 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)->first+insetAscent); + 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. + if (par->Last() == 0 && !par->next) { + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(bv->getParentLanguage(this)); + SetFont(bv, font, false); + } } @@ -494,6 +543,7 @@ bool InsetText::LockInsetInInset(BufferView * bv, UpdatableInset * inset) inset_y = cy(bv) + drawTextYOffset; inset_pos = cpos(bv); inset_par = cpar(bv); + inset_boundary = cboundary(bv); TEXT(bv)->UpdateInset(bv, the_locking_inset); return true; } else if (the_locking_inset && (the_locking_inset == inset)) { @@ -557,7 +607,7 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) no_selection = false; int tmp_x = x - drawTextXOffset; - 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); @@ -570,6 +620,7 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) 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) { @@ -581,15 +632,18 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) 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); +// TEXT(bv)->ClearSelection(); if (the_locking_inset) { UpdateLocal(bv, CURSOR_PAR, false); } @@ -597,12 +651,26 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button) } } 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); } @@ -644,7 +712,7 @@ void InsetText::InsetMotionNotify(BufferView * bv, int x, int y, int state) if (!no_selection) { HideInsetCursor(bv); TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset, - y+TEXT(bv)->first+insetAscent); + y+insetAscent); TEXT(bv)->SetSelection(); if (TEXT(bv)->toggle_cursor.par()!=TEXT(bv)->toggle_end_cursor.par() || TEXT(bv)->toggle_cursor.pos()!=TEXT(bv)->toggle_end_cursor.pos()) @@ -687,23 +755,33 @@ 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; } 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")); @@ -725,6 +803,7 @@ InsetText::LocalDispatch(BufferView * bv, bv->text->cursor.par()->next #endif ); + bv->setState(); if (lyxrc.auto_region_delete) { if (TEXT(bv)->selection){ TEXT(bv)->CutSelection(bv, false); @@ -732,32 +811,52 @@ InsetText::LocalDispatch(BufferView * bv, } TEXT(bv)->ClearSelection(); 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])) { +#if 0 + bv->owner()->getIntl()->getTrans()->TranslateAndInsert(arg[i], TEXT(bv)); +#else + bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], TEXT(bv)); +#endif + } else if (!the_locking_inset) { + (void)moveRight(bv, false); + } + } else { +#if 0 + bv->owner()->getIntl()->getTrans()->TranslateAndInsert(arg[i], TEXT(bv)); +#else + bv->owner()->getIntl()->getTrans().TranslateAndInsert(arg[i], TEXT(bv)); +#endif + } } } UpdateLocal(bv, CURSOR_PAR, true); + result=DISPATCHED_NOUPDATE; break; // --- Cursor Movements --------------------------------------------- case LFUN_RIGHTSEL: bv->text->FinishUndo(); - moveRight(bv, false); + moveRight(bv, false, true); TEXT(bv)->SetSelection(); UpdateLocal(bv, SELECTION, false); break; case LFUN_RIGHT: result = moveRight(bv); bv->text->FinishUndo(); + TEXT(bv)->ClearSelection(); UpdateLocal(bv, CURSOR, false); break; case LFUN_LEFTSEL: bv->text->FinishUndo(); - moveLeft(bv, false); + moveLeft(bv, false, true); TEXT(bv)->SetSelection(); UpdateLocal(bv, SELECTION, false); break; case LFUN_LEFT: bv->text->FinishUndo(); - result= moveLeft(bv); + result = moveLeft(bv); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_DOWNSEL: @@ -769,6 +868,8 @@ InsetText::LocalDispatch(BufferView * bv, case LFUN_DOWN: bv->text->FinishUndo(); result = moveDown(bv); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_UPSEL: @@ -780,15 +881,21 @@ InsetText::LocalDispatch(BufferView * bv, case LFUN_UP: bv->text->FinishUndo(); result = moveUp(bv); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_HOME: bv->text->FinishUndo(); TEXT(bv)->CursorHome(bv); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_END: TEXT(bv)->CursorEnd(bv); + TEXT(bv)->ClearSelection(); + TEXT(bv)->sel_cursor = TEXT(bv)->cursor; UpdateLocal(bv, CURSOR, false); break; case LFUN_BACKSPACE: @@ -801,7 +908,10 @@ InsetText::LocalDispatch(BufferView * bv, bv->text->cursor.par()->next #endif ); - TEXT(bv)->Backspace(bv); + if (TEXT(bv)->selection) + TEXT(bv)->CutSelection(bv); + else + TEXT(bv)->Backspace(bv); UpdateLocal(bv, CURSOR_PAR, true); break; case LFUN_DELETE: @@ -814,7 +924,10 @@ InsetText::LocalDispatch(BufferView * bv, bv->text->cursor.par()->next #endif ); - TEXT(bv)->Delete(bv); + if (TEXT(bv)->selection) + TEXT(bv)->CutSelection(bv); + else + TEXT(bv)->Delete(bv); UpdateLocal(bv, CURSOR_PAR, true); break; case LFUN_CUT: @@ -835,6 +948,20 @@ 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: if (!autoBreakRows) { CutAndPaste cap; @@ -864,6 +991,12 @@ 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; @@ -880,40 +1013,44 @@ InsetText::LocalDispatch(BufferView * bv, 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); + 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()); - UpdateLocal(bv, CURSOR_PAR, true); } - } - 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 @@ -926,11 +1063,7 @@ InsetText::LocalDispatch(BufferView * bv, cur_value = par->spacing.getValue(); } -#ifdef HAVE_SSTREAM std::istringstream istr(arg.c_str()); -#else - istrstream istr(arg.c_str()); -#endif string tmp; istr >> tmp; Spacing::Space new_spacing = cur_spacing; @@ -986,6 +1119,38 @@ 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; + p = p->next; + } + 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); + p = p->next; + } + + return lines; +} + + void InsetText::Validate(LaTeXFeatures & features) const { LyXParagraph * p = par; @@ -1006,14 +1171,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; @@ -1042,7 +1208,7 @@ void InsetText::ToggleInsetCursor(BufferView * bv) } -void InsetText::ShowInsetCursor(BufferView * bv) +void InsetText::ShowInsetCursor(BufferView * bv, bool show) { if (the_locking_inset) { the_locking_inset->ShowInsetCursor(bv); @@ -1055,7 +1221,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; } } @@ -1073,24 +1240,45 @@ 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())) return FINISHED; - if (activate_inset && checkAndActivateInset(bv, false)) + if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; - TEXT(bv)->CursorRight(bv); + TEXT(bv)->CursorRight(bv, selecting); 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)) return FINISHED; - TEXT(bv)->CursorLeft(bv); - if (activate_inset && checkAndActivateInset(bv, true)) + TEXT(bv)->CursorLeft(bv, selecting); + if (activate_inset && checkAndActivateInset(bv, behind)) return DISPATCHED; return DISPATCHED_NOUPDATE; } @@ -1132,14 +1320,16 @@ bool InsetText::InsertInset(BufferView * bv, Inset * inset) bv->text->cursor.par()->next #endif ); - if (inset->Editable() == Inset::IS_EDITABLE) { - UpdatableInset * i = static_cast(inset); - i->setOwner(static_cast(this)); - } + inset->setOwner(this); + HideInsetCursor(bv); TEXT(bv)->InsertInset(bv, inset); + if ((cpar(bv)->GetChar(cpos(bv)) != LyXParagraph::META_INSET) || + (cpar(bv)->GetInset(cpos(bv)) != inset)) + TEXT(bv)->CursorLeft(bv); TEXT(bv)->selection = 0; + bv->fitCursor(TEXT(bv)); UpdateLocal(bv, CURSOR_PAR, true); - static_cast(inset)->Edit(bv, 0, 0, 0); + ShowInsetCursor(bv); return true; } @@ -1162,28 +1352,42 @@ UpdatableInset * InsetText::GetFirstLockingInsetOfType(Inset::Code c) void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) { + 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); @@ -1196,9 +1400,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) @@ -1235,8 +1439,14 @@ int InsetText::getMaxWidth(Painter & pain, UpdatableInset const * inset) const 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; + } + LyXParagraph * np; if (par) { np = par->next; delete par; @@ -1260,6 +1470,15 @@ void InsetText::SetParagraphData(LyXParagraph *p) } +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) { @@ -1297,9 +1516,18 @@ LyXFont InsetText::GetDrawFont(BufferView * bv, LyXParagraph * p, int pos) const } #endif + int InsetText::cx(BufferView * bv) const { - return TEXT(bv)->cursor.x() + top_x + TEXT_TO_INSET_OFFSET; + 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; } @@ -1310,7 +1538,7 @@ int InsetText::cy(BufferView * bv) const } -int InsetText::cpos(BufferView * bv) const +LyXParagraph::size_type InsetText::cpos(BufferView * bv) const { return TEXT(bv)->cursor.pos(); } @@ -1321,6 +1549,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 { @@ -1328,15 +1561,18 @@ Row * InsetText::crow(BufferView * bv) const } -LyXText * InsetText::getLyXText(BufferView * bv) const +LyXText * InsetText::getLyXText(BufferView const * lbv) const { - if (cache.find(bv) != cache.end()) + // Super UGLY! (Lgb) + BufferView * bv = const_cast(lbv); + + if ((cache.find(bv) != cache.end()) && cache[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); } return lt; } @@ -1344,42 +1580,54 @@ LyXText * InsetText::getLyXText(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); if (recursive) { /// then remove all LyXText in text-insets LyXParagraph * p = par; - for(;p;p = p->next) { + for (;p;p = p->next) { p->deleteInsetsLyXText(bv); } } } + void InsetText::resizeLyXText(BufferView * bv) const { if (!par->next && !par->size()) // resize not neccessary! return; - if (cache.find(bv) == cache.end()) + if ((cache.find(bv) == cache.end()) || !cache[bv]) return; LyXParagraph * lpar = 0; LyXParagraph * selstartpar = 0; LyXParagraph * selendpar = 0; - int pos = 0; - int selstartpos = 0; - int selendpos = 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); - lpar = TEXT(bv)->cursor.par(); - pos = TEXT(bv)->cursor.pos(); - selstartpar = TEXT(bv)->sel_start_cursor.par(); - selstartpos = TEXT(bv)->sel_start_cursor.pos(); - selendpar = TEXT(bv)->sel_end_cursor.par(); - selendpos = TEXT(bv)->sel_end_cursor.pos(); - selection = TEXT(bv)->selection; - mark_set = TEXT(bv)->mark_set; + 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) { @@ -1388,13 +1636,14 @@ void InsetText::resizeLyXText(BufferView * bv) const * Mechanism when setting the cursor */ TEXT(bv)->mark_set = mark_set; if (selection) { - TEXT(bv)->SetCursor(bv, selstartpar, selstartpos); + TEXT(bv)->SetCursor(bv, selstartpar, selstartpos,true, + selstartboundary); TEXT(bv)->sel_cursor = TEXT(bv)->cursor; - TEXT(bv)->SetCursor(bv, selendpar, selendpos); + TEXT(bv)->SetCursor(bv, selendpar, selendpos, true, selendboundary); TEXT(bv)->SetSelection(); TEXT(bv)->SetCursor(bv, lpar, pos); } else { - TEXT(bv)->SetCursor(bv, lpar, pos); + TEXT(bv)->SetCursor(bv, lpar, pos, true, boundary); TEXT(bv)->sel_cursor = TEXT(bv)->cursor; TEXT(bv)->selection = false; } @@ -1408,8 +1657,7 @@ void InsetText::resizeLyXText(BufferView * bv) const /// then resize all LyXText in text-insets inset_x = cx(bv) - top_x + drawTextXOffset; inset_y = cy(bv) + drawTextYOffset; - LyXParagraph * p = par; - for(;p;p = p->next) { + for (LyXParagraph * p = par; p; p = p->next) { p->resizeInsetsLyXText(bv); } } @@ -1419,10 +1667,8 @@ void InsetText::resizeLyXText(BufferView * bv) const void InsetText::removeNewlines() { - LyXParagraph * p = par; - - for(;p; p = p->next) { - for(int i = 0; i < p->Last(); ++i) { + for (LyXParagraph * p = par; p; p = p->next) { + for (int i = 0; i < p->Last(); ++i) { if (p->GetChar(i) == LyXParagraph::META_NEWLINE) p->Erase(i); }