add support for TABs in Listings, fileformat change, fixes http://bugzilla.lyx.org/show_bug.cgi?id=3629 , patch by Vincent, lyx2lyx and UI stuff by me

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26647 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Uwe Stöhr 2008-09-30 18:00:02 +00:00
parent ede2dbfade
commit 7382c55fd7
10 changed files with 333 additions and 177 deletions

View File

@ -1,6 +1,9 @@
LyX file-format changes
-----------------------
2008-09-30 Uwe Stöhr <uwestoehr@web.de>
* Format incremented to 341: support for TABs in listings".
2008-08-01 José Matos <jamatos@fc.up.pt>
* Format incremented to 340: move empty layouts to "Plain Layout".
@ -1023,5 +1026,3 @@ renamed as "size_kind" and "lyxsize_kind" respectively.
\end_inset

View File

@ -2906,6 +2906,37 @@ def add_plain_layout(document):
document.body[i] = "\\begin_layout Plain Layout"
i += 1
def revert_tabulators(document):
"Revert tabulators to 4 spaces"
i = 0
while True:
i = find_token(document.body, "\t", i)
if i == -1:
return
document.body[i] = document.body[i].replace("\t", " ")
i += 1
def revert_tabsize(document):
"Revert the tabsize parameter of listings"
i = 0
j = 0
while True:
# either it is the only parameter
i = find_token(document.body, 'lstparams "tabsize=4"', i)
if i != -1:
del document.body[i]
# or the last one
j = find_token(document.body, "lstparams", j)
if j == -1:
return
pos = document.body[j].find(",tabsize=")
document.body[j] = document.body[j][:pos] + '"'
i += 1
j += 1
##
# Conversion hub
#
@ -2974,10 +3005,12 @@ convert = [[277, [fix_wrong_tables]],
[337, [convert_display_enum]],
[338, []],
[339, []],
[340, [add_plain_layout]]
[340, [add_plain_layout]],
[341, []]
]
revert = [[339, []],
revert = [[340, [revert_tabulators, revert_tabsize]],
[339, []],
[338, [revert_removed_modules]],
[337, [revert_polytonicgreek]],
[336, [revert_display_enum]],

View File

@ -115,7 +115,7 @@ namespace os = support::os;
namespace {
int const LYX_FORMAT = 340; //jamatos: add plain layout
int const LYX_FORMAT = 341; //uwestoehr: TAB support for listings
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@ -619,11 +619,8 @@ void Buffer::insertStringAsLines(ParagraphList & pars,
++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)) {

View File

@ -499,7 +499,7 @@ bool Lexer::Pimpl::nextToken()
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 @@ bool Lexer::Pimpl::nextToken()
buff.push_back(c);
is.get(cc);
c = cc;
} while (c >= ' ' && c != '\\' && is);
} while ((c >= ' ' || c == '\t') && c != '\\' && is);
}
if (c == '\\')

View File

@ -2396,7 +2396,7 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options) const
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);

View File

@ -220,6 +220,9 @@ int ParagraphMetrics::singleWidth(pos_type pos, Font const & font) const
char_type c = par_->getChar(pos);
if (c == '\t')
return 4 * theFontMetrics(font).width(' ');
if (!isPrintable(c))
return theFontMetrics(font).width(c);

View File

