]> git.lyx.org Git - features.git/blobdiff - src/Text.cpp
Improve undo of consecutive insertions/deletions
[features.git] / src / Text.cpp
index a448a5c7eebadc98947b2ffe2bc974adf43546e7..c438f7760fafaa93c5db4c259dd9f321fb5a015b 100644 (file)
@@ -113,8 +113,8 @@ static bool moveItem(Paragraph & fromPar, pos_type fromPos,
        // Therefore, it should only be used for breaking and merging paragraphs
 
        // We need a copy here because the character at fromPos is going to be erased.
-       Font const tmpFont = fromPar.getFontSettings(params, fromPos);
-       Change const tmpChange = fromPar.lookupChange(fromPos);
+       Font const tmpFont = fromPar.getFontSettings(params, fromPos);
+       Change const tmpChange = fromPar.lookupChange(fromPos);
 
        if (Inset * tmpInset = fromPar.getInset(fromPos)) {
                fromPar.releaseInset(fromPos);
@@ -198,7 +198,7 @@ void mergeParagraph(BufferParams const & bparams,
 
 
 Text::Text(InsetText * owner, bool use_default_layout)
-       : owner_(owner), autoBreakRows_(false), undo_counter_(0)
+       : owner_(owner), autoBreakRows_(false)
 {
        pars_.push_back(Paragraph());
        Paragraph & par = pars_.back();
@@ -212,7 +212,7 @@ Text::Text(InsetText * owner, bool use_default_layout)
 
 
 Text::Text(InsetText * owner, Text const & text)
-       : owner_(owner), autoBreakRows_(text.autoBreakRows_), undo_counter_(0)
+       : owner_(owner), autoBreakRows_(text.autoBreakRows_)
 {
        pars_ = text.pars_;
        ParagraphList::iterator const end = pars_.end();
@@ -486,18 +486,42 @@ void Text::readParToken(Paragraph & par, Lexer & lex,
        } else if (token == "\\color") {
                lex.next();
                setLyXColor(lex.getString(), font.fontInfo());
-       } else if (token == "\\SpecialChar") {
+       } else if (token == "\\SpecialChar" ||
+                  (token == "\\SpecialCharNoPassThru" &&
+                   !par.layout().pass_thru && !inset().isPassThru())) {
                auto_ptr<Inset> inset;
                inset.reset(new InsetSpecialChar);
                inset->read(lex);
                inset->setBuffer(*buf);
                par.insertInset(par.size(), inset.release(), font, change);
+       } else if (token == "\\SpecialCharNoPassThru") {
+               lex.next();
+               docstring const s = ltrim(lex.getDocString(), "\\");
+               par.insert(par.size(), s, font, change);
        } else if (token == "\\IPAChar") {
                auto_ptr<Inset> inset;
                inset.reset(new InsetIPAChar);
                inset->read(lex);
                inset->setBuffer(*buf);
                par.insertInset(par.size(), inset.release(), font, change);
+       } else if (token == "\\twohyphens" || token == "\\threehyphens") {
+               // Ideally, this should be done by lyx2lyx, but lyx2lyx does not know the
+               // running font and does not know anything about layouts (and CopyStyle).
+               Layout const & layout(par.layout());
+               FontInfo info = font.fontInfo();
+               info.realize(layout.resfont);
+               if (layout.pass_thru || inset().isPassThru() ||
+                   info.family() == TYPEWRITER_FAMILY) {
+                       if (token == "\\twohyphens")
+                               par.insert(par.size(), from_ascii("--"), font, change);
+                       else
+                               par.insert(par.size(), from_ascii("---"), font, change);
+               } else {
+                       if (token == "\\twohyphens")
+                               par.insertChar(par.size(), 0x2013, font, change);
+                       else
+                               par.insertChar(par.size(), 0x2014, font, change);
+               }
        } else if (token == "\\backslash") {
                par.appendChar('\\', font, change);
        } else if (token == "\\LyXTable") {
@@ -1019,14 +1043,36 @@ void Text::insertChar(Cursor & cur, char_type c)
                }
        }
 
-       par.insertChar(cur.pos(), c, cur.current_font,
+       pos_type pos = cur.pos();
+       if (!cur.paragraph().isPassThru() && owner_->lyxCode() != IPA_CODE &&
+           cur.current_font.fontInfo().family() != TYPEWRITER_FAMILY &&
+           c == '-' && pos > 0) {
+               if (par.getChar(pos - 1) == '-') {
+                       // convert "--" to endash
+                       par.eraseChar(pos - 1, cur.buffer()->params().track_changes);
+                       c = 0x2013;
+                       pos--;
+               } else if (par.getChar(pos - 1) == 0x2013) {
+                       // convert "---" to emdash
+                       par.eraseChar(pos - 1, cur.buffer()->params().track_changes);
+                       c = 0x2014;
+                       pos--;
+               } else if (par.getChar(pos - 1) == 0x2014) {
+                       // convert "----" to "-"
+                       par.eraseChar(pos - 1, cur.buffer()->params().track_changes);
+                       c = '-';
+                       pos--;
+               }
+       }
+
+       par.insertChar(pos, c, cur.current_font,
                cur.buffer()->params().track_changes);
        cur.checkBufferStructure();
 
 //             cur.screenUpdateFlags(Update::Force);
        bool boundary = cur.boundary()
-               || tm.isRTLBoundary(cur.pit(), cur.pos() + 1);
-       setCursor(cur, cur.pit(), cur.pos() + 1, false, boundary);
+               || tm.isRTLBoundary(cur.pit(), pos + 1);
+       setCursor(cur, cur.pit(), pos + 1, false, boundary);
        charInserted(cur);
 }
 
@@ -1035,15 +1081,6 @@ void Text::charInserted(Cursor & cur)
 {
        Paragraph & par = cur.paragraph();
 
-       // Here we call finishUndo for every 20 characters inserted.
-       // This is from my experience how emacs does it. (Lgb)
-       if (undo_counter_ < 20) {
-               ++undo_counter_;
-       } else {
-               cur.finishUndo();
-               undo_counter_ = 0;
-       }
-
        // register word if a non-letter was entered
        if (cur.pos() > 1
            && !par.isWordSeparator(cur.pos() - 2)
@@ -2057,11 +2094,11 @@ void Text::charsTranspose(Cursor & cur)
 
        // Store the characters to be transposed (including font information).
        char_type const char1 = par.getChar(pos1);
-       Font const font1 =
+       Font const font1 =
                par.getFontSettings(cur.buffer()->params(), pos1);
 
        char_type const char2 = par.getChar(pos2);
-       Font const font2 =
+       Font const font2 =
                par.getFontSettings(cur.buffer()->params(), pos2);
 
        // And finally, we are ready to perform the transposition.