]> git.lyx.org Git - features.git/blobdiff - src/text2.C
clear()->erase() ; lots of using directives for cxx
[features.git] / src / text2.C
index d151ef37dec59e69ed7ddddf3f31a3ba8d4cf6a4..16ac40d0a53f0100b8de8bcfbe9bcfd09c278c98 100644 (file)
@@ -4,13 +4,12 @@
  *           LyX, The Document Processor
  *      
  *           Copyright 1995 Matthias Ettrich
- *           Copyright 1995-1999 The LyX Team.
+ *           Copyright 1995-2000 The LyX Team.
  *
  * ====================================================== */
 
 #include <config.h>
 
-#include <cctype>
 #include FORMS_H_LOCATION
 
 
@@ -22,6 +21,7 @@
 #include "lyxparagraph.h"
 #include "insets/inseterror.h"
 #include "insets/insetbib.h"
+#include "insets/insetspecialchar.h"
 #include "layout.h"
 #include "LyXView.h"
 #include "support/textutils.h"
 #include "BufferView.h"
 #include "LyXView.h"
 #include "lyxrow.h"
+#include "CutAndPaste.h"
+#include "Painter.h"
+#include "font.h"
+#include "debug.h"
 
-#define FIX_DOUBLE_SPACE 1
+//#define USE_OLD_CUT_AND_PASTE 1
 
 using std::copy;
+using std::endl;
+using std::pair;
 
 LyXText::LyXText(BufferView * bv, int pw, Buffer * p)
 {
        owner_ = bv;
        firstrow = 0;
        lastrow = 0;
-       currentrow = 0;
-       currentrow_y = 0;
        paperwidth = pw;
-       parameters = &p->params;
-       params = p;
+       buffer = p;
        number_of_rows = 0;
        refresh_y = 0;
        status = LyXText::UNCHANGED;
@@ -81,6 +84,22 @@ LyXText::LyXText(BufferView * bv, int pw, Buffer * p)
 
        // Default layouttype for copy environment type
        copylayouttype = 0;
+
+#if 0
+       // Dump all rowinformation:
+       Row * tmprow = firstrow;
+       lyxerr << "Baseline Paragraph Pos Height Ascent Fill\n";
+       while (tmprow) {
+               lyxerr << tmprow->baseline << '\t'
+                      << tmprow->par << '\t'
+                      << tmprow->pos << '\t'
+                      << tmprow->height << '\t'
+                      << tmprow->ascent_of_text << '\t'
+                      << tmprow->fill << '\n';
+               tmprow = tmprow->next;
+       }
+       lyxerr.flush();
+#endif
 }
 
 