@ -20,6 +20,7 @@
#include "insets/InsetListings.h"
#include "insets/InsetListingsParams.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/gettext.h"
#include "support/lstrings.h"
@ -198,6 +199,8 @@ GuiListings::GuiListings(GuiView & lv)
this, SLOT(change_adaptor()));
connect(spaceInStringCB, SIGNAL(clicked()),
this, SLOT(change_adaptor()));
connect(tabsizeSB, SIGNAL(valueChanged(int)),
this, SLOT(change_adaptor()));
connect(extendedcharsCB, SIGNAL(clicked()),
this, SLOT(change_adaptor()));
@ -296,6 +299,7 @@ string GuiListings::construct_params()
basicstyle += "\\" + fontstyle;
bool breakline = breaklinesCB->isChecked();
bool space = spaceCB->isChecked();
int tabsize = tabsizeSB->value();
bool spaceInString = spaceInStringCB->isChecked();
bool extendedchars = extendedcharsCB->isChecked();
string extra = fromqstr(listingsED->toPlainText());
@ -331,6 +335,8 @@ string GuiListings::construct_params()
par.addParam("showspaces", "true");
if (!spaceInString)
par.addParam("showstringspaces", "false");
if (tabsize != 8)
par.addParam("tabsize", convert<string>(tabsize));
if (extendedchars)
par.addParam("extendedchars", "true");
par.addParams(extra);
@ -456,6 +462,7 @@ void GuiListings::updateContents()
breaklinesCB->setChecked(false);
spaceCB->setChecked(false);
spaceInStringCB->setChecked(true);
tabsizeSB->setValue(8);
extendedcharsCB->setChecked(false);
// set values from param string
@ -583,6 +590,9 @@ void GuiListings::updateContents()
} else if (prefixIs(*it, "showstringspaces=")) {
spaceInStringCB->setChecked(contains(*it, "true"));
*it = "";
} else if (prefixIs(*it, "tabsize=")) {
tabsizeSB->setValue(convert<int>(plainParam(it->substr(8))));
*it = "";
} else if (prefixIs(*it, "extendedchars=")) {
extendedcharsCB->setChecked(contains(*it, "true"));
*it = "";

View File

@ -8,8 +8,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>612</width>
<height>317</height>
<width>654</width>
<height>349</height>
</rect>
</property>
<property name="windowTitle" >
@ -28,9 +28,7 @@
<item row="0" column="0" >
<widget class="QTabWidget" name="listingsTW" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -49,150 +47,6 @@
<property name="spacing" >
<number>6</number>
</property>
<item rowspan="2" row="0" column="2" >
<widget class="QGroupBox" name="basicstyleGB" >
<property name="title" >
<string>Style</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="1" >
<widget class="QComboBox" name="fontsizeCO" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip" >
<string>The content's base font size</string>
</property>
<property name="editable" >
<bool>false</bool>
</property>
<property name="autoCompletion" >
<bool>true</bool>
</property>
<property name="duplicatesEnabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="fontsize_label_3" >
<property name="text" >
<string>F&amp;ont size:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>fontsizeCO</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="fontstyleCO" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip" >
<string>The content's base font style</string>
</property>
<property name="editable" >
<bool>false</bool>
</property>
<property name="autoCompletion" >
<bool>true</bool>
</property>
<property name="duplicatesEnabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="fontstyle_label_3" >
<property name="text" >
<string>Font Famil&amp;y:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>fontstyleCO</cstring>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2" >
<widget class="QCheckBox" name="extendedcharsCB" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="toolTip" >
<string>Use extended character table</string>
</property>
<property name="text" >
<string>&amp;Extended character table</string>
</property>
<property name="shortcut" >
<number>276824133</number>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2" >
<widget class="QCheckBox" name="spaceInStringCB" >
<property name="toolTip" >
<string>Make spaces in strings visible by a special symbol</string>
</property>
<property name="text" >
<string>Space i&amp;n string as symbol</string>
</property>
<property name="shortcut" >
<number>276824147</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QCheckBox" name="spaceCB" >
<property name="toolTip" >
<string>Make spaces visible by a special symbol</string>
</property>
<property name="text" >
<string>S&amp;pace as symbol</string>
</property>
<property name="shortcut" >
<number>276824147</number>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QCheckBox" name="breaklinesCB" >
<property name="toolTip" >
<string>Break lines longer than the linewidth</string>
</property>
<property name="text" >
<string>&amp;Break long lines</string>
</property>
<property name="shortcut" >
<number>276824130</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" >
<widget class="QGroupBox" name="placementGB" >
<property name="title" >
@ -285,9 +139,7 @@
<item row="2" column="1" >
<widget class="QComboBox" name="numberFontSizeCO" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -478,6 +330,175 @@
</widget>
</item>
</layout>
<zorder>numberfontsizeL_2</zorder>
<zorder>lastlineLE</zorder>
<zorder>firstlineLE</zorder>
<zorder>numberfontsizeL_3</zorder>
<zorder>basicstyleGB</zorder>
</widget>
</item>
<item rowspan="2" row="0" column="2" >
<widget class="QGroupBox" name="basicstyleGB" >
<property name="title" >
<string>Style</string>
</property>
<layout class="QGridLayout" >
<property name="sizeConstraint" >
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QLabel" name="fontsize_label_3" >
<property name="text" >
<string>F&amp;ont size:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>fontsizeCO</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="fontsizeCO" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip" >
<string>The content's base font size</string>
</property>
<property name="editable" >
<bool>false</bool>
</property>
<property name="autoCompletion" >
<bool>true</bool>
</property>
<property name="duplicatesEnabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="fontstyle_label_3" >
<property name="text" >
<string>Font Famil&amp;y:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
<property name="buddy" >
<cstring>fontstyleCO</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="fontstyleCO" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip" >
<string>The content's base font style</string>
</property>
<property name="editable" >
<bool>false</bool>
</property>
<property name="autoCompletion" >
<bool>true</bool>
</property>
<property name="duplicatesEnabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QCheckBox" name="breaklinesCB" >
<property name="toolTip" >
<string>Break lines longer than the linewidth</string>
</property>
<property name="text" >
<string>&amp;Break long lines</string>
</property>
<property name="shortcut" >
<number>276824130</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QCheckBox" name="spaceCB" >
<property name="toolTip" >
<string>Make spaces visible by a special symbol</string>
</property>
<property name="text" >
<string>S&amp;pace as symbol</string>
</property>
<property name="shortcut" >
<number>276824147</number>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2" >
<widget class="QCheckBox" name="spaceInStringCB" >
<property name="toolTip" >
<string>Make spaces in strings visible by a special symbol</string>
</property>
<property name="text" >
<string>Space i&amp;n string as symbol</string>
</property>
<property name="shortcut" >
<number>276824147</number>
</property>
</widget>
</item>
<item row="6" column="0" >
<widget class="QLabel" name="tabsizeL" >
<property name="text" >
<string>Tabulator size</string>
</property>
</widget>
</item>
<item row="6" column="1" >
<widget class="QSpinBox" name="tabsizeSB" />
</item>
<item row="7" column="0" colspan="2" >
<widget class="QCheckBox" name="extendedcharsCB" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="toolTip" >
<string>Use extended character table</string>
</property>
<property name="text" >
<string>&amp;Extended character table</string>
</property>
<property name="shortcut" >
<number>276824133</number>
</property>
</widget>
</item>
</layout>
<zorder>fontsizeCO</zorder>
<zorder>fontsize_label_3</zorder>
<zorder>fontstyleCO</zorder>
<zorder>fontstyle_label_3</zorder>
<zorder>extendedcharsCB</zorder>
<zorder>spaceCB</zorder>
<zorder>breaklinesCB</zorder>
<zorder>label_2</zorder>
<zorder>tabsizeL</zorder>
<zorder>tabsizeSB</zorder>
<zorder>horizontalSpacer</zorder>
</widget>
</item>
</layout>
@ -496,9 +517,7 @@
<item row="0" column="0" >
<widget class="QGroupBox" name="listingsGB" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -535,8 +554,8 @@
<height>16777215</height>
</size>
</property>
<property name="cursor" >
<cursor>0</cursor>
<property name="cursor" stdset="0" >
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="acceptDrops" >
<bool>false</bool>
@ -556,9 +575,7 @@
</widget>
<widget class="QTextEdit" name="listingsED" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -578,12 +595,12 @@
</item>
<item row="1" column="0" >
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation" >
@ -592,7 +609,7 @@
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0" >
<size>
<width>221</width>
<height>27</height>

View File

@ -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 @@ void InsetListings::doDispatch(Cursor & cur, FuncRequest & cmd)
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 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd,
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);
}

View File

@ -246,6 +246,7 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font,
// 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 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font,
char_type c = par_.getChar(pos);
if (c == '\t' || prev_char == '\t') {
prev_char = c;
break;
}
if (!isPrintableNonspace(c))
break;
@ -308,6 +314,9 @@ void RowPainter::paintChars(pos_type & vpos, FontInfo const & font,
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;