>> Pavel Sanda wrote: >> >> i just tried this patch and seems to work correctly.
Works fine for me too. Attached is the patch against current trunk. >> if there are no other comments, i'll put it in. >> lfuns will be sorted later. > > I wonder if something needs to be done on reversion to 1.5.x. IOW, is this a > file format change?This is not really a fileformat change. When you revert a listing to LyX 1.5, the TABs will be erased as LyX 1.5 doesn't support TABs. But what I can do is to try to convert the TABs via lyx2lyx to 4 spaces. Should I do this? If not, the patch should go in, if yes I'll try to provide a lyx2lyx patch.
Attached is a LyX testfile generated with the new TAB support to test lyx2lyx. regards Uwe
Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (revision 26575) +++ src/Buffer.cpp (working copy) @@ -619,11 +619,8 @@ ++pos; space_inserted = true; } else { - const pos_type n = 8 - pos % 8; - for (pos_type i = 0; i < n; ++i) { - par.insertChar(pos, ' ', font, params().trackChanges); - ++pos; - } + par.insertChar(pos, *cit, font, params().trackChanges); + ++pos; space_inserted = true; } } else if (!isPrintable(*cit)) { Index: src/insets/InsetListings.cpp =================================================================== --- src/insets/InsetListings.cpp (revision 26575) +++ src/insets/InsetListings.cpp (working copy) @@ -33,6 +33,7 @@ #include "support/docstream.h" #include "support/gettext.h" #include "support/lstrings.h" +#include "support/lassert.h" #include "frontends/alert.h" #include "frontends/Application.h" @@ -289,6 +290,87 @@ case LFUN_INSET_DIALOG_UPDATE: cur.bv().updateDialog("listings", params2string(params())); break; + case LFUN_CELL_FORWARD: + if (cur.selection()) { + // If there is a selection, a tab is inserted at the + // beginning of each paragraph. + cur.recordUndoSelection(); + pit_type const pit_end = cur.selEnd().pit(); + for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) { + LASSERT(pit < paragraphs().size(), /**/); + paragraphs()[pit].insertChar(0, '\t', + buffer().params().trackChanges); + // Update the selection pos to make sure the selection does not + // change as the inserted tab will increase the logical pos. + if (cur.anchor_.pit() == pit) + cur.anchor_.forwardPos(); + if (cur.pit() == pit) + cur.forwardPos(); + } + cur.finishUndo(); + } else { + // Maybe we shouldn't allow tabs within a line, because they + // are not (yet) aligned as one might do expect. + cur.recordUndo(); + cur.insert(from_ascii("\t")); + cur.finishUndo(); + } + break; + case LFUN_CELL_BACKWARD: + if (cur.selection()) { + // If there is a selection, a tab (if present) is removed from + // the beginning of each paragraph. + cur.recordUndoSelection(); + pit_type const pit_end = cur.selEnd().pit(); + for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) { + LASSERT( pit < paragraphs().size(), /**/ ); + Paragraph & par = paragraphs()[pit]; + if (par.getChar(0) == '\t') { + if (cur.pit() == pit) + cur.posBackward(); + if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 ) + cur.anchor_.backwardPos(); + + par.eraseChar(0, buffer().params().trackChanges); + } else + // If no tab was present, try to remove up to four spaces. + for (int n_spaces = 0; + par.getChar(0) == ' ' && n_spaces < 4; ++n_spaces) { + if (cur.pit() == pit) + cur.posBackward(); + if (cur.anchor_.pit() == pit && cur.anchor_.pos() > 0 ) + cur.anchor_.backwardPos(); + + par.eraseChar(0, buffer().params().trackChanges); + } + } + cur.finishUndo(); + } else { + // If there is no selection, try to remove a tab or some spaces + // before the position of the cursor. + LASSERT(cur.pit() >= 0 && cur.pit() < paragraphs().size(), /**/); + + Paragraph & par = paragraphs()[cur.pit()]; + pos_type const pos = cur.pos(); + + if (pos == 0) + break; + + char_type const c = par.getChar(pos - 1); + cur.recordUndo(); + if (c == '\t') { + cur.posBackward(); + par.eraseChar(cur.pos(), buffer().params().trackChanges); + } else + for (int n_spaces = 0; cur.pos() > 0 + && par.getChar(cur.pos() - 1) == ' ' && n_spaces < 4; + ++n_spaces) { + cur.posBackward(); + par.eraseChar(cur.pos(), buffer().params().trackChanges); + } + cur.finishUndo(); + } + break; default: InsetCollapsable::doDispatch(cur, cmd); break; @@ -307,6 +389,10 @@ case LFUN_CAPTION_INSERT: status.setEnabled(!params().isInline()); return true; + case LFUN_CELL_BACKWARD: + case LFUN_CELL_FORWARD: + status.setEnabled(true); + return true; default: return InsetCollapsable::getStatus(cur, cmd, status); } Index: src/Lexer.cpp =================================================================== --- src/Lexer.cpp (revision 26575) +++ src/Lexer.cpp (working copy) @@ -499,7 +499,7 @@ char cc = 0; is.get(cc); c = cc; - if (c >= ' ' && is) { + if ((c >= ' ' || c == '\t') && is) { buff.clear(); if (c == '\\') { // first char == '\\' @@ -513,7 +513,7 @@ buff.push_back(c); is.get(cc); c = cc; - } while (c >= ' ' && c != '\\' && is); + } while ((c >= ' ' || c == '\t') && c != '\\' && is); } if (c == '\\') Index: src/Paragraph.cpp =================================================================== --- src/Paragraph.cpp (revision 26575) +++ src/Paragraph.cpp (working copy) @@ -2389,7 +2389,7 @@ for (pos_type i = beg; i < end; ++i) { char_type const c = d->text_[i]; - if (isPrintable(c)) + if (isPrintable(c) || c == '\t') os.put(c); else if (c == META_INSET && options & AS_STR_INSETS) getInset(i)->textString(os); Index: src/ParagraphMetrics.cpp =================================================================== --- src/ParagraphMetrics.cpp (revision 26575) +++ src/ParagraphMetrics.cpp (working copy) @@ -220,6 +220,9 @@ char_type c = par_->getChar(pos); + if (c == '\t') + return 4 * theFontMetrics(font).width(' '); + if (!isPrintable(c)) return theFontMetrics(font).width(c); Index: src/rowpainter.cpp =================================================================== --- src/rowpainter.cpp (revision 26575) +++ src/rowpainter.cpp (working copy) @@ -246,6 +246,7 @@ // selected text? bool const selection = pos >= row_.sel_beg && pos < row_.sel_end; + char_type prev_char = ' '; // collect as much similar chars as we can for (++vpos ; vpos < end ; ++vpos) { pos = bidi_.vis2log(vpos); @@ -264,6 +265,11 @@ char_type c = par_.getChar(pos); + if (c == '\t' || prev_char == '\t') { + prev_char = c; + break; + } + if (!isPrintableNonspace(c)) break; @@ -308,6 +314,9 @@ docstring s(&str[0], str.size()); + if (s[0] == '\t') + s.replace(0,1,from_ascii(" ")); + if (!selection && !change_running.changed()) { x_ += pi_.pain.text(int(x_), yo_, s, font); return;
newfile2.lyx
Description: application/lyx