- Ausrücken mit Shift-Tab implementiert
- RÜcksprung mit Backspace implementiert - Anzeige für veränderte Datei implementiert
This commit is contained in:
@@ -269,19 +269,77 @@ void CodeEditor::highlightCurrentLine()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Key handling – auto-indent + Tab → spaces
|
||||
// Key handling – Tab/Shift+Tab, Smart-Backspace, Auto-Indent
|
||||
// ---------------------------------------------------------------------------
|
||||
void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
// Tab key: insert spaces instead of a real tab character
|
||||
if (event->key() == Qt::Key_Tab && m_settings->useSpacesForTabs())
|
||||
const int tabSize = m_settings->tabSize();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Shift+Tab: Einrückung zurückziehen
|
||||
// -----------------------------------------------------------------------
|
||||
if (event->key() == Qt::Key_Backtab ||
|
||||
(event->key() == Qt::Key_Tab && event->modifiers() & Qt::ShiftModifier))
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
|
||||
QTextBlock startBlock = document()->findBlock(cursor.selectionStart());
|
||||
QTextBlock endBlock = document()->findBlock(cursor.selectionEnd());
|
||||
|
||||
cursor.beginEditBlock();
|
||||
for (QTextBlock b = startBlock; b != endBlock.next(); b = b.next())
|
||||
{
|
||||
const QString lineText = b.text();
|
||||
int toRemove = 0;
|
||||
|
||||
if (m_settings->useSpacesForTabs())
|
||||
{
|
||||
// Bis zu tabSize führende Leerzeichen entfernen
|
||||
for (int i = 0; i < tabSize && i < lineText.length(); ++i)
|
||||
{
|
||||
if (lineText[i] == ' ')
|
||||
{
|
||||
++toRemove;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Einen führenden Tab entfernen
|
||||
if (!lineText.isEmpty() && lineText[0] == '\t')
|
||||
{
|
||||
toRemove = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (toRemove > 0)
|
||||
{
|
||||
QTextCursor lineCursor(b);
|
||||
lineCursor.movePosition(QTextCursor::StartOfBlock);
|
||||
lineCursor.movePosition(QTextCursor::Right,
|
||||
QTextCursor::KeepAnchor,
|
||||
toRemove);
|
||||
lineCursor.removeSelectedText();
|
||||
}
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Tab: Einrücken (Leerzeichen oder echter Tab)
|
||||
// -----------------------------------------------------------------------
|
||||
if (event->key() == Qt::Key_Tab)
|
||||
{
|
||||
const int tabSize = m_settings->tabSize();
|
||||
QTextCursor cursor = textCursor();
|
||||
|
||||
if (cursor.hasSelection())
|
||||
{
|
||||
// Indent selected lines
|
||||
// Mehrere Zeilen einrücken
|
||||
QTextBlock startBlock = document()->findBlock(cursor.selectionStart());
|
||||
QTextBlock endBlock = document()->findBlock(cursor.selectionEnd());
|
||||
|
||||
@@ -289,27 +347,76 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
for (QTextBlock b = startBlock; b != endBlock.next(); b = b.next())
|
||||
{
|
||||
QTextCursor lineCursor(b);
|
||||
lineCursor.insertText(QString(tabSize, ' '));
|
||||
lineCursor.movePosition(QTextCursor::StartOfBlock);
|
||||
if (m_settings->useSpacesForTabs())
|
||||
{
|
||||
lineCursor.insertText(QString(tabSize, ' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
lineCursor.insertText("\t");
|
||||
}
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate spaces needed to reach next tab stop
|
||||
const int col = cursor.columnNumber();
|
||||
const int spacesNeeded = tabSize - (col % tabSize);
|
||||
cursor.insertText(QString(spacesNeeded, ' '));
|
||||
if (m_settings->useSpacesForTabs())
|
||||
{
|
||||
// Zum nächsten Tab-Stop auffüllen
|
||||
const int col = cursor.columnNumber();
|
||||
const int spacesNeeded = tabSize - (col % tabSize);
|
||||
cursor.insertText(QString(spacesNeeded, ' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.insertText("\t");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Enter / Return: auto-indent
|
||||
// -----------------------------------------------------------------------
|
||||
// Smart Backspace: springt zur vorherigen Einrückungsstufe
|
||||
// -----------------------------------------------------------------------
|
||||
if (event->key() == Qt::Key_Backspace
|
||||
&& !textCursor().hasSelection()
|
||||
&& m_settings->useSpacesForTabs())
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
const int col = cursor.columnNumber();
|
||||
|
||||
if (col > 0)
|
||||
{
|
||||
// Prüfen ob links vom Cursor nur Leerzeichen bis Zeilenbeginn stehen
|
||||
const QString lineText = cursor.block().text();
|
||||
const QString leftOfCursor = lineText.left(col);
|
||||
const bool onlySpaces = leftOfCursor.trimmed().isEmpty();
|
||||
|
||||
if (onlySpaces && col > 0)
|
||||
{
|
||||
// Zur vorherigen Tab-Stop-Position springen
|
||||
const int targetCol = ((col - 1) / tabSize) * tabSize;
|
||||
const int toDelete = col - targetCol;
|
||||
|
||||
cursor.movePosition(QTextCursor::Left,
|
||||
QTextCursor::KeepAnchor,
|
||||
toDelete);
|
||||
cursor.removeSelectedText();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Enter / Return: Auto-Indent
|
||||
// -----------------------------------------------------------------------
|
||||
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
const QString currentLine = cursor.block().text();
|
||||
|
||||
// Count leading whitespace
|
||||
// Führende Leerzeichen der aktuellen Zeile zählen
|
||||
int leadingSpaces = 0;
|
||||
for (const QChar &ch : currentLine)
|
||||
{
|
||||
@@ -319,7 +426,7 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
}
|
||||
else if (ch == '\t')
|
||||
{
|
||||
leadingSpaces += m_settings->tabSize();
|
||||
leadingSpaces += tabSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -327,15 +434,13 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
// Let the base class insert the newline first
|
||||
QPlainTextEdit::keyPressEvent(event);
|
||||
|
||||
// Then re-indent
|
||||
if (leadingSpaces > 0)
|
||||
{
|
||||
const QString indent = m_settings->useSpacesForTabs()
|
||||
? QString(leadingSpaces, ' ')
|
||||
: QString(leadingSpaces / m_settings->tabSize(), '\t');
|
||||
: QString(leadingSpaces / tabSize, '\t');
|
||||
textCursor().insertText(indent);
|
||||
}
|
||||
return;
|
||||
@@ -343,3 +448,4 @@ void CodeEditor::keyPressEvent(QKeyEvent *event)
|
||||
|
||||
QPlainTextEdit::keyPressEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "SearchPanel.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QTextDocument>
|
||||
|
||||
EditorPanel::EditorPanel(Settings *settings, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -70,7 +71,20 @@ void EditorPanel::openFile(const QString &filePath)
|
||||
m_tabWidget->setTabToolTip(index, filePath);
|
||||
m_openTabs.insert(filePath, tab);
|
||||
|
||||
// Tab-Titel nach "Speichern unter" aktualisieren
|
||||
// Änderungsindikator im Tab-Titel (● = ungespeichert)
|
||||
connect(tab->editor()->document(), &QTextDocument::modificationChanged,
|
||||
this, [this, tab](bool modified)
|
||||
{
|
||||
const int idx = m_tabWidget->indexOf(tab);
|
||||
if (idx == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const QString name = QFileInfo(tab->filePath()).fileName();
|
||||
m_tabWidget->setTabText(idx, modified ? "● " + name : name);
|
||||
});
|
||||
|
||||
// Tab-Titel nach "Speichern unter" aktualisieren (neuer Dateiname, kein Punkt)
|
||||
connect(tab->editor(), &CodeEditor::fileSaved, this, [this, tab](const QString &savedPath)
|
||||
{
|
||||
const int idx = m_tabWidget->indexOf(tab);
|
||||
|
||||
Reference in New Issue
Block a user