@@ -113,7 +132,8 @@ LyXFont LyXText::GetFont(LyXParagraph * par,
                         LyXParagraph::size_type pos) const
 {
        LyXLayout const & layout = 
-               textclasslist.Style(parameters->textclass, par->GetLayout());
+               textclasslist.Style(buffer->params.textclass,
+                                   par->GetLayout());
 
        char par_depth = par->GetDepth();
        // We specialize the 95% common case:
@@ -167,13 +187,13 @@ LyXFont LyXText::GetFont(LyXParagraph * par,
                par = par->DepthHook(par_depth - 1);
                if (par) {
                        tmpfont.realize(textclasslist.
-                                       Style(parameters->textclass,
+                                       Style(buffer->params.textclass,
                                              par->GetLayout()).font);
                        par_depth = par->GetDepth();
                }
        }
 
-       tmpfont.realize(textclasslist.TextClass(parameters->textclass).defaultfont());
+       tmpfont.realize(textclasslist.TextClass(buffer->params.textclass).defaultfont());
 
        // Cosmetic improvement: If this is an open footnote, make the font 
        // smaller.
@@ -197,8 +217,9 @@ void LyXText::SetCharFont(LyXParagraph * par,
                        font = par->GetInset(pos)->ConvertFont(font);
        }
 
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass,
-                                          par->GetLayout());
+       LyXLayout const & layout =
+               textclasslist.Style(buffer->params.textclass,
+                                   par->GetLayout());
 
        // Get concrete layout font to reduce against
        LyXFont layoutfont;
@@ -215,12 +236,12 @@ void LyXText::SetCharFont(LyXParagraph * par,
                        tp = tp->DepthHook(tp->GetDepth()-1);
                        if (tp)
                                layoutfont.realize(textclasslist.
-                                               Style(parameters->textclass,
+                                               Style(buffer->params.textclass,
                                                      tp->GetLayout()).font);
                }
        }
 
-       layoutfont.realize(textclasslist.TextClass(parameters->textclass).defaultfont());
+       layoutfont.realize(textclasslist.TextClass(buffer->params.textclass).defaultfont());
 
        if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
            && par->footnotekind == LyXParagraph::FOOTNOTE) {
@@ -274,11 +295,6 @@ void LyXText::RemoveRow(Row * row) const
           row of this row */
        long unused_y;
        GetRow(row->par, row->pos, unused_y);
-       currentrow = currentrow->previous;
-       if (currentrow)
-               currentrow_y -= currentrow->height;
-       else
-               currentrow_y = 0;
    
        if (row->next)
                row->next->previous = row->previous;
@@ -355,7 +371,7 @@ void LyXText::OpenStuff()
                 && cursor.par->GetInset(cursor.pos)->Editable()) {
                owner_->owner()->getMiniBuffer()
                        ->Set(cursor.par->GetInset(cursor.pos)->EditMessage());
-               if (cursor.par->GetInset(cursor.pos)->Editable() != 2)
+               if (cursor.par->GetInset(cursor.pos)->Editable() != Inset::HIGHLY_EDITABLE)
                        SetCursorParUndo();
                cursor.par->GetInset(cursor.pos)->Edit(owner_, 0, 0, 0);
        } else {
@@ -390,7 +406,7 @@ void LyXText::CloseFootnote()
                // now the cursor is at the beginning of the physical par
                SetCursor(cursor.par,
                          cursor.pos +
-                         cursor.par->ParFromPos(cursor.pos)->text.size());
+                         cursor.par->ParFromPos(cursor.pos)->size());
        } else  {
                /* we are in a footnote, so let us move at the beginning */ 
                /* this is just faster than using just CursorLeft() */ 
@@ -439,11 +455,12 @@ void LyXText::CloseFootnote()
 // Asger is not sure we want to do this...
 void LyXText::MakeFontEntriesLayoutSpecific(LyXParagraph * par)
 {
-       LyXFont layoutfont, tmpfont;
    
        LyXLayout const & layout =
-               textclasslist.Style(parameters->textclass, par->GetLayout());
+               textclasslist.Style(buffer->params.textclass,
+                                   par->GetLayout());
 
+       LyXFont layoutfont, tmpfont;
        for (LyXParagraph::size_type pos = 0;
             pos < par->Last(); ++pos) {
                if (pos < BeginningOfMainBody(par))
@@ -457,12 +474,78 @@ void LyXText::MakeFontEntriesLayoutSpecific(LyXParagraph * par)
        }
 }
 
+LyXParagraph * LyXText::SetLayout(LyXCursor & cur, LyXCursor & sstart_cur,
+                                 LyXCursor & send_cur,
+                                 LyXTextClass::size_type layout)
+{
+       LyXParagraph * endpar = send_cur.par->LastPhysicalPar()->Next();
+       LyXParagraph * undoendpar = endpar;
+
+       if (endpar && endpar->GetDepth()) {
+               while (endpar && endpar->GetDepth()) {
+                       endpar = endpar->LastPhysicalPar()->Next();
+                       undoendpar = endpar;
+               }
+       } else if (endpar) {
+               endpar = endpar->Next(); // because of parindents etc.
+       }
+   
+       SetUndo(Undo::EDIT,
+               sstart_cur.par->ParFromPos(sstart_cur.pos)->previous, 
+               undoendpar);
+
+       /* ok we have a selection. This is always between sstart_cur
+        * and sel_end cursor */ 
+       cur = sstart_cur;
+   
+       LyXLayout const & lyxlayout =
+               textclasslist.Style(buffer->params.textclass, layout);
+   
+       while (cur.par != send_cur.par) {
+               if (cur.par->footnoteflag == sstart_cur.par->footnoteflag) {
+                       cur.par->SetLayout(layout);
+                       MakeFontEntriesLayoutSpecific(cur.par);
+                       LyXParagraph* fppar = cur.par->FirstPhysicalPar();
+                       fppar->added_space_top = lyxlayout.fill_top ?
+                               VSpace(VSpace::VFILL) : VSpace(VSpace::NONE);
+                       fppar->added_space_bottom = lyxlayout.fill_bottom ? 
+                               VSpace(VSpace::VFILL) : VSpace(VSpace::NONE); 
+                       if (lyxlayout.margintype == MARGIN_MANUAL)
+                               cur.par->SetLabelWidthString(lyxlayout.labelstring());
+                       if (lyxlayout.labeltype != LABEL_BIBLIO
+                           && fppar->bibkey) {
+                               delete fppar->bibkey;
+                               fppar->bibkey = 0;
+                       }
+               }
+               cur.par = cur.par->Next();
+       }
+       if (cur.par->footnoteflag == sstart_cur.par->footnoteflag) {
+               cur.par->SetLayout(layout);
+               MakeFontEntriesLayoutSpecific(cur.par);
+               LyXParagraph* fppar = cur.par->FirstPhysicalPar();
+               fppar->added_space_top = lyxlayout.fill_top ?
+                       VSpace(VSpace::VFILL) : VSpace(VSpace::NONE);
+               fppar->added_space_bottom = lyxlayout.fill_bottom ? 
+                       VSpace(VSpace::VFILL) : VSpace(VSpace::NONE); 
+               if (lyxlayout.margintype == MARGIN_MANUAL)
+                       cur.par->SetLabelWidthString(lyxlayout.labelstring());
+               if (lyxlayout.labeltype != LABEL_BIBLIO
+                   && fppar->bibkey) {
+                       delete fppar->bibkey;
+                       fppar->bibkey = 0;
+               }
+       }
+       return endpar;
+}
 
 // set layout over selection and make a total rebreak of those paragraphs
-void  LyXText::SetLayout(char layout)
+void LyXText::SetLayout(LyXTextClass::size_type layout)
 {
-       LyXCursor tmpcursor;
+       LyXCursor
+               tmpcursor = cursor;  /* store the current cursor  */
 
+#ifdef USE_OLD_SET_LAYOUT
        // if there is no selection just set the layout
        // of the current paragraph  */
        if (!selection) {
@@ -487,14 +570,12 @@ void  LyXText::SetLayout(char layout)
                sel_start_cursor.par->ParFromPos(sel_start_cursor.pos)->previous, 
                undoendpar);
 
-       tmpcursor = cursor;                    /* store the current cursor  */
-
        /* ok we have a selection. This is always between sel_start_cursor
         * and sel_end cursor */ 
        cursor = sel_start_cursor;
    
        LyXLayout const & lyxlayout =
-               textclasslist.Style(parameters->textclass, layout);
+               textclasslist.Style(buffer->params.textclass, layout);
    
        while (cursor.par != sel_end_cursor.par) {
                if (cursor.par->footnoteflag ==
@@ -533,18 +614,27 @@ void  LyXText::SetLayout(char layout)
                        fppar->bibkey = 0;
                }
        }
-   
+#else
+       // if there is no selection just set the layout
+       // of the current paragraph  */
+       if (!selection) {
+               sel_start_cursor = cursor;  // dummy selection
+               sel_end_cursor = cursor;
+       }
+       LyXParagraph *
+       endpar = SetLayout(cursor, sel_start_cursor, sel_end_cursor, layout);
+#endif
        RedoParagraphs(sel_start_cursor, endpar);
    
        // we have to reset the selection, because the
        // geometry could have changed */ 
-       SetCursor(sel_start_cursor.par, sel_start_cursor.pos);
+       SetCursor(sel_start_cursor.par, sel_start_cursor.pos, false);
        sel_cursor = cursor;
-       SetCursor(sel_end_cursor.par, sel_end_cursor.pos);
+       SetCursor(sel_end_cursor.par, sel_end_cursor.pos, false);
        UpdateCounters(cursor.row);
        ClearSelection();
        SetSelection();
-       SetCursor(tmpcursor.par, tmpcursor.pos);
+       SetCursor(tmpcursor.par, tmpcursor.pos, true);
 }
 
 
@@ -589,7 +679,7 @@ void  LyXText::IncDepth()
                // NOTE: you can't change the depth of a bibliography entry
                if (cursor.par->footnoteflag ==
                    sel_start_cursor.par->footnoteflag
-                   && textclasslist.Style(parameters->textclass,
+                   && textclasslist.Style(buffer->params.textclass,
                                      cursor.par->GetLayout()
                                     ).labeltype != LABEL_BIBLIO) {
                        LyXParagraph * prev =
@@ -597,7 +687,7 @@ void  LyXText::IncDepth()
                        if (prev 
                            && (prev->GetDepth() - cursor.par->GetDepth() > 0
                                || (prev->GetDepth() == cursor.par->GetDepth()
-                                   && textclasslist.Style(parameters->textclass,
+                                   && textclasslist.Style(buffer->params.textclass,
                                                      prev->GetLayout()).isEnvironment()))) {
                                cursor.par->FirstPhysicalPar()->depth++;
                                anything_changed = true;
@@ -694,7 +784,7 @@ void  LyXText::DecDepth()
 
 
 // set font over selection and make a total rebreak of those paragraphs
-void  LyXText::SetFont(LyXFont const & font, bool toggleall)
+void LyXText::SetFont(LyXFont const & font, bool toggleall)
 {
        // if there is no selection just set the current_font
        if (!selection) {
@@ -705,7 +795,9 @@ void  LyXText::SetFont(LyXFont const & font, bool toggleall)
                else
                        layoutfont = GetFont(cursor.par, -1);
                // Update current font
-               real_current_font.update(font, toggleall);
+               real_current_font.update(font,
+                                        buffer->params.language_info,
+                                        toggleall);
 
                // Reduce to implicit settings
                current_font = real_current_font;
@@ -734,7 +826,9 @@ void  LyXText::SetFont(LyXFont const & font, bool toggleall)
                        // an open footnote should behave
                        // like a closed one
                        LyXFont newfont = GetFont(cursor.par, cursor.pos);
-                       newfont.update(font, toggleall);
+                       newfont.update(font,
+                                      buffer->params.language_info,
+                                      toggleall);
                        SetCharFont(cursor.par, cursor.pos, newfont);
                        cursor.pos++;
                } else {
@@ -832,8 +926,8 @@ void LyXText::RedoParagraphs(LyXCursor const & cur,
                first_phys_par = tmprow->par->FirstPhysicalPar();
                // find the first row of the paragraph
                if (first_phys_par != tmprow->par)
-                       while (tmprow->previous
-                              && tmprow->previous->par != first_phys_par) {
+                       while (tmprow->previous &&
+                              (tmprow->previous->par != first_phys_par)) {
                                tmprow = tmprow->previous;
                                y -= tmprow->height;
                        }
@@ -897,14 +991,14 @@ void LyXText::RedoParagraphs(LyXCursor const & cur,
 }
 
 
-int LyXText::FullRebreak()
+bool LyXText::FullRebreak()
 {
        if (need_break_row) {
                BreakAgain(need_break_row);
                need_break_row = 0;
-               return 1;
+               return true;
        }
-       return 0;
+       return false;
 }
 
 
@@ -924,7 +1018,7 @@ void LyXText::SetSelection()
                sel_end_cursor = sel_cursor;
        }
    
-       selection = True;
+       selection = true;
    
        // first the toggling area
        if (cursor.y < last_sel_cursor.y ||
@@ -1028,38 +1122,21 @@ void  LyXText::CursorBottom() const
    
 /* returns a pointer to the row near the specified y-coordinate
 * (relative to the whole text). y is set to the real beginning
-* of this row */ 
+* of this row */
 Row * LyXText::GetRowNearY(long & y) const
 {
-       Row * tmprow;
-       long tmpy;
-   
-       if (currentrow) {
-               tmprow = currentrow;
-               tmpy = currentrow_y;
-       } else {
-               tmprow = firstrow;
-               tmpy = 0;
-       }
-
-       if (tmpy <= y)
-               while (tmprow->next && tmpy + tmprow->height <= y) {
-                       tmpy += tmprow->height;
-                       tmprow = tmprow->next;
-               }
-       else
-               while (tmprow->previous && tmpy > y) {
-                       tmprow = tmprow->previous;
-                       tmpy -= tmprow->height;
-               }
+       Row * tmprow = firstrow;
+       long tmpy = 0;
 
-       currentrow = tmprow;
-       currentrow_y = tmpy;
+       while (tmprow->next && tmpy + tmprow->height <= y) {
+               tmpy += tmprow->height;
+               tmprow = tmprow->next;
+       }
 
        y = tmpy;   // return the real y
        return tmprow;
 }
-   
+
 
 void LyXText::ToggleFree(LyXFont const & font, bool toggleall)
 {
@@ -1073,8 +1150,11 @@ void LyXText::ToggleFree(LyXFont const & font, bool toggleall)
        }
 
        // Try implicit word selection
+       // If there is a change in the language the implicit word selection 
+       // is disabled.
        LyXCursor resetCursor = cursor;
-       int implicitSelection = SelectWordWhenUnderCursor();
+       bool implicitSelection = (font.language() == ignore_language)
+               ? SelectWordWhenUnderCursor() : false;
 
        // Set font
        SetFont(font, toggleall);
@@ -1092,7 +1172,7 @@ void LyXText::ToggleFree(LyXFont const & font, bool toggleall)
 
 LyXParagraph::size_type LyXText::BeginningOfMainBody(LyXParagraph * par) const
 {
-       if (textclasslist.Style(parameters->textclass,
+       if (textclasslist.Style(buffer->params.textclass,
                                par->GetLayout()).labeltype != LABEL_MANUAL)
                return 0;
        else
@@ -1128,7 +1208,7 @@ void LyXText::MeltFootnoteEnvironment()
        tmppar = firsttmppar;
        /* tmppar is now the paragraph right before the footnote */
 
-       char first_footnote_par_is_not_empty = tmppar->next->text.size();
+       bool first_footnote_par_is_not_empty = tmppar->next->size();
    
        while (tmppar->next
               && tmppar->next->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
@@ -1139,7 +1219,7 @@ void LyXText::MeltFootnoteEnvironment()
                tmppar->footnoteflag = LyXParagraph::NO_FOOTNOTE;
       
                /* remember the captions and empty paragraphs */
-               if ((textclasslist.Style(parameters->textclass,
+               if ((textclasslist.Style(buffer->params.textclass,
                                         tmppar->GetLayout())
                     .labeltype == LABEL_SENSITIVE)
                    || !tmppar->Last())
@@ -1172,8 +1252,8 @@ void LyXText::MeltFootnoteEnvironment()
         * (only if the previous par and the footnotepar are not empty!) */
        if ((!firsttmppar->next->GetLayout() && !firsttmppar->next->table)
            || firsttmppar->HasSameLayout(firsttmppar->next)) {
-               if (firsttmppar->text.size()
-                   && !firsttmppar->IsSeparator(firsttmppar->text.size() - 1)
+               if (firsttmppar->size()
+                   && !firsttmppar->IsSeparator(firsttmppar->size() - 1)
                    && first_footnote_par_is_not_empty) {
                        firsttmppar->next->InsertChar(0, ' ');
                }
@@ -1253,13 +1333,13 @@ void LyXText::SetParagraph(bool line_top, bool line_bottom,
                        // does the layout allow the new alignment?
                        if (align == LYX_ALIGN_LAYOUT)
                                align = textclasslist
-                                       .Style(parameters->textclass,
+                                       .Style(buffer->params.textclass,
                                               cursor.par->GetLayout()).align;
                        if (align & textclasslist
-                           .Style(parameters->textclass,
+                           .Style(buffer->params.textclass,
                                   cursor.par->GetLayout()).alignpossible) {
                                if (align == textclasslist
-                                   .Style(parameters->textclass,
+                                   .Style(buffer->params.textclass,
                                           cursor.par->GetLayout()).align)
                                        cursor.par->align = LYX_ALIGN_LAYOUT;
                                else
@@ -1347,19 +1427,48 @@ void LyXText::SetParagraphExtraOpt(int type,
 }
 
 
-static char const * alphaCounter(int n) {
-       static char result[2];
-       result[1] = 0;
-       if (n == 0)
-               return "";
-       else {
-               result[0] = 'A' + n;
-               if (n > 'Z')
-                       return "??";
-       }
-       return result;
+char loweralphaCounter(int n)
+{
+       if (n < 1 || n > 26)
+               return '?';
+       else
+               return 'a' + n - 1;
 }
 
+char alphaCounter(int n)
+{
+       if (n < 1 || n > 26)
+               return '?';
+       else
+               return 'A' + n - 1;
+}
+
+char hebrewCounter(int n)
+{
+       static const char hebrew[22] = {
+               'à', 'á', 'â', 'ã', 'ä', 'Ã¥', 'æ', 'ç', 'è',
+               'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö', 
+               '÷', 'ø', 'ù', 'ú'
+       };
+       if (n < 1 || n > 22)
+               return '?';
+       else
+               return hebrew[n-1];
+}
+
+static char const * romanCounter(int n)
+{
+       static char const * roman[20] = {
+               "i",   "ii",  "iii", "iv", "v",
+               "vi",  "vii", "viii", "ix", "x",
+               "xi",  "xii", "xiii", "xiv", "xv",
+               "xvi", "xvii", "xviii", "xix", "xx"
+       };
+       if (n < 1 || n > 20)
+               return "??";
+       else
+               return roman[n-1];
+}
 
 // set the counter of a paragraph. This includes the labels
 void LyXText::SetCounter(LyXParagraph * par) const
@@ -1367,11 +1476,12 @@ void LyXText::SetCounter(LyXParagraph * par) const
        // this is only relevant for the beginning of paragraph
        par = par->FirstPhysicalPar();
 
-       LyXLayout const & layout = textclasslist.Style(parameters->textclass, 
-                                                      par->GetLayout());
+       LyXLayout const & layout =
+               textclasslist.Style(buffer->params.textclass, 
+                                   par->GetLayout());
 
        LyXTextClass const & textclass =
-               textclasslist.TextClass(parameters->textclass);
+               textclasslist.TextClass(buffer->params.textclass);
 
        /* copy the prev-counters to this one, unless this is the start of a 
           footnote or of a bibliography or the very first paragraph */
@@ -1379,7 +1489,7 @@ void LyXText::SetCounter(LyXParagraph * par) const
            && !(par->Previous()->footnoteflag == LyXParagraph::NO_FOOTNOTE 
                    && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
                    && par->footnotekind == LyXParagraph::FOOTNOTE)
-           && !(textclasslist.Style(parameters->textclass,
+           && !(textclasslist.Style(buffer->params.textclass,
                                par->Previous()->GetLayout()
                                ).labeltype != LABEL_BIBLIO
                 && layout.labeltype == LABEL_BIBLIO)) {
@@ -1414,7 +1524,7 @@ void LyXText::SetCounter(LyXParagraph * par) const
            && par->Previous()
            && par->Previous()->footnoteflag != LyXParagraph::OPEN_FOOTNOTE
            && (par->PreviousBeforeFootnote()
-               && textclasslist.Style(parameters->textclass,
+               && textclasslist.Style(buffer->params.textclass,
                                  par->PreviousBeforeFootnote()->GetLayout()
                                 ).labeltype >= LABEL_COUNTER_ENUMI)) {
                 // Any itemize or enumerate environment in a marginnote
@@ -1436,7 +1546,7 @@ void LyXText::SetCounter(LyXParagraph * par) const
         */
        if (par->Previous()
            && par->Previous()->GetDepth() < par->GetDepth()
-           && textclasslist.Style(parameters->textclass,
+           && textclasslist.Style(buffer->params.textclass,
                              par->Previous()->GetLayout()
                             ).labeltype == LABEL_COUNTER_ENUMI
            && par->enumdepth < 3
@@ -1465,15 +1575,14 @@ void LyXText::SetCounter(LyXParagraph * par) const
        }
    
        if (!par->labelstring.empty()) {
-               par->labelstring.clear();
+               par->labelstring.erase();
        }
    
        if (layout.margintype == MARGIN_MANUAL) {
                if (par->labelwidthstring.empty()) {
                        par->SetLabelWidthString(layout.labelstring());
                }
-       }
-       else {
+       } else {
                par->SetLabelWidthString(string());
        }
    
@@ -1481,120 +1590,157 @@ void LyXText::SetCounter(LyXParagraph * par) const
        if (layout.labeltype >=  LABEL_FIRST_COUNTER) {
       
                int i = layout.labeltype - LABEL_FIRST_COUNTER;
-               if (i >= 0 && i<= parameters->secnumdepth) {
+               if (i >= 0 && i<= buffer->params.secnumdepth) {
                        par->incCounter(i);     // increment the counter  
         
-                       char * s = new char[50];
-
                        // Is there a label? Useful for Chapter layout
                        if (!par->appendix){
                                if (!layout.labelstring().empty())
                                        par->labelstring = layout.labelstring();
                                else
-                                       par->labelstring.clear();
+                                       par->labelstring.erase();
                         } else {
                                if (!layout.labelstring_appendix().empty())
                                        par->labelstring = layout.labelstring_appendix();
                                else
-                                       par->labelstring.clear();
+                                       par->labelstring.erase();
                        }
-                       if (!par->appendix){
+
+#ifdef HAVE_SSTREAM
+                       std::ostringstream s;
+#else
+                       ostrstream s;
+#endif
+                       if (!par->appendix) {
                                switch (2 * LABEL_FIRST_COUNTER -
                                        textclass.maxcounter() + i) {
                                case LABEL_COUNTER_CHAPTER:
-                                       sprintf(s, "%d",
-                                               par->getCounter(i));
+                                       s << par->getCounter(i);
                                        break;
                                case LABEL_COUNTER_SECTION:
-                                       sprintf(s, "%d.%d",
-                                               par->getCounter(i - 1),
-                                               par->getCounter(i));
+                                       s << par->getCounter(i - 1) << '.'
+                                          << par->getCounter(i);
                                        break;
                                case LABEL_COUNTER_SUBSECTION:
-                                       sprintf(s, "%d.%d.%d",
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       s << par->getCounter(i - 2) << '.'
+                                         << par->getCounter(i - 1) << '.'
+                                         << par->getCounter(i);
                                        break;
                                case LABEL_COUNTER_SUBSUBSECTION:
-                                       sprintf(s, "%d.%d.%d.%d",
-                                               par->getCounter(i-3),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       s << par->getCounter(i - 3) << '.'
+                                         << par->getCounter(i - 2) << '.'
+                                         << par->getCounter(i - 1) << '.'
+                                         << par->getCounter(i);
+                                       
                                        break;
                                case LABEL_COUNTER_PARAGRAPH:
-                                       sprintf(s, "%d.%d.%d.%d.%d",
-                                               par->getCounter(i-4),
-                                               par->getCounter(i-3),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       s << par->getCounter(i - 4) << '.'
+                                         << par->getCounter(i - 3) << '.'
+                                         << par->getCounter(i - 2) << '.'
+                                         << par->getCounter(i - 1) << '.'
+                                         << par->getCounter(i);
                                        break;
                                case LABEL_COUNTER_SUBPARAGRAPH:
-                                       sprintf(s, "%d.%d.%d.%d.%d.%d",
-                                               par->getCounter(i-5),
-                                               par->getCounter(i-4),
-                                               par->getCounter(i-3),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       s << par->getCounter(i - 5) << '.'
+                                         << par->getCounter(i - 4) << '.'
+                                         << par->getCounter(i - 3) << '.'
+                                         << par->getCounter(i - 2) << '.'
+                                         << par->getCounter(i - 1) << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                default:
-                                       sprintf(s, "%d.", par->getCounter(i));
+                                       s << par->getCounter(i) << '.';
                                         break;
                                }
-                       } else {
+                       } else { // appendix
                                switch (2 * LABEL_FIRST_COUNTER - textclass.maxcounter() + i) {
                                case LABEL_COUNTER_CHAPTER:
-                                       sprintf(s, "%s",
-                                               alphaCounter(par->getCounter(i)));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i));
+                                       else
+                                               s << alphaCounter(par->getCounter(i));
                                        break;
                                case LABEL_COUNTER_SECTION:
-                                       sprintf(s, "%s.%d",
-                                               alphaCounter(par->getCounter(i - 1)),
-                                               par->getCounter(i));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i - 1));
+                                       else
+                                               s << alphaCounter(par->getCounter(i - 1));
+
+                                       s << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                case LABEL_COUNTER_SUBSECTION:
-                                       sprintf(s, "%s.%d.%d",
-                                               alphaCounter(par->getCounter(i-2)),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i - 2));
+                                       else
+                                               s << alphaCounter(par->getCounter(i - 2));
+
+                                       s << '.'
+                                         << par->getCounter(i-1) << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                case LABEL_COUNTER_SUBSUBSECTION:
-                                       sprintf(s, "%s.%d.%d.%d",
-                                               alphaCounter(par->getCounter(i-3)),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i-3));
+                                       else
+                                               s << alphaCounter(par->getCounter(i-3));
+
+                                       s << '.'
+                                         << par->getCounter(i-2) << '.'
+                                         << par->getCounter(i-1) << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                case LABEL_COUNTER_PARAGRAPH:
-                                       sprintf(s, "%s.%d.%d.%d.%d",
-                                               alphaCounter(par->getCounter(i-4)),
-                                               par->getCounter(i-3),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i-4));
+                                       else
+                                               s << alphaCounter(par->getCounter(i-4));
+
+                                       s << '.'
+                                         << par->getCounter(i-3) << '.'
+                                         << par->getCounter(i-2) << '.'
+                                         << par->getCounter(i-1) << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                case LABEL_COUNTER_SUBPARAGRAPH:
-                                       sprintf(s, "%s.%d.%d.%d.%d.%d",
-                                               alphaCounter(par->getCounter(i-5)),
-                                               par->getCounter(i-4),
-                                               par->getCounter(i-3),
-                                               par->getCounter(i-2),
-                                               par->getCounter(i-1),
-                                               par->getCounter(i));
+                                       if (par->isRightToLeftPar())
+                                               s << hebrewCounter(par->getCounter(i-5));
+                                       else
+                                               s << alphaCounter(par->getCounter(i-5));
+
+                                       s << '.'
+                                         << par->getCounter(i-4) << '.'
+                                         << par->getCounter(i-3) << '.'
+                                         << par->getCounter(i-2) << '.'
+                                         << par->getCounter(i-1) << '.'
+                                         << par->getCounter(i);
+
                                        break;
                                default:
-                                       sprintf(s, "%c.", par->getCounter(i));
+                                       // Can this ever be reached? And in the
+                                       // case it is, how can this be correct?
+                                       // (Lgb)
+                                       s << static_cast<unsigned char>(par->getCounter(i)) << '.';
+                                       
                                        break;
                                }
                        }
-        
-                       par->labelstring += s;
-                       delete[] s;
-        
+#ifdef HAVE_SSTREAM
+                       par->labelstring += s.str().c_str();
+                       // We really want to remove the c_str as soon as
+                       // possible...
+#else
+                       s << '\0';
+                       char * tmps = s.str();
+                       par->labelstring += tmps;
+                       delete [] tmps;
+#endif
+                       
                        for (i++; i < 10; ++i) {
                                // reset the following counters
                                par->setCounter(i, 0);
@@ -1606,49 +1752,54 @@ void LyXText::SetCounter(LyXParagraph * par) const
                        }
                } else if (layout.labeltype == LABEL_COUNTER_ENUMI) {
                        par->incCounter(i + par->enumdepth);
-                       char * s = new char[25];
                        int number = par->getCounter(i + par->enumdepth);
 
-                       static const char *roman[20] = {
-                               "i",   "ii",  "iii", "iv", "v",
-                               "vi",  "vii", "viii", "ix", "x",
-                               "xi",  "xii", "xiii", "xiv", "xv",
-                               "xvi", "xvii", "xviii", "xix", "xx"
-                       };
-                       static const char hebrew[22] = {
-                               'à', 'á', 'â', 'ã', 'ä', 'Ã¥', 'æ', 'ç', 'è',
-                               'é', 'ë', 'ì', 'î', 'ð', 'ñ', 'ò', 'ô', 'ö', 
-                               '÷', 'ø', 'ù', 'ú'
-                       };
-
+#ifdef HAVE_SSTREAM
+                       std::ostringstream s;
+#else
+                       ostrstream s;
+#endif
                        switch (par->enumdepth) {
                        case 1:
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       sprintf(s, "(%c)", ((number-1) % 26) + 'a');
+                               if (par->isRightToLeftPar())
+                                       s << '('
+                                         << hebrewCounter(number)
+                                         << ')';
                                else
-                                       sprintf(s, "(%c)", hebrew[(number-1) % 22]);
+                                       s << '('
+                                         << loweralphaCounter(number)
+                                         << ')';
                                break;
                        case 2:
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       sprintf(s, "%s.", roman[(number-1) % 20]);
+                               if (par->isRightToLeftPar())
+                                       s << '.' << romanCounter(number);
                                else
-                                       sprintf(s, ".%s", roman[(number-1) % 20]);
+                                       s << romanCounter(number) << '.';
                                break;
                        case 3:
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       sprintf(s, "%c.", ((number-1) % 26) + 'A');
+                               if (par->isRightToLeftPar())
+                                       s << '.'
+                                         << alphaCounter(number);
                                else
-                                       sprintf(s, ".%c", ((number-1) % 26) + 'A');
+                                       s << alphaCounter(number)
+                                         << '.';
                                break;
                        default:
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       sprintf(s, "%d.", number);
+                               if (par->isRightToLeftPar())
+                                       s << '.' << number;
                                else
-                                       sprintf(s, ".%d", number);      
+                                       s << number << '.';
                                break;
                        }
-                       par->labelstring = s;
-                       delete[] s;
+#ifdef HAVE_SSTREAM
+                       par->labelstring = s.str().c_str();
+                       // we really want to get rid of that c_str()
+#else
+                       s << '\0';
+                       char * tmps = s.str();
+                       par->labelstring = tmps;
+                       delete [] tmps;
+#endif
 
                        for (i += par->enumdepth + 1; i < 10; ++i)
                                par->setCounter(i, 0);  /* reset the following counters  */
@@ -1673,31 +1824,22 @@ void LyXText::SetCounter(LyXParagraph * par) const
                        if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                            && (par->footnotekind == LyXParagraph::FIG
                                || par->footnotekind == LyXParagraph::WIDE_FIG))
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       s = "Figure:";
-                               else
-                                       s = ":øåéà";
+                               s = (par->getParLanguage()->lang == "hebrew")
+                                       ? ":øåéà" : "Figure:";
                        else if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                                 && (par->footnotekind == LyXParagraph::TAB
                                     || par->footnotekind == LyXParagraph::WIDE_TAB))
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       s = "Table:";
-                               else
-                                       s = ":äìáè";
+                               s = (par->getParLanguage()->lang == "hebrew")
+                                       ? ":äìáè" : "Table:";
                        else if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE
                                 && par->footnotekind == LyXParagraph::ALGORITHM)
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       s = "Algorithm:";
-                               else
-                                       s = ":íúéøåâìà";
+                               s = (par->getParLanguage()->lang == "hebrew")
+                                       ? ":íúéøåâìà" : "Algorithm:";
                        else {
                                /* par->SetLayout(0); 
                                   s = layout->labelstring;  */
-                               if (par->getParDirection() == LYX_DIR_LEFT_TO_RIGHT)
-                                       s = "Senseless: ";
-                               else
-                                       s = " :úåòîùî Ã¸Ã±Ã§";
-          
+                               s = (par->getParLanguage()->lang == "hebrew")
+                                       ? " :úåòîùî Ã¸Ã±Ã§" : "Senseless: ";
                        }
                }
                par->labelstring = s;
@@ -1737,9 +1879,11 @@ void LyXText::UpdateCounters(Row * row) const
                /* now  check for the headline layouts. remember that they
                 * have a dynamic left margin */ 
                if (!par->IsDummy()
-                   && ( textclasslist.Style(parameters->textclass, par->layout).margintype == MARGIN_DYNAMIC
-                        || textclasslist.Style(parameters->textclass, par->layout).labeltype == LABEL_SENSITIVE)
-                       ){
+                   && ( textclasslist.Style(buffer->params.textclass,
+                                            par->layout).margintype == MARGIN_DYNAMIC
+                        || textclasslist.Style(buffer->params.textclass,
+                                               par->layout).labeltype == LABEL_SENSITIVE)
+                       ) {
         
                        /* Rebreak the paragraph */ 
                        RemoveParagraph(row);
@@ -1768,6 +1912,8 @@ void LyXText::UpdateCounters(Row * row) const
 /* insets an inset. */ 
 void LyXText::InsertInset(Inset *inset)
 {
+       if (!cursor.par->InsertInsetAllowed(inset))
+               return;
        SetUndo(Undo::INSERT, 
                cursor.par->ParFromPos(cursor.pos)->previous, 
                cursor.par->ParFromPos(cursor.pos)->next);
@@ -1779,6 +1925,7 @@ void LyXText::InsertInset(Inset *inset)
 }
 
 
+#ifdef USE_OLD_CUT_AND_PASTE
 // this is for the simple cut and paste mechanism
 static LyXParagraph * simple_cut_buffer = 0;
 static char simple_cut_buffer_textclass = 0;
@@ -1796,7 +1943,7 @@ void DeleteSimpleCutBuffer()
        }
        simple_cut_buffer = 0;
 }
-
+#endif
 
 void LyXText::copyEnvironmentType()
 {
@@ -1809,7 +1956,7 @@ void LyXText::pasteEnvironmentType()
        SetLayout(copylayouttype);
 }
 
-
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::CutSelection(bool doclear)
 {
        // This doesn't make sense, if there is no selection
@@ -1869,7 +2016,7 @@ void LyXText::CutSelection(bool doclear)
        DeleteSimpleCutBuffer();
    
        // set the textclass
-       simple_cut_buffer_textclass = parameters->textclass;
+       simple_cut_buffer_textclass = buffer->params.textclass;
 
 #ifdef WITH_WARNINGS
 #warning Asger: Make cut more intelligent here.
@@ -1914,22 +2061,6 @@ void LyXText::CutSelection(bool doclear)
           (Lgb)
        */
 
-#ifndef FIX_DOUBLE_SPACE
-       bool space_wrapped =
-               sel_end_cursor.par->IsLineSeparator(sel_end_cursor.pos);
-       if (sel_end_cursor.pos > 0
-           && sel_end_cursor.par->IsLineSeparator(sel_end_cursor.pos - 1)) {
-               // please break before a space at the end
-               sel_end_cursor.pos--;
-               space_wrapped = true;
-       }
-       // cut behind a space if there is one
-       while (sel_start_cursor.par->Last() > sel_start_cursor.pos
-              && sel_start_cursor.par->IsLineSeparator(sel_start_cursor.pos)
-              && (sel_start_cursor.par != sel_end_cursor.par
-                  || sel_start_cursor.pos < sel_end_cursor.pos))
-               sel_start_cursor.pos++; 
-#endif
        // there are two cases: cut only within one paragraph or
        // more than one paragraph
    
@@ -1952,55 +2083,19 @@ void LyXText::CutSelection(bool doclear)
                        }
                        simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
                }
-#ifndef FIX_DOUBLE_SPACE
-               // check for double spaces
-               if (sel_start_cursor.pos &&
-                   sel_start_cursor.par->Last() > sel_start_cursor.pos
-                   && sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos - 1)
-                   && sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos)) {
-                       sel_start_cursor.par->Erase(sel_start_cursor.pos);
-               }
-               if (space_wrapped)
-                       simple_cut_buffer->InsertChar(i - sel_start_cursor.pos,
-                                                     ' ');
-#endif
                endpar = sel_end_cursor.par->Next();
        } else {
                // cut more than one paragraph
    
                sel_end_cursor.par
                        ->BreakParagraphConservative(sel_end_cursor.pos);
-#ifndef FIX_DOUBLE_SPACE
-               // insert a space at the end if there was one
-               if (space_wrapped)
-                       sel_end_cursor.par
-                               ->InsertChar(sel_end_cursor.par->Last(), ' ');
-#endif
                sel_end_cursor.par = sel_end_cursor.par->Next();
                sel_end_cursor.pos = 0;
    
                cursor = sel_end_cursor;
 
-#ifndef FIX_DOUBLE_SPACE
-               // please break behind a space, if there is one.
-               // The space should be copied too
-               if (sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos))
-                       sel_start_cursor.pos++;
-#endif   
                sel_start_cursor.par
                        ->BreakParagraphConservative(sel_start_cursor.pos);
-#ifndef FIX_DOUBLE_SPACE
-               if (!sel_start_cursor.pos
-                   || sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos - 1)
-                   || sel_start_cursor.par
-                   ->IsNewline(sel_start_cursor.pos - 1)) {
-                       sel_start_cursor.par->Next()->InsertChar(0, ' ');
-               }
-#endif
                // store the endparagraph for redoing later
                endpar = sel_end_cursor.par->Next(); /* needed because
                                                        the sel_end_
@@ -2039,17 +2134,6 @@ void LyXText::CutSelection(bool doclear)
                    || 
                    !sel_start_cursor.par->Next()->Last())
                        sel_start_cursor.par->ParFromPos(sel_start_cursor.pos)->PasteParagraph();
-
-#ifndef FIX_DOUBLE_SPACE
-               // maybe a forgotten blank
-               if (sel_start_cursor.pos 
-                   && sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos)
-                   && sel_start_cursor.par
-                   ->IsLineSeparator(sel_start_cursor.pos - 1)) {
-                       sel_start_cursor.par->Erase(sel_start_cursor.pos);
-               }
-#endif
        }
 
        // sometimes necessary
@@ -2065,7 +2149,98 @@ void LyXText::CutSelection(bool doclear)
        UpdateCounters(cursor.row);
 }
 
+#else ///////////////////////////////////////////////////////////////////
+
+void LyXText::CutSelection(bool doclear)
+{
+    // This doesn't make sense, if there is no selection
+    if (!selection)
+       return;
+   
+    // OK, we have a selection. This is always between sel_start_cursor
+    // and sel_end cursor
+    LyXParagraph * tmppar;
+    
+    // Check whether there are half footnotes in the selection
+    if (sel_start_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
+       || sel_end_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+       tmppar = sel_start_cursor.par;
+       while (tmppar != sel_end_cursor.par){
+           if (tmppar->footnoteflag != sel_end_cursor.par->footnoteflag) {
+               WriteAlert(_("Impossible operation"),
+                          _("Don't know what to do with half floats."),
+                          _("sorry."));
+               return;
+                       }
+           tmppar = tmppar->Next();
+       }
+    }
+    
+    /* table stuff -- begin */
+    if (sel_start_cursor.par->table || sel_end_cursor.par->table) {
+       if ( sel_start_cursor.par != sel_end_cursor.par) {
+           WriteAlert(_("Impossible operation"),
+                      _("Don't know what to do with half tables."),
+                      _("sorry."));
+           return;
+       }
+       sel_start_cursor.par->table->Reinit();
+    }
+    /* table stuff -- end */
+    
+    // make sure that the depth behind the selection are restored, too
+    LyXParagraph * endpar = sel_end_cursor.par->LastPhysicalPar()->Next();
+    LyXParagraph * undoendpar = endpar;
+    
+    if (endpar && endpar->GetDepth()) {
+       while (endpar && endpar->GetDepth()) {
+           endpar = endpar->LastPhysicalPar()->Next();
+           undoendpar = endpar;
+       }
+    } else if (endpar) {
+       endpar = endpar->Next(); // because of parindents etc.
+    }
+    
+    SetUndo(Undo::DELETE, sel_start_cursor
+           .par->ParFromPos(sel_start_cursor.pos)->previous, undoendpar);
+    
+    CutAndPaste cap;
+
+    // there are two cases: cut only within one paragraph or
+    // more than one paragraph
+    if (sel_start_cursor.par->ParFromPos(sel_start_cursor.pos) 
+       == sel_end_cursor.par->ParFromPos(sel_end_cursor.pos)) {
+       // only within one paragraph
+       endpar = sel_start_cursor.par;
+       cap.cutSelection(sel_start_cursor.par, &endpar,
+                        sel_start_cursor.pos, sel_end_cursor.pos,
+                        buffer->params.textclass, doclear);
+    } else {
+       endpar = sel_end_cursor.par;
+
+       cap.cutSelection(sel_start_cursor.par, &endpar,
+                        sel_start_cursor.pos, sel_end_cursor.pos,
+                        buffer->params.textclass, doclear);
+       cursor.par = sel_end_cursor.par = endpar;
+       cursor.pos = sel_end_cursor.pos;
+    }
+    endpar = sel_end_cursor.par->Next();
+
+    // sometimes necessary
+    if (doclear)
+       sel_start_cursor.par->ClearParagraph();
+
+    RedoParagraphs(sel_start_cursor, endpar);
+   
+    ClearSelection();
+    cursor = sel_start_cursor;
+    SetCursor(cursor.par, cursor.pos);
+    sel_cursor = cursor;
+    UpdateCounters(cursor.row);
+}
+#endif
     
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::CopySelection()
 {
        // this doesnt make sense, if there is no selection
@@ -2108,16 +2283,15 @@ void LyXText::CopySelection()
        DeleteSimpleCutBuffer();
 
        // set the textclass
-       simple_cut_buffer_textclass = parameters->textclass;
+       simple_cut_buffer_textclass = buffer->params.textclass;
 
-#ifdef FIX_DOUBLE_SPACE
        // copy behind a space if there is one
        while (sel_start_cursor.par->Last() > sel_start_cursor.pos
               && sel_start_cursor.par->IsLineSeparator(sel_start_cursor.pos)
               && (sel_start_cursor.par != sel_end_cursor.par
                   || sel_start_cursor.pos < sel_end_cursor.pos))
                sel_start_cursor.pos++; 
-#endif
+
        // there are two cases: copy only within one paragraph
        // or more than one paragraph
        if (sel_start_cursor.par->ParFromPos(sel_start_cursor.pos) 
@@ -2166,12 +2340,67 @@ void LyXText::CopySelection()
      
                tmpi2 = sel_end_cursor.par->PositionInParFromPos(sel_end_cursor.pos);
                while (tmppar2->size() > tmpi2) {
-                       tmppar2->Erase(tmppar2->text.size() - 1);
+                       tmppar2->Erase(tmppar2->size() - 1);
                }
        }
 }
-          
 
+#else //////////////////////////////////////////////////////////////////////
+
+void LyXText::CopySelection()
+{
+       // this doesnt make sense, if there is no selection
+       if (!selection)
+               return;
+
+       // ok we have a selection. This is always between sel_start_cursor
+       // and sel_end cursor
+       LyXParagraph * tmppar;
+   
+       /* check wether there are half footnotes in the selection */
+       if (sel_start_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
+           || sel_end_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+               tmppar = sel_start_cursor.par;
+               while (tmppar != sel_end_cursor.par) {
+                       if (tmppar->footnoteflag !=
+                           sel_end_cursor.par->footnoteflag) {
+                               WriteAlert(_("Impossible operation"),
+                                          _("Don't know what to do"
+                                            " with half floats."),
+                                          _("sorry."));
+                               return;
+                       }
+                       tmppar = tmppar->Next();
+               }
+       }
+
+       /* table stuff -- begin */
+       if (sel_start_cursor.par->table || sel_end_cursor.par->table){
+               if ( sel_start_cursor.par != sel_end_cursor.par){
+                       WriteAlert(_("Impossible operation"),
+                                  _("Don't know what to do with half tables."),
+                                  _("sorry."));
+                       return;
+               }
+       }
+       /* table stuff -- end */
+   
+       // copy behind a space if there is one
+       while (sel_start_cursor.par->Last() > sel_start_cursor.pos
+              && sel_start_cursor.par->IsLineSeparator(sel_start_cursor.pos)
+              && (sel_start_cursor.par != sel_end_cursor.par
+                  || sel_start_cursor.pos < sel_end_cursor.pos))
+               sel_start_cursor.pos++; 
+
+       CutAndPaste cap;
+
+       cap.copySelection(sel_start_cursor.par, sel_end_cursor.par,
+                         sel_start_cursor.pos, sel_end_cursor.pos,
+                         buffer->params.textclass);
+}
+#endif          
+
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::PasteSelection()
 {
        // this does not make sense, if there is nothing to paste
@@ -2221,17 +2450,11 @@ void LyXText::PasteSelection()
        if (!simple_cut_buffer->next) {
                // only within a paragraph
 
-#ifndef FIX_DOUBLE_SPACE
-               // please break behind a space, if there is one
-               while (tmpcursor.par->Last() > tmpcursor.pos
-                      && tmpcursor.par->IsLineSeparator(tmpcursor.pos))
-                       tmpcursor.pos++; 
-#endif
                tmppar = simple_cut_buffer->Clone();
                /* table stuff -- begin */
                bool table_too_small = false;
                if (tmpcursor.par->table) {
-                       while (simple_cut_buffer->text.size()
+                       while (simple_cut_buffer->size()
                               && !table_too_small) {
                                if (simple_cut_buffer->IsNewline(0)){
                                        while(tmpcursor.pos < tmpcursor.par->Last() && !tmpcursor.par->IsNewline(tmpcursor.pos))
@@ -2242,7 +2465,6 @@ void LyXText::PasteSelection()
                                        else
                                                table_too_small = true;
                                } else {
-#ifdef FIX_DOUBLE_SPACE
                                        // This is an attempt to fix the
                                        // "never insert a space at the
                                        // beginning of a paragraph" problem.
@@ -2255,12 +2477,6 @@ void LyXText::PasteSelection()
                                                tmpcursor.par->InsertFromMinibuffer(tmpcursor.pos);
                                                tmpcursor.pos++;
                                        }
-#else
-                                       simple_cut_buffer->CutIntoMinibuffer(0);
-                                       simple_cut_buffer->Erase(0);
-                                       tmpcursor.par->InsertFromMinibuffer(tmpcursor.pos);
-                                       tmpcursor.pos++;
-#endif
                                }
                        }
                } else {
@@ -2271,8 +2487,7 @@ void LyXText::PasteSelection()
                        // of the text to insert and we are inserting at
                        // the beginning of the paragraph the space should
                        // be removed.
-                       while (simple_cut_buffer->text.size()) {
-#ifdef FIX_DOUBLE_SPACE
+                       while (simple_cut_buffer->size()) {
                                // This is an attempt to fix the
                                // "never insert a space at the
                                // beginning of a paragraph" problem.
@@ -2285,12 +2500,6 @@ void LyXText::PasteSelection()
                                        tmpcursor.par->InsertFromMinibuffer(tmpcursor.pos);
                                        tmpcursor.pos++;
                                }
-#else
-                               simple_cut_buffer->CutIntoMinibuffer(0);
-                               simple_cut_buffer->Erase(0);
-                               tmpcursor.par->InsertFromMinibuffer(tmpcursor.pos);
-                               tmpcursor.pos++;
-#endif
                        }
                }
                delete simple_cut_buffer;
@@ -2298,6 +2507,7 @@ void LyXText::PasteSelection()
                endpar = tmpcursor.par->Next();
        } else {
                // many paragraphs
+               CutAndPaste cap;
 
                // make a copy of the simple cut_buffer
                tmppar = simple_cut_buffer;
@@ -2319,9 +2529,9 @@ void LyXText::PasteSelection()
                }
      
                // make sure there is no class difference
-               SwitchLayoutsBetweenClasses(simple_cut_buffer_textclass,
-                                           parameters->textclass,
-                                           simple_cut_buffer);
+               cap.SwitchLayoutsBetweenClasses(simple_cut_buffer_textclass,
+                                               buffer->params.textclass,
+                                               simple_cut_buffer);
      
                // make the simple_cut_buffer exactly the same layout than
                // the cursor paragraph
@@ -2332,13 +2542,6 @@ void LyXText::PasteSelection()
                while (lastbuffer->Next())
                        lastbuffer = lastbuffer->Next();
      
-#ifndef FIX_DOUBLE_SPACE
-               // Please break behind a space, if there is one. The space 
-               // should be copied too.
-               if (cursor.par->Last() > cursor.pos
-                   && cursor.par->IsLineSeparator(cursor.pos))
-                       cursor.pos++; 
-#endif
                bool paste_the_end = false;
 
                // open the paragraph for inserting the simple_cut_buffer
@@ -2348,15 +2551,6 @@ void LyXText::PasteSelection()
                        paste_the_end = true;
                }
 
-#ifndef FIX_DOUBLE_SPACE
-               // be careful with double spaces
-               if ((!cursor.par->Last()
-                    || cursor.par->IsLineSeparator(cursor.pos - 1)
-                    || cursor.par->IsNewline(cursor.pos - 1))
-                   && simple_cut_buffer->text.size()
-                   && simple_cut_buffer->IsLineSeparator(0))
-                       simple_cut_buffer->Erase(0);
-#endif
                // set the end for redoing later
                endpar = cursor.par->ParFromPos(cursor.pos)->next->Next();
      
@@ -2382,41 +2576,14 @@ void LyXText::PasteSelection()
                // maybe some pasting
                if (lastbuffer->Next() && paste_the_end) {
                        if (lastbuffer->Next()->HasSameLayout(lastbuffer)) {
-#ifndef FIX_DOUBLE_SPACE
-                               // be careful with double spaces
-                               if ((!lastbuffer->Last()
-                                    || lastbuffer->IsLineSeparator(lastbuffer->Last() - 1)
-                                    || lastbuffer->IsNewline(lastbuffer->Last() - 1))
-                                   && lastbuffer->Next()->Last()
-                                   && lastbuffer->Next()->IsLineSeparator(0))
-                                       lastbuffer->Next()->Erase(0);
-#endif
                                lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
         
                        } else if (!lastbuffer->Next()->Last()) {
                                lastbuffer->Next()->MakeSameLayout(lastbuffer);
-#ifndef FIX_DOUBLE_SPACE
-                               // be careful witth double spaces
-                               if ((!lastbuffer->Last()
-                                    || lastbuffer->IsLineSeparator(lastbuffer->Last() - 1)
-                                    || lastbuffer->IsNewline(lastbuffer->Last() - 1))
-                                   && lastbuffer->Next()->Last()
-                                   && lastbuffer->Next()->IsLineSeparator(0))
-                                       lastbuffer->Next()->Erase(0);
-#endif
                                lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
         
                        } else if (!lastbuffer->Last()) {
                                lastbuffer->MakeSameLayout(lastbuffer->next);
-#ifndef FIX_DOUBLE_SPACE
-                               // be careful witth double spaces
-                               if ((!lastbuffer->Last()
-                                    || lastbuffer->IsLineSeparator(lastbuffer->Last() - 1)
-                                    || lastbuffer->IsNewline(lastbuffer->Last() - 1))
-                                   && lastbuffer->Next()->Last()
-                                   && lastbuffer->Next()->IsLineSeparator(0))
-                                       lastbuffer->Next()->Erase(0);
-#endif
                                lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
         
                        } else
@@ -2437,12 +2604,43 @@ void LyXText::PasteSelection()
        SetSelection();
        UpdateCounters(cursor.row);
 }
+
+#else ////////////////////////////////////////////////////////////////////
+
+void LyXText::PasteSelection()
+{
+    CutAndPaste cap;
+
+    // this does not make sense, if there is nothing to paste
+    if (!cap.checkPastePossible(cursor.par, cursor.pos))
+       return;
+
+    SetUndo(Undo::INSERT, 
+           cursor.par->ParFromPos(cursor.pos)->previous, 
+           cursor.par->ParFromPos(cursor.pos)->next); 
+
+    LyXParagraph *endpar;
+    LyXParagraph *actpar = cursor.par;
+    int endpos = cursor.pos;
+
+    cap.pasteSelection(&actpar, &endpar, endpos, buffer->params.textclass);
+
+    RedoParagraphs(cursor, endpar);
+    
+    SetCursor(cursor.par, cursor.pos);
+    ClearSelection();
    
+    sel_cursor = cursor;
+    SetCursor(actpar, endpos);
+    SetSelection();
+    UpdateCounters(cursor.row);
+}
+#endif   
 
 // returns a pointer to the very first LyXParagraph
 LyXParagraph * LyXText::FirstParagraph() const
 {
-       return params->paragraph;
+       return buffer->paragraph;
 }
 
 
@@ -2552,20 +2750,9 @@ bool LyXText::SearchBackward(char const * string) const
 }
 
 
-void LyXText::InsertStringA(LyXParagraph::TextContainer const & text)
-{
-       char * str = new char[text.size() + 1];
-       copy(text.begin(), text.end(), str);
-       str[text.size()] = '\0';
-       InsertStringA(str);
-       delete [] str;
-}
-
-
 // needed to insert the selection
-void LyXText::InsertStringA(char const * s)
+void LyXText::InsertStringA(string const & str)
 {
-       string str(s);
        LyXParagraph * par = cursor.par;
        LyXParagraph::size_type pos = cursor.pos;
        LyXParagraph::size_type a = 0;
@@ -2574,8 +2761,8 @@ void LyXText::InsertStringA(char const * s)
        
        SetCursorParUndo();
        
-       char flag =
-               textclasslist.Style(parameters->textclass, 
+       bool flag =
+               textclasslist.Style(buffer->params.textclass, 
                                    cursor.par->GetLayout()).isEnvironment();
        // only to be sure, should not be neccessary
        ClearSelection();
@@ -2588,6 +2775,7 @@ void LyXText::InsertStringA(char const * s)
                            && i + 1 < str.length() && str[i + 1] != ' '
                            && pos && par->GetChar(pos - 1)!= ' ') {
                                par->InsertChar(pos,' ');
+                               par->SetFont(pos, current_font);
                                ++pos;
                        } else if (par->table) {
                                if (str[i] == '\t') {
@@ -2601,20 +2789,38 @@ void LyXText::InsertStringA(char const * s)
                                } else if ((str[i] != 13) &&
                                           ((str[i] & 127) >= ' ')) {
                                        par->InsertChar(pos, str[i]);
+                                       par->SetFont(pos, current_font);
                                        ++pos;
                                }
                         } else if (str[i] == ' ') {
-                               par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR);
+                               InsetSpecialChar * new_inset =
+                                       new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
+                               if (par->InsertInsetAllowed(new_inset)) {
+                                       par->InsertChar(pos, LyXParagraph::META_INSET);
+                                       par->SetFont(pos, current_font);
+                                       par->InsertInset(pos, new_inset);
+                               } else {
+                                       delete new_inset;
+                               }
                                ++pos;
                        } else if (str[i] == '\t') {
                                for (a = pos; a < (pos / 8 + 1) * 8 ; ++a) {
-                                       par->InsertChar(a, LyXParagraph::META_PROTECTED_SEPARATOR);
+                               InsetSpecialChar * new_inset =
+                                       new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
+                               if (par->InsertInsetAllowed(new_inset)) {
+                                       par->InsertChar(pos, LyXParagraph::META_INSET);
+                                       par->SetFont(pos, current_font);
+                                       par->InsertInset(pos, new_inset);
+                               } else {
+                                       delete new_inset;
+                               }
                                }
                                pos = a;
-                       } else if (str[i]!= 13 && 
+                       } else if (str[i] != 13 && 
                                   // Ignore unprintables
                                   (str[i] & 127) >= ' ') {
                                par->InsertChar(pos, str[i]);
+                               par->SetFont(pos, current_font);
                                ++pos;
                        }
                } else {
@@ -2630,6 +2836,7 @@ void LyXText::InsertStringA(char const * s)
                                 cell = NumberOfCell(par, pos);
                                 while((pos < par->size()) &&
                                       !(par->table->IsFirstCell(cell))) {
+
                                         while((pos < par->size()) &&
                                               (par->GetChar(pos) != LyXParagraph::META_NEWLINE))
                                                 ++pos;
@@ -2640,8 +2847,16 @@ void LyXText::InsertStringA(char const * s)
                                         // no more fields to fill skip the rest
                                         break;
                         } else {
-                                if (!par->text.size()) {
-                                        par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR);
+                                if (!par->size()) { // par is empty
+                                       InsetSpecialChar * new_inset =
+                                               new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
+                                       if (par->InsertInsetAllowed(new_inset)) {
+                                               par->InsertChar(pos, LyXParagraph::META_INSET);
+                                               par->SetFont(pos, current_font);
+                                               par->InsertInset(pos, new_inset);
+                                       } else {
+                                               delete new_inset;
+                                       }
                                         ++pos;
                                 }
                                 par->BreakParagraph(pos, flag);
@@ -2660,21 +2875,11 @@ void LyXText::InsertStringA(char const * s)
 }
 
 
-void LyXText::InsertStringB(LyXParagraph::TextContainer const & text)
-{
-       char * str = new char[text.size() + 1];
-       copy(text.begin(), text.end(), str);
-       str[text.size()] = '\0';
-       InsertStringB(str);
-       delete [] str;
-}
-
-
 /* turns double-CR to single CR, others where converted into one blank and 13s 
  * that are ignored .Double spaces are also converted into one. Spaces at
  * the beginning of a paragraph are forbidden. tabs are converted into one
  * space. then InsertStringA is called */ 
-void LyXText::InsertStringB(char const * s)
+void LyXText::InsertStringB(string const & s)
 {
        string str(s);
        LyXParagraph * par = cursor.par;
@@ -2702,7 +2907,7 @@ void LyXText::InsertStringB(char const * s)
                }
                ++i;
        }
-       InsertStringA(str.c_str());
+       InsertStringA(str);
 }
 
 
@@ -2753,49 +2958,11 @@ bool LyXText::GotoNextNote() const
 }
 
 
-int LyXText::SwitchLayoutsBetweenClasses(char class1, char class2,
-                                        LyXParagraph * par)
-{
-       int ret = 0;
-       if (!par || class1 == class2)
-               return ret;
-       par = par->FirstPhysicalPar();
-       while (par) {
-               string name = textclasslist.NameOfLayout(class1, par->layout);
-               int lay = 0;
-               pair<bool, LyXTextClass::LayoutList::size_type> pp =
-                       textclasslist.NumberOfLayout(class2, name);
-               if (pp.first) {
-                       lay = pp.second;
-               } else { // layout not found
-                       // use default layout "Standard" (0)
-                       lay = 0;
-               }
-               par->layout = lay;
-      
-               if (name != textclasslist.NameOfLayout(class2, par->layout)) {
-                       ++ret;
-                       string s = "Layout had to be changed from\n"
-                               + name + " to " + textclasslist.NameOfLayout(class2, par->layout)
-                               + "\nbecause of class conversion from\n"
-                               + textclasslist.NameOfClass(class1) + " to "
-                               + textclasslist.NameOfClass(class2);
-                       InsetError * new_inset = new InsetError(s);
-                       par->InsertChar(0, LyXParagraph::META_INSET);
-                       par->InsertInset(0, new_inset);
-               }
-      
-               par = par->next;
-       }
-       return ret;
-}
-
-
 void LyXText::CheckParagraph(LyXParagraph * par,
                             LyXParagraph::size_type pos)
 {
-  
-       LyXCursor tmpcursor;
+       LyXCursor tmpcursor;                    
+
 
        /* table stuff -- begin*/
    
@@ -2841,7 +3008,7 @@ void LyXText::CheckParagraph(LyXParagraph * par,
                        status = LyXText::NEED_MORE_REFRESH; 
    
                // check the special right address boxes
-               if (textclasslist.Style(parameters->textclass,
+               if (textclasslist.Style(buffer->params.textclass,
                                        par->GetLayout()).margintype
                    == MARGIN_RIGHT_ADDRESS_BOX) {
                        tmpcursor.par = par;
@@ -2912,17 +3079,139 @@ void LyXText::SetCursor(LyXParagraph * par,
 }
 
 
+void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
+                       LyXParagraph::size_type pos) const
+{
+       // correct the cursor position if impossible
+       if (pos > par->Last()){
+               LyXParagraph * tmppar = par->ParFromPos(pos);
+               pos = par->PositionInParFromPos(pos);
+               par = tmppar;
+       }
+       if (par->IsDummy() && par->previous &&
+           par->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
+               while (par->previous &&
+                      ((par->previous->IsDummy() &&
+                        (par->previous->previous->footnoteflag ==
+                         LyXParagraph::CLOSED_FOOTNOTE)) ||
+                       (par->previous->footnoteflag ==
+                        LyXParagraph::CLOSED_FOOTNOTE))) {
+                       par = par->previous ;
+                       if (par->IsDummy() &&
+                           (par->previous->footnoteflag ==
+                            LyXParagraph::CLOSED_FOOTNOTE))
+                               pos += par->size() + 1;
+               }
+               if (par->previous) {
+                       par = par->previous;
+               }
+               pos += par->size() + 1;
+       }
+
+       cur.par = par;
+       cur.pos = pos;
+
+       /* get the cursor y position in text  */
+       long y = 0;
+       Row * row = GetRow(par, pos, y);
+       /* y is now the beginning of the cursor row */ 
+       y += row->baseline;
+       /* y is now the cursor baseline */ 
+       cur.y = y;
+   
+       /* now get the cursors x position */
+       float x;
+       float fill_separator, fill_hfill, fill_label_hfill;
+       PrepareToPrint(row, x, fill_separator, fill_hfill, fill_label_hfill);
+       LyXParagraph::size_type cursor_vpos;
+       LyXParagraph::size_type last = RowLastPrintable(row);
+
+       if (pos > last + 1)   // This shouldn't happen.
+               pos = last+1;
+
+       if (last < row->pos)
+                cursor_vpos = 0;
+       else if ((pos > last) ||
+                ((pos - 1 >= row->pos) &&
+                 (row->par->IsSeparator(pos) ||
+                  (row->par->table && row->par->IsNewline(pos)))))
+               /// Place cursor after char at (logical) position pos-1
+               cursor_vpos = !(bidi_level(pos-1) % 2)
+                       ? log2vis(pos-1) + 1 : log2vis(pos-1);
+       else
+               /// Place cursor before char at (logical) position pos
+               cursor_vpos = !(bidi_level(pos) % 2)
+                       ? log2vis(pos) : log2vis(pos) + 1;
+
+       /* table stuff -- begin*/
+       if (row->par->table) {
+               int cell = NumberOfCell(row->par, row->pos);
+               float x_old = x;
+               x += row->par->table->GetBeginningOfTextInCell(cell);
+               for (LyXParagraph::size_type vpos = row->pos;
+                    vpos < cursor_vpos; ++vpos) {
+                       pos = vis2log(vpos);
+                       if (row->par->IsNewline(pos)) {
+                               x = x_old + row->par->table->WidthOfColumn(cell);
+                               x_old = x;
+                               ++cell;
+                               x += row->par->table->GetBeginningOfTextInCell(cell);
+                       } else {
+                               x += SingleWidth(row->par, pos);
+                       }
+               }
+       } else {
+               /* table stuff -- end*/
+               LyXParagraph::size_type main_body =
+                       BeginningOfMainBody(row->par);
+               if ((main_body > 0) &&
+                   ((main_body-1 > last) || 
+                    !row->par->IsLineSeparator(main_body-1)))
+                       main_body = 0;
+
+               for (LyXParagraph::size_type vpos = row->pos;
+                    vpos < cursor_vpos; ++vpos) {
+                       pos = vis2log(vpos);
+                       if (main_body > 0 && pos == main_body-1) {
+                               x += fill_label_hfill +
+                                       lyxfont::width(textclasslist.Style(
+                                               buffer->params.textclass,
+                                               row->par->GetLayout())
+                                                      .labelsep,
+                                                      GetFont(row->par, -2));
+                               if (row->par->IsLineSeparator(main_body-1))
+                                       x -= SingleWidth(row->par,main_body-1);
+                       }
+                       if (HfillExpansion(row, pos)) {
+                               x += SingleWidth(row->par, pos);
+                               if (pos >= main_body)
+                                       x += fill_hfill;
+                               else 
+                                       x += fill_label_hfill;
+                       } else if (row->par->IsSeparator(pos)) {
+                               x += SingleWidth(row->par, pos);
+                               if (pos >= main_body)
+                                       x += fill_separator;
+                       } else
+                               x += SingleWidth(row->par, pos);
+               }
+       }
+   
+       cur.x = int(x);
+       cur.x_fix = cur.x;
+       cur.row = row;
+}
+
+
 void LyXText::SetCursorIntern(LyXParagraph * par,
                              LyXParagraph::size_type pos, bool setfont) const
 {
-       long y;
-       Row * row;
-       LyXParagraph * tmppar;
-       LyXParagraph::size_type vpos,cursor_vpos;
-
+       SetCursor(cursor, par, pos);
+#warning Remove this when verified working (Jug 20000413)
+#if 0
        // correct the cursor position if impossible
        if (pos > par->Last()){
-               tmppar = par->ParFromPos(pos);
+               LyXParagraph * tmppar = par->ParFromPos(pos);
                pos = par->PositionInParFromPos(pos);
                par = tmppar;
        }
@@ -2934,38 +3223,20 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
                        par = par->previous ;
                        if (par->IsDummy() &&
                            par->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
-                               pos += par->text.size() + 1;
+                               pos += par->size() + 1;
                }
                if (par->previous) {
                        par = par->previous;
                }
-               pos += par->text.size() + 1;
+               pos += par->size() + 1;
        }
 
        cursor.par = par;
        cursor.pos = pos;
 
-       if (setfont)
-               if (cursor.pos && 
-                   (cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
-                    || (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
-                        && !cursor.par->IsSeparator(cursor.pos))
-                    || (cursor.par->table && cursor.par->IsNewline(cursor.pos))
-                    )) {
-                       current_font = cursor.par->GetFontSettings(cursor.pos - 1);
-                       real_current_font = GetFont(cursor.par, cursor.pos - 1);
-               } else {
-                       current_font = cursor.par->GetFontSettings(cursor.pos);
-                       real_current_font = GetFont(cursor.par, cursor.pos);
-                       if (pos == 0 && par->size() == 0 
-                           && owner_->buffer()->params.getDocumentDirection() == LYX_DIR_RIGHT_TO_LEFT) {
-                               current_font.setDirection(LyXFont::RTL_DIR);
-                               real_current_font.setDirection(LyXFont::RTL_DIR);
-                       }
-               }
-
        /* get the cursor y position in text  */
-       row = GetRow(par, pos, y);
+       long y = 0;
+       Row * row = GetRow(par, pos, y);
        /* y is now the beginning of the cursor row */ 
        y += row->baseline;
        /* y is now the cursor baseline */ 
@@ -2975,31 +3246,33 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
        float x;
        float fill_separator, fill_hfill, fill_label_hfill;
        PrepareToPrint(row, x, fill_separator, fill_hfill, fill_label_hfill);
-
-       LyXParagraph::size_type last = RowLast(row);
-       if (row->pos > last)
-               cursor_vpos = 0;
-       else if (pos <= last ) {
-               LyXDirection letter_direction =
-                       row->par->getLetterDirection(pos);
-               LyXDirection font_direction =
-                       real_current_font.getFontDirection();
-               if (letter_direction == font_direction || pos == 0)
-                       cursor_vpos = (letter_direction == LYX_DIR_LEFT_TO_RIGHT)
-                               ? log2vis(pos) : log2vis(pos)+1;
-               else
-                       cursor_vpos = (font_direction == LYX_DIR_LEFT_TO_RIGHT)
-                               ? log2vis(pos-1)+1 : log2vis(pos-1);
-       } else
-               cursor_vpos = (row->par->getLetterDirection(last) == LYX_DIR_LEFT_TO_RIGHT)
-                       ? log2vis(last)+1 : log2vis(last);
+       LyXParagraph::size_type cursor_vpos;
+       LyXParagraph::size_type last = RowLastPrintable(row);
+
+       if (pos > last + 1)   // This shouldn't happen.
+               pos = last+1;
+
+       if (last < row->pos)
+                cursor_vpos = 0;
+       else if (pos > last ||
+           (pos - 1 >= row->pos &&
+            (row->par->IsSeparator(pos) ||
+             (row->par->table && row->par->IsNewline(pos))
+             )))
+               /// Place cursor after char at (logical) position pos-1
+               cursor_vpos = (bidi_level(pos-1) % 2 == 0)
+                       ? log2vis(pos-1) + 1 : log2vis(pos-1);
+       else
+               /// Place cursor before char at (logical) position pos
+               cursor_vpos = (bidi_level(pos) % 2 == 0)
+                       ? log2vis(pos) : log2vis(pos) + 1;
 
        /* table stuff -- begin*/
        if (row->par->table) {
                int cell = NumberOfCell(row->par, row->pos);
                float x_old = x;
                x += row->par->table->GetBeginningOfTextInCell(cell);
-               for (vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
+               for (LyXParagraph::size_type vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
                        pos = vis2log(vpos);
                        if (row->par->IsNewline(pos)) {
                                x = x_old + row->par->table->WidthOfColumn(cell);
@@ -3019,26 +3292,31 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
                     !row->par->IsLineSeparator(main_body-1)))
                        main_body = 0;
 
-               for (vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
+               for (LyXParagraph::size_type vpos = row->pos; vpos < cursor_vpos; ++vpos)  {
                        pos = vis2log(vpos);
                        if (main_body > 0 && pos == main_body-1) {
                                x += fill_label_hfill +
-                                       GetFont(row->par, -2).stringWidth(
-                                                   textclasslist.Style(parameters->textclass, row->par->GetLayout()).labelsep);
+                                       lyxfont::width(textclasslist
+                                                      .Style(buffer->params.textclass,
+                                                             row->par->GetLayout())
+                                                      .labelsep,
+                                                      GetFont(row->par, -2));
                                if (row->par->IsLineSeparator(main_body-1))
                                        x -= SingleWidth(row->par, main_body-1);
                        }
-      
-                       x += SingleWidth(row->par, pos);
                        if (HfillExpansion(row, pos)) {
+                               x += SingleWidth(row->par, pos);
                                if (pos >= main_body)
                                        x += fill_hfill;
                                else 
                                        x += fill_label_hfill;
                        }
-                       else if (pos >= main_body && row->par->IsSeparator(pos)) {
-                               x+= fill_separator;
-                       }
+                       else if (row->par->IsSeparator(pos)) {
+                               x += SingleWidth(row->par, pos);
+                               if (pos >= main_body)
+                                       x += fill_separator;
+                       } else
+                               x += SingleWidth(row->par, pos);
                }
        }
    
@@ -3046,6 +3324,19 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
    
        cursor.x_fix = cursor.x;
        cursor.row = row;
+#endif
+       if (setfont) {
+               if (cursor.pos && 
+                   (cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
+                    || (cursor.par->table && cursor.par->IsNewline(cursor.pos))
+                    )) {
+                       current_font = cursor.par->GetFontSettings(cursor.pos - 1);
+                       real_current_font = GetFont(cursor.par, cursor.pos - 1);
+               } else {
+                       current_font = cursor.par->GetFontSettings(cursor.pos);
+                       real_current_font = GetFont(cursor.par, cursor.pos);
+               }
+       }
 }
 
 
@@ -3082,6 +3373,20 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
        DeleteEmptyParagraphMechanism(old_cursor);
 }
 
+void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
+{
+       /* get the row first */ 
+   
+       Row * row = GetRowNearY(y);
+       int column = GetColumnNearX(row, x);
+   
+       cur.par = row->par;
+       cur.pos = row->pos + column;
+       cur.x = x;
+       cur.y = y + row->baseline;
+       cur.row = row;
+}
+
 
 void LyXText::CursorLeft() const
 {
@@ -3089,7 +3394,7 @@ void LyXText::CursorLeft() const
         if (cursor.par->table) {
                 int cell = NumberOfCell(cursor.par, cursor.pos);
                 if (cursor.par->table->IsContRow(cell) &&
-                    cursor.par->table->CellHasContRow(cursor.par->table->GetCellAbove(cell))<0) {
+                    cursor.par->table->CellHasContRow(cursor.par->table->GetCellAbove(cell)) < 0) {
                         CursorUp();
                 }
         }
@@ -3101,7 +3406,7 @@ void LyXText::CursorLeftIntern() const
        if (cursor.pos > 0) {
                SetCursor(cursor.par, cursor.pos - 1);
        }
-       else if (cursor.par->Previous()) {
+       else if (cursor.par->Previous()) { // steps into the above paragraph.
                SetCursor(cursor.par->Previous(), cursor.par->Previous()->Last());
        }
 }
@@ -3196,12 +3501,16 @@ void LyXText::CursorDownParagraph() const
 
 void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
 {
-       bool deleted = false;
-       
-       // this is the delete-empty-paragraph-mechanism.
+       // Would be wrong to delete anything if we have a selection.
        if (selection) return;
 
-#ifdef FIX_DOUBLE_SPACE
+       // We allow all kinds of "mumbo-jumbo" when freespacing.
+       if (textclasslist.Style(buffer->params.textclass,
+                               old_cursor.par->GetLayout()).free_spacing)
+               return;
+
+       bool deleted = false;
+       
        /* Ok I'll put some comments here about what is missing.
           I have fixed BackSpace (and thus Delete) to not delete
           double-spaces automagically. I have also changed Cut,
@@ -3226,26 +3535,26 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
        // MISSING
 
        // If the pos around the old_cursor were spaces, delete one of them.
-       if (!(old_cursor.par == cursor.par && old_cursor.pos == cursor.pos)
-           && old_cursor.pos > 0
-           && old_cursor.pos < old_cursor.par->Last()
-           && old_cursor.par->IsLineSeparator(old_cursor.pos)
-           && old_cursor.par->IsLineSeparator(old_cursor.pos - 1)) {
-               old_cursor.par->Erase(old_cursor.pos - 1);
-               RedoParagraphs(old_cursor, old_cursor.par->Next());
-               // or RedoDrawingOfParagraph(old_cursor);
-               // correct cursor
-               if (old_cursor.par == cursor.par &&
-                   cursor.pos > old_cursor.pos)
-                       SetCursor(cursor.par, cursor.pos - 1);
-               else
-                       SetCursor(cursor.par, cursor.pos);
-               return;
+       if (old_cursor.par != cursor.par || old_cursor.pos != cursor.pos) { // Only if the cursor has really moved
+               
+               if (old_cursor.pos > 0
+                   && old_cursor.pos < old_cursor.par->Last()
+                   && old_cursor.par->IsLineSeparator(old_cursor.pos)
+                   && old_cursor.par->IsLineSeparator(old_cursor.pos - 1)) {
+                       old_cursor.par->Erase(old_cursor.pos - 1);
+                       RedoParagraphs(old_cursor, old_cursor.par->Next());
+                       // correct cursor
+                       if (old_cursor.par == cursor.par &&
+                           cursor.pos > old_cursor.pos) {
+                               SetCursorIntern(cursor.par, cursor.pos - 1);
+                       } else
+                               SetCursorIntern(cursor.par, cursor.pos);
+                       return;
+               }
        }
-#endif
-       //
-       // Paragraph should not be deleted if empty
-       if ((textclasslist.Style(parameters->textclass,
+
+       // Do not delete empty paragraphs with keepempty set.
+       if ((textclasslist.Style(buffer->params.textclass,
                                 old_cursor.par->GetLayout())).keepempty)
                return;
 
@@ -3254,10 +3563,9 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
        if (old_cursor.par != cursor.par) {
                if ( (old_cursor.par->Last() == 0
                      || (old_cursor.par->Last() == 1
-                         && (old_cursor.par->IsLineSeparator(0))))
+                         && old_cursor.par->IsLineSeparator(0)))
                     && old_cursor.par->FirstPhysicalPar()
                     == old_cursor.par->LastPhysicalPar()) {
-                       
                        // ok, we will delete anything
                        
                        // make sure that you do not delete any environments
@@ -3266,13 +3574,11 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
                               && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)
                             && !(old_cursor.row->next 
                                  && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE))
-                           || 
-                           (old_cursor.par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE &&
-                            ((old_cursor.row->previous 
-                              && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)
-                             || 
-                             (old_cursor.row->next
-                              && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE))
+                           || (old_cursor.par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
+                               && ((old_cursor.row->previous 
+                                    && old_cursor.row->previous->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE)
+                                   || (old_cursor.row->next
+                                       && old_cursor.row->next->par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE))
                                    )) {
                                status = LyXText::NEED_MORE_REFRESH;
                                deleted = true;
@@ -3295,8 +3601,8 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
 
                                        // delete old row
                                        RemoveRow(old_cursor.row);
-                                       if (params->paragraph == old_cursor.par) {
-                                               params->paragraph = params->paragraph->next;
+                                       if (buffer->paragraph == old_cursor.par) {
+                                               buffer->paragraph = buffer->paragraph->next;
                                        }
                                        // delete old par
                                        delete old_cursor.par;
@@ -3331,8 +3637,8 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
                                        // delete old row
                                        RemoveRow(old_cursor.row);
                                        // delete old par
-                                       if (params->paragraph == old_cursor.par) {
-                                               params->paragraph = params->paragraph->next;
+                                       if (buffer->paragraph == old_cursor.par) {
+                                               buffer->paragraph = buffer->paragraph->next;
                                        }
                                        delete old_cursor.par;
                                        
@@ -3349,11 +3655,9 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
                                }
                                
                                // correct cursor y
-                               SetCursor(cursor.par, cursor.pos);
-                               
-                               /* if (cursor.y > old_cursor.y)
-                                  cursor.y -= old_cursor.row->height; */ 
-        
+
+                               SetCursorIntern(cursor.par, cursor.pos);
+
                                if (sel_cursor.par  == old_cursor.par
                                    && sel_cursor.pos == sel_cursor.pos) {
                                        // correct selection
@@ -3362,10 +3666,10 @@ void LyXText::DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const
                        }
                }
                if (!deleted) {
-                       if (old_cursor.par->ClearParagraph()){
+                       if (old_cursor.par->ClearParagraph()) {
                                RedoParagraphs(old_cursor, old_cursor.par->Next());
                                // correct cursor y
-                               SetCursor(cursor.par, cursor.pos);
+                               SetCursorIntern(cursor.par, cursor.pos);
                                sel_cursor = cursor;
                        }
                }
@@ -3386,11 +3690,11 @@ LyXParagraph * LyXText::GetParFromID(int id)
 bool LyXText::TextUndo()
 {
        // returns false if no undo possible
-       Undo * undo = params->undostack.pop();
+       Undo * undo = buffer->undostack.pop();
        if (undo) {
                FinishUndo();
                if (!undo_frozen)
-                       params->redostack
+                       buffer->redostack
                                .push(CreateUndo(undo->kind, 
                                                 GetParFromID(undo->number_of_before_par),
                                                 GetParFromID(undo->number_of_behind_par)));
@@ -3402,11 +3706,11 @@ bool LyXText::TextUndo()
 bool LyXText::TextRedo()
 {
        // returns false if no redo possible
-       Undo * undo = params->redostack.pop();
+       Undo * undo = buffer->redostack.pop();
        if (undo) {
                FinishUndo();
                if (!undo_frozen)
-                       params->undostack
+                       buffer->undostack
                                .push(CreateUndo(undo->kind, 
                                                 GetParFromID(undo->number_of_before_par),
                                                 GetParFromID(undo->number_of_behind_par)));
@@ -3426,8 +3730,6 @@ bool LyXText::TextHandleUndo(Undo * undo)
                        GetParFromID(undo->number_of_behind_par); 
                LyXParagraph * tmppar;
                LyXParagraph * tmppar2;
-               LyXParagraph * tmppar3;
-               LyXParagraph * tmppar4;
                LyXParagraph * endpar;
                LyXParagraph * tmppar5;
     
@@ -3438,9 +3740,9 @@ bool LyXText::TextHandleUndo(Undo * undo)
 
                // replace the paragraphs with the undo informations
 
-               tmppar3 = undo->par;
+               LyXParagraph * tmppar3 = undo->par;
                undo->par = 0; // otherwise the undo destructor would delete the paragraph
-               tmppar4 = tmppar3;
+               LyXParagraph * tmppar4 = tmppar3;
                if (tmppar4){
                        while (tmppar4->next)
                                tmppar4 = tmppar4->next;
@@ -3451,25 +3753,18 @@ bool LyXText::TextHandleUndo(Undo * undo)
                        if (before)
                                tmppar5 = before->next;
                        else
-                               tmppar5 = params->paragraph;
+                               tmppar5 = buffer->paragraph;
                        tmppar2 = tmppar3;
                        while (tmppar5 && tmppar5 != behind){
                                tmppar = tmppar5;
                                tmppar5 = tmppar5->next;
                                // a memory optimization for edit: Only layout information
                                // is stored in the undo. So restore the text informations.
-                               if (undo->kind == Undo::EDIT){
-                                       tmppar2->text = tmppar->text;
-                                       tmppar->text.clear();
+                               if (undo->kind == Undo::EDIT) {
+                                       tmppar2->setContentsFromPar(tmppar);
+                                       tmppar->clearContents();
                                        tmppar2 = tmppar2->next;
                                }
-                               if ( currentrow && currentrow->par == tmppar )
-                                       currentrow = currentrow -> previous;
-                               // Commenting out this might remove the error
-                               // reported by Purify, but it might also
-                               // introduce a memory leak. We need to
-                               // check this (Lgb)
-                               //delete tmppar;
                        }
                }
     
@@ -3478,12 +3773,12 @@ bool LyXText::TextHandleUndo(Undo * undo)
                        if (before)
                                before->next = tmppar3;
                        else
-                               params->paragraph = tmppar3;
+                               buffer->paragraph = tmppar3;
                        tmppar3->previous = before;
                }
                else {
                        if (!before)
-                               params->paragraph = behind;
+                               buffer->paragraph = behind;
                }
                if (tmppar4) {
                        tmppar4->next = behind;
@@ -3493,7 +3788,7 @@ bool LyXText::TextHandleUndo(Undo * undo)
     
     
                // Set the cursor for redoing
-               if (before){
+               if (before) {
                        SetCursorIntern(before->FirstSelfrowPar(), 0);
                        // check wether before points to a closed float and open it if necessary
                        if (before && before->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
@@ -3568,15 +3863,15 @@ void LyXText::SetUndo(Undo::undo_kind kind, LyXParagraph const * before,
                      LyXParagraph const * behind) const
 {
        if (!undo_frozen)
-               params->undostack.push(CreateUndo(kind, before, behind));
-       params->redostack.clear();
+               buffer->undostack.push(CreateUndo(kind, before, behind));
+       buffer->redostack.clear();
 }
 
 
 void LyXText::SetRedo(Undo::undo_kind kind, LyXParagraph const * before,
                      LyXParagraph const * behind)
 {
-       params->redostack.push(CreateUndo(kind, before, behind));
+       buffer->redostack.push(CreateUndo(kind, before, behind));
 }
 
 
@@ -3599,10 +3894,10 @@ Undo * LyXText::CreateUndo(Undo::undo_kind kind, LyXParagraph const * before,
        if (!undo_finished && kind != Undo::EDIT && 
            kind != Undo::FINISH){
                // check wether storing is needed
-               if (!params->undostack.empty() && 
-                   params->undostack.top()->kind == kind &&
-                   params->undostack.top()->number_of_before_par ==  before_number &&
-                   params->undostack.top()->number_of_behind_par ==  behind_number ){
+               if (!buffer->undostack.empty() && 
+                   buffer->undostack.top()->kind == kind &&
+                   buffer->undostack.top()->number_of_before_par ==  before_number &&
+                   buffer->undostack.top()->number_of_behind_par ==  behind_number ){
                        // no undo needed
                        return 0;
                }
@@ -3637,7 +3932,8 @@ Undo * LyXText::CreateUndo(Undo::undo_kind kind, LyXParagraph const * before,
                // a memory optimization: Just store the layout information
                // when only edit
                if (kind == Undo::EDIT){
-                       tmppar2->text.clear();
+                       //tmppar2->text.clear();
+                       tmppar2->clearContents();
                }
 
                undopar = tmppar2;
@@ -3649,7 +3945,8 @@ Undo * LyXText::CreateUndo(Undo::undo_kind kind, LyXParagraph const * before,
                        // a memory optimization: Just store the layout
                        // information when only edit
                        if (kind == Undo::EDIT){
-                               tmppar2->next->text.clear();
+                               //tmppar2->next->text.clear();
+                               tmppar2->clearContents();
                        }
                        tmppar2->next->previous = tmppar2;
                        tmppar2 = tmppar2->next;