Commit ffd19fe8 authored by Joel Nordell's avatar Joel Nordell
Browse files

XCode-style tab behavior

parent bb6f56f5
......@@ -845,11 +845,22 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
} break;
#endif
case Qt::Key_Tab:
case Qt::Key_Backtab:
case Qt::Key_Backtab: {
if (ro) break;
QTextCursor cursor = textCursor();
int newPosition;
if (d->m_document->tabSettings().tabShouldIndent(document(), cursor, &newPosition)) {
if (newPosition != cursor.position() && !cursor.hasSelection()) {
cursor.setPosition(newPosition);
setTextCursor(cursor);
}
indent(document(), cursor, QChar::Null);
} else {
indentOrUnindent(e->key() == Qt::Key_Tab);
}
e->accept();
return;
} break;
case Qt::Key_Backspace:
if (ro) break;
if (d->m_document->tabSettings().m_smartBackspace
......
......@@ -133,6 +133,7 @@ void BehaviorSettingsPage::settingsFromUI(TabSettings &tabSettings,
tabSettings.m_smartBackspace = m_d->m_page.smartBackspace->isChecked();
tabSettings.m_tabSize = m_d->m_page.tabSize->value();
tabSettings.m_indentSize = m_d->m_page.indentSize->value();
tabSettings.m_tabKeyBehavior = (TabSettings::TabKeyBehavior)m_d->m_page.tabKeyBehavior->currentIndex();
storageSettings.m_cleanWhitespace = m_d->m_page.cleanWhitespace->isChecked();
storageSettings.m_inEntireDocument = m_d->m_page.inEntireDocument->isChecked();
......@@ -148,6 +149,7 @@ void BehaviorSettingsPage::settingsToUI()
m_d->m_page.smartBackspace->setChecked(tabSettings.m_smartBackspace);
m_d->m_page.tabSize->setValue(tabSettings.m_tabSize);
m_d->m_page.indentSize->setValue(tabSettings.m_indentSize);
m_d->m_page.tabKeyBehavior->setCurrentIndex(tabSettings.m_tabKeyBehavior);
const StorageSettings &storageSettings = m_d->m_storageSettings;
m_d->m_page.cleanWhitespace->setChecked(storageSettings.m_cleanWhitespace);
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>428</width>
<height>325</height>
<width>615</width>
<height>367</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
......@@ -122,6 +122,29 @@
<string>Tabs and Indentation</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="insertSpaces">
<property name="text">
<string>Insert &amp;spaces instead of tabs</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
......@@ -184,6 +207,13 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="autoIndent">
<property name="text">
<string>Enable automatic &amp;indentation</string>
</property>
</widget>
</item>
<item row="1" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
......@@ -233,7 +263,7 @@
</item>
</layout>
</item>
<item row="3" column="0">
<item row="2" column="0">
<widget class="QCheckBox" name="smartBackspace">
<property name="toolTip">
<string>Backspace will go back one indentation level instead of one space.</string>
......@@ -243,8 +273,36 @@
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_5">
<item row="3" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Tab key performs auto-indent:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="tabKeyBehavior">
<item>
<property name="text">
<string>Never</string>
</property>
</item>
<item>
<property name="text">
<string>Always</string>
</property>
</item>
<item>
<property name="text">
<string>In leading white space</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
......@@ -253,25 +311,13 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>10</height>
<width>31</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="insertSpaces">
<property name="text">
<string>Insert &amp;spaces instead of tabs</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="autoIndent">
<property name="text">
<string>Enable automatic &amp;indentation</string>
</property>
</widget>
</layout>
</item>
</layout>
</widget>
......
......@@ -40,6 +40,7 @@ static const char *smartBackspaceKey = "SmartBackspace";
static const char *autoIndentKey = "AutoIndent";
static const char *tabSizeKey = "TabSize";
static const char *indentSizeKey = "IndentSize";
static const char *tabKeyBehaviorKey = "TabKeyBehavior";
static const char *groupPostfix = "TabSettings";
namespace TextEditor {
......@@ -49,7 +50,8 @@ TabSettings::TabSettings() :
m_autoIndent(true),
m_smartBackspace(false),
m_tabSize(8),
m_indentSize(4)
m_indentSize(4),
m_tabKeyBehavior(TabNeverIndents)
{
}
......@@ -64,6 +66,7 @@ void TabSettings::toSettings(const QString &category, QSettings *s) const
s->setValue(QLatin1String(smartBackspaceKey), m_smartBackspace);
s->setValue(QLatin1String(tabSizeKey), m_tabSize);
s->setValue(QLatin1String(indentSizeKey), m_indentSize);
s->setValue(QLatin1String(tabKeyBehaviorKey), m_tabKeyBehavior);
s->endGroup();
}
......@@ -81,6 +84,7 @@ void TabSettings::fromSettings(const QString &category, const QSettings *s)
m_smartBackspace = s->value(group + QLatin1String(smartBackspaceKey), m_smartBackspace).toBool();
m_tabSize = s->value(group + QLatin1String(tabSizeKey), m_tabSize).toInt();
m_indentSize = s->value(group + QLatin1String(indentSizeKey), m_indentSize).toInt();
m_tabKeyBehavior = (TabKeyBehavior)s->value(group + QLatin1String(tabKeyBehaviorKey), m_tabKeyBehavior).toInt();
}
int TabSettings::lineIndentPosition(const QString &text) const
......@@ -140,6 +144,28 @@ bool TabSettings::isIndentationClean(const QString &text) const
return true;
}
bool TabSettings::tabShouldIndent(const QTextDocument *document, QTextCursor cursor, int *suggestedPosition) const
{
if (m_tabKeyBehavior == TabNeverIndents)
return false;
QTextCursor tc = cursor;
if (suggestedPosition)
*suggestedPosition = tc.position(); // At least suggest original position
tc.movePosition(QTextCursor::StartOfLine);
if (tc.atBlockEnd()) // cursor was on a blank line
return true;
if (document->characterAt(tc.position()).isSpace()) {
tc.movePosition(QTextCursor::WordRight);
if (tc.columnNumber() >= cursor.columnNumber()) {
if (suggestedPosition)
*suggestedPosition = tc.position(); // Suggest position after whitespace
if (m_tabKeyBehavior == TabLeadingWhitespaceIndents)
return true;
}
}
return (m_tabKeyBehavior == TabAlwaysIndents);
}
int TabSettings::columnAt(const QString &text, int position) const
{
int column = 0;
......@@ -229,7 +255,8 @@ bool TabSettings::equals(const TabSettings &ts) const
&& m_autoIndent == ts.m_autoIndent
&& m_smartBackspace == ts.m_smartBackspace
&& m_tabSize == ts.m_tabSize
&& m_indentSize == ts.m_indentSize;
&& m_indentSize == ts.m_indentSize
&& m_tabKeyBehavior == ts.m_tabKeyBehavior;
}
} // namespace TextEditor
......@@ -44,6 +44,13 @@ namespace TextEditor {
// with some convenience functions for formatting.
struct TEXTEDITOR_EXPORT TabSettings
{
// This enum must match the indexes of tabKeyBehavior widget
enum TabKeyBehavior {
TabNeverIndents = 0,
TabAlwaysIndents = 1,
TabLeadingWhitespaceIndents = 2
};
TabSettings();
void toSettings(const QString &category, QSettings *s) const;
......@@ -61,13 +68,14 @@ struct TEXTEDITOR_EXPORT TabSettings
int trailingWhitespaces(const QString &text) const;
bool isIndentationClean(const QString &text) const;
bool tabShouldIndent(const QTextDocument *document, QTextCursor cursor, int *suggestedPosition = 0) const;
bool m_spacesForTabs;
bool m_autoIndent;
bool m_smartBackspace;
int m_tabSize;
int m_indentSize;
TabKeyBehavior m_tabKeyBehavior;
bool equals(const TabSettings &ts) const;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment