]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insettext.C
Changed drawing of button in InsetCollapsable and some Mouse/Curosor fixes.
[lyx.git] / src / insets / insettext.C
index 218521efbca3099c49124d38e9ab77fca011af5a..833eb64c621b705b31d4007e9b76d99bc5ebb9a1 100644 (file)
@@ -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()
 {
@@ -107,6 +109,7 @@ void InsetText::init(InsetText const * ins)
     frame_color = LColor::insetframe;
     locked = false;
     old_par = 0;
+    last_drawn_width = -1;
 }
 
 
@@ -118,13 +121,23 @@ InsetText::~InsetText()
        delete (*cit).second;
        (*cit).second = 0;
     }
-    LyXParagraph * p = par->next;
+#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
 }
 
 
@@ -136,13 +149,23 @@ void InsetText::clear()
        delete (*cit).second;
        (*cit).second = 0;
     }
-    LyXParagraph * p = par->next;
+#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();
 }
 
@@ -186,13 +209,23 @@ void InsetText::Read(Buffer const * buf, LyXLex & lex)
        (*cit).second = 0;
     }
 
-    LyXParagraph * p = par->next;
+#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
     par = new LyXParagraph;
     while (lex.IsOK()) {
         lex.nextToken();
@@ -219,7 +252,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") {
@@ -251,14 +288,15 @@ 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);
+    int const w = getMaxWidth(pain, this);
     return w;
 }
 
@@ -270,7 +308,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f,
 
     // no draw is necessary !!!
     if ((drawFrame == LOCKED) && !locked && !par->size()) {
-       if (!cleared && (need_update == CLEAR_FRAME)) {
+       if (!cleared && (need_update & CLEAR_FRAME)) {
            pain.rectangle(top_x + 1, baseline - insetAscent + 1,
                           width(bv, f) - 1,
                           insetAscent + insetDescent - 1,
@@ -286,8 +324,16 @@ 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))) {
+    // 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;
@@ -313,6 +359,10 @@ void InsetText::draw(BufferView * bv, LyXFont const & f,
        bv->text->status = LyXText::CHANGED_IN_DRAW;
        return;
     }
+    if (cleared || (last_drawn_width != insetWidth)) {
+       need_update |= FULL;
+       last_drawn_width = insetWidth;
+    }
 
     top_baseline = baseline;
     top_y = baseline - ascent(bv, f);
@@ -344,7 +394,7 @@ void InsetText::draw(BufferView * bv, LyXFont const & f,
        if (y_offset < 0)
            y_offset = y;
        TEXT(bv)->first = first;
-       if (cleared || !locked || (need_update == FULL)) {
+       if (cleared) { // (need_update&FULL) || (need_update&INIT)
            int yf = y_offset;
            y = 0;
            while ((row != 0) && (yf < ph)) {
@@ -354,16 +404,23 @@ void InsetText::draw(BufferView * bv, LyXFont const & f,
                yf += row->height();
                row = row->next();
            }
-       } else if (need_update == SELECTION) {
-           bv->screen()->ToggleToggle(TEXT(bv), y_offset, int(x));
+       } 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 == CURSOR) {
-               bv->screen()->ToggleSelection(TEXT(bv), true, y_offset,int(x));
-               TEXT(bv)->ClearSelection();
+           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), y_offset, int(x));
+           bv->screen()->Update(TEXT(bv), bv, y_offset, int(x));
            locked = true;
        }
     }
@@ -375,15 +432,15 @@ void InsetText::draw(BufferView * bv, LyXFont const & f,
            pain.rectangle(top_x + 1, baseline - insetAscent + 1,
                           width(bv, f) - 1, insetAscent + insetDescent - 1,
                           frame_color);
-    } else if (need_update == CLEAR_FRAME) {
+    } 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)
+    if (bv->text->status==LyXText::CHANGED_IN_DRAW) {
        need_update = INIT;
-    else if (need_update != INIT)
+    else if (need_update != INIT)
        need_update = NONE;
 }
 
@@ -441,16 +498,23 @@ void InsetText::update(BufferView * bv, LyXFont const & font, bool reinit)
        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 (need_update != INIT) {
-       if (TEXT(bv)->status == LyXText::NEED_MORE_REFRESH)
-           need_update = FULL;
-       else if (!the_locking_inset || (what != CURSOR))
-           need_update = what;
-    }
+    SetUpdateStatus(bv, what);
     if ((need_update != CURSOR) || (TEXT(bv)->status != LyXText::UNCHANGED) ||
        TEXT(bv)->selection)
            bv->updateInset(this, mark_dirty);
@@ -480,6 +544,7 @@ 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))
@@ -489,6 +554,18 @@ void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button)
     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->size() == 0 && !par->next()) {
+#endif
+       LyXFont font(LyXFont::ALL_IGNORE);
+       font.setLanguage(bv->getParentLanguage(this));
+       SetFont(bv, font, false);
+    }
 }
 
 
@@ -501,8 +578,7 @@ void InsetText::InsetUnlock(BufferView * bv)
     HideInsetCursor(bv);
     no_selection = false;
     locked = false;
-    TEXT(bv)->selection = 0;
-    UpdateLocal(bv, CLEAR_FRAME, false);
+    UpdateLocal(bv, CLEAR_FRAME|CURSOR, false);
     if (owner())
            bv->owner()->setLayout(owner()->getLyXText(bv)
                                    ->cursor.par()->GetLayout());
@@ -523,7 +599,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) {
@@ -567,7 +650,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);
@@ -583,7 +666,7 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset)
 
 void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
 {
-    no_selection = false;
+    no_selection = true;
 
     int tmp_x = x - drawTextXOffset;
     int tmp_y = y + insetAscent - TEXT(bv)->first;
@@ -593,6 +676,7 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
     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
@@ -602,9 +686,9 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
            the_locking_inset = static_cast<UpdatableInset*>(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);
-           }
+           if (the_locking_inset)
+               UpdateLocal(bv, CURSOR, false);
+           no_selection = false;
            return;
        }
        // otherwise only unlock the_locking_inset
@@ -618,17 +702,17 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
            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);
-           }
+           if (the_locking_inset)
+               UpdateLocal(bv, CURSOR, false);
+           no_selection = false;
            return;
        }
     }
-    if (!inset) {
+    if (!inset && (button == 2)) {
        bool paste_internally = false;
        if ((button == 2) && TEXT(bv)->selection) {
            LocalDispatch(bv, LFUN_COPY, "");
@@ -651,6 +735,7 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
        }
     }
     ShowInsetCursor(bv);
+    no_selection = false;
 }
 
 
@@ -682,22 +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) {
-       HideInsetCursor(bv);
-       TEXT(bv)->SetCursorFromCoordinates(bv, x-drawTextXOffset,
-                                          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())
-           UpdateLocal(bv, SELECTION, 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);
 }
 
 
@@ -712,7 +796,7 @@ 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
@@ -733,25 +817,36 @@ InsetText::LocalDispatch(BufferView * bv,
            UpdateLocal(bv, CURSOR_PAR, false);
             return result;
         } else if (result == FINISHED) {
+           bool dispatched = false;
            switch (action) {
-           case -1:
+           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;
        }
@@ -764,40 +859,33 @@ InsetText::LocalDispatch(BufferView * bv,
 
            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
+                             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
+                             bv->text->cursor.par()->previous(),
+                             bv->text->cursor.par()->next()
 #endif
                    );
-           // if an empty paragraph set the language to the surronding
-           // paragraph language on insertion of the first character!
-           if (!par->Last() && !par->next) {
-               LyXText * text = 0;
-               if (owner()) {
-                   Inset * inset = owner();
-                   while(inset && inset->getLyXText(bv) == TEXT(bv))
-                       inset = inset->owner();
-                   if (inset)
-                       text = inset->getLyXText(bv);
-               }
-               if (!text)
-                   text = bv->text;
-               LyXFont font(LyXFont::ALL_IGNORE);
-               font.setLanguage(text->cursor.par()->getParLanguage(bv->buffer()->params));
-               SetFont(bv, font, false);
-           }
+           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;
@@ -805,75 +893,64 @@ InsetText::LocalDispatch(BufferView * bv,
     case LFUN_RIGHTSEL:
        bv->text->FinishUndo();
        moveRight(bv, false, true);
-       TEXT(bv)->SetSelection();
+       TEXT(bv)->SetSelection(bv);
        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, true);
-       TEXT(bv)->SetSelection();
+       TEXT(bv)->SetSelection(bv);
        UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_LEFT:
        bv->text->FinishUndo();
-       result= moveLeft(bv);
-       TEXT(bv)->ClearSelection();
-       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)->ClearSelection();
-       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)->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:
        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
+         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
+         bv->text->cursor.par()->previous(),
+         bv->text->cursor.par()->next()
 #endif
                );
        if (TEXT(bv)->selection)
@@ -885,11 +962,11 @@ InsetText::LocalDispatch(BufferView * bv,
     case LFUN_DELETE:
        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
+         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
+         bv->text->cursor.par()->previous(),
+         bv->text->cursor.par()->next()
 #endif
                );
        if (TEXT(bv)->selection)
@@ -901,11 +978,11 @@ InsetText::LocalDispatch(BufferView * bv,
     case LFUN_CUT:
        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
+         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
+         bv->text->cursor.par()->previous(),
+         bv->text->cursor.par()->next()
 #endif
                );
        TEXT(bv)->CutSelection(bv);
@@ -943,11 +1020,11 @@ InsetText::LocalDispatch(BufferView * bv,
        }
        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
+         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
+         bv->text->cursor.par()->previous(),
+         bv->text->cursor.par()->next()
 #endif
                );
        TEXT(bv)->PasteSelection(bv);
@@ -959,16 +1036,22 @@ 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,
 #ifndef NEW_INSETS
-           bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
-           bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
+           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
+           bv->text->cursor.par()->previous(),
+           bv->text->cursor.par()->next()
 #endif
                );
        TEXT(bv)->InsertChar(bv, LyXParagraph::META_NEWLINE);
@@ -1019,10 +1102,10 @@ InsetText::LocalDispatch(BufferView * bv,
            // 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();
            }
                        
            std::istringstream istr(arg.c_str());
@@ -1053,7 +1136,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);
@@ -1062,9 +1145,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->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
@@ -1091,7 +1188,11 @@ int InsetText::Ascii(Buffer const * buf, ostream & os, int linelen) const
        tmp = buf->asciiParagraph(p, linelen);
        lines += countChar(tmp, '\n');
        os << tmp;
-       p = p->next;
+#ifndef NEW_INSETS
+       p = p->next();
+#else
+       p = p->next();
+#endif
     }
     return lines;
 }
@@ -1106,7 +1207,11 @@ int InsetText::DocBook(Buffer const * buf, ostream & os) const
     string tmp;
     while (p) {
        buf->SimpleDocBookOnePar(os,tmp,p,desc,0);
-       p = p->next;
+#ifndef NEW_INSETS
+       p = p->next_;
+#else
+       p = p->next();
+#endif
     }
     
     return lines;
@@ -1118,7 +1223,11 @@ 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
     }
 }
 
@@ -1204,22 +1313,55 @@ void InsetText::HideInsetCursor(BufferView * bv)
 UpdatableInset::RESULT
 InsetText::moveRight(BufferView * bv, bool activate_inset, bool selecting)
 {
-    if (!cpar(bv)->next && (cpos(bv) >= cpar(bv)->Last()))
+    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)
+{
+#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, false))
+    if (activate_inset && checkAndActivateInset(bv, behind))
        return DISPATCHED;
-    TEXT(bv)->CursorRight(bv, selecting);
+    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, bool selecting)
+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, selecting);
-    if (activate_inset && checkAndActivateInset(bv, true))
+    TEXT(bv)->CursorLeft(bv);
+    if (!selecting)
+           TEXT(bv)->sel_cursor = TEXT(bv)->cursor;
+    if (activate_inset && checkAndActivateInset(bv, behind))
        return DISPATCHED;
     return DISPATCHED_NOUPDATE;
 }
@@ -1254,22 +1396,23 @@ bool InsetText::InsertInset(BufferView * bv, Inset * inset)
     }
     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
+             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
+             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);
-    TEXT(bv)->selection = 0;
+#endif
     bv->fitCursor(TEXT(bv));
-    UpdateLocal(bv, CURSOR_PAR, true);
+    UpdateLocal(bv, CURSOR_PAR|CURSOR, true);
     ShowInsetCursor(bv);
     return true;
 }
@@ -1291,17 +1434,27 @@ 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)
 {
-    bv->text->SetUndo(bv->buffer(), Undo::EDIT,
+    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
+                         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
+                         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);
@@ -1321,13 +1474,14 @@ bool InsetText::checkAndActivateInset(BufferView * bv, bool behind)
                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, xy, 0);
        if (!the_locking_inset)
            return false;
        UpdateLocal(bv, CURSOR_PAR, false);
@@ -1340,9 +1494,11 @@ bool InsetText::checkAndActivateInset(BufferView * bv, bool behind)
 bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y,
                                      int button)
 {
-    x = x - drawTextXOffset;
-    y = y + insetAscent;
-    Inset * inset = bv->checkInsetHit(TEXT(bv), x, y, 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)
@@ -1377,7 +1533,7 @@ int InsetText::getMaxWidth(Painter & pain, UpdatableInset const * inset) const
 }
 
 
-void InsetText::SetParagraphData(LyXParagraph *p)
+void InsetText::SetParagraphData(LyXParagraph * p)
 {
     // delete all instances of LyXText before deleting the paragraps used
     // by it.
@@ -1386,30 +1542,62 @@ void InsetText::SetParagraphData(LyXParagraph *p)
        (*cit).second = 0;
     }
 
+#ifndef NEW_INSETS
     LyXParagraph * np;
     if (par) {
-       np = par->next;
+       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();
        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) {
@@ -1450,7 +1638,15 @@ LyXFont InsetText::GetDrawFont(BufferView * bv, LyXParagraph * p, int pos) const
 
 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;
 }
 
 
@@ -1472,6 +1668,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
 {
@@ -1479,15 +1680,23 @@ 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()) && cache[bv])
+    // Super UGLY! (Lgb)
+    BufferView * bv = const_cast<BufferView *>(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<InsetText *>(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;
 }
@@ -1502,16 +1711,26 @@ void InsetText::deleteLyXText(BufferView * bv, bool recursive) const
     if (recursive) {
        /// then remove all LyXText in text-insets
        LyXParagraph * p = par;
-       for (;p;p = p->next) {
+#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
 {
-    if (!par->next && !par->size()) // resize not neccessary!
+#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;
@@ -1522,6 +1741,9 @@ void InsetText::resizeLyXText(BufferView * bv) const
     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;
 
@@ -1530,10 +1752,13 @@ void InsetText::resizeLyXText(BufferView * bv) const
     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;
     }
@@ -1545,13 +1770,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)->SetSelection();
+           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);
+           TEXT(bv)->SetCursor(bv, lpar, pos, true, boundary);
            TEXT(bv)->sel_cursor = TEXT(bv)->cursor;
            TEXT(bv)->selection = false;
        }
@@ -1565,9 +1791,15 @@ 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;
-       for (LyXParagraph * p = par; p; p = p->next) {
+#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;
 }
@@ -1575,8 +1807,13 @@ void InsetText::resizeLyXText(BufferView * bv) const
 
 void InsetText::removeNewlines()
 {
-    for (LyXParagraph * p = par; p; p = p->next) {
+#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);
        }