diff --git a/client/src/widget/propertyluacodeedit.cpp b/client/src/widget/propertyluacodeedit.cpp index 2dd9ccab..ef302322 100644 --- a/client/src/widget/propertyluacodeedit.cpp +++ b/client/src/widget/propertyluacodeedit.cpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2019-2021,2024 Reinder Feenstra + * Copyright (C) 2019-2025 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,6 +26,12 @@ #include #include +namespace { + +const auto indent = QStringLiteral(" "); + +} + PropertyLuaCodeEdit::PropertyLuaCodeEdit(Property& property, QWidget* parent) : QPlainTextEdit(parent), m_property{property}, @@ -91,6 +97,29 @@ void PropertyLuaCodeEdit::updateViewportMargins() setViewportMargins(calcLineNumbersWidth(), 0, 0, 0); } +void PropertyLuaCodeEdit::keyPressEvent(QKeyEvent* event) +{ + const bool shiftModifier = (event->modifiers() & Qt::ShiftModifier); + if(event->key() == Qt::Key_Tab && !shiftModifier) + { + if(textCursor().hasSelection()) + { + indentSelection(); + } + else + { + textCursor().insertText(indent); + } + return; + } + if(event->key() == Qt::Key_Backtab || (event->key() == Qt::Key_Tab && shiftModifier)) + { + unindentSelection(); + return; + } + QPlainTextEdit::keyPressEvent(event); +} + void PropertyLuaCodeEdit::resizeEvent(QResizeEvent* event) { QPlainTextEdit::resizeEvent(event); @@ -125,6 +154,67 @@ void PropertyLuaCodeEdit::paintLineNumbers(QPaintEvent* event) } } +void PropertyLuaCodeEdit::indentSelection() +{ + QTextCursor cursor = textCursor(); + + if(!cursor.hasSelection()) + { + return; + } + + cursor.beginEditBlock(); + + const int start = cursor.selectionStart(); + int end = cursor.selectionEnd(); + + cursor.setPosition(start); + cursor.movePosition(QTextCursor::StartOfLine); + + while(cursor.position() < end) + { + cursor.insertText(indent); + end += indent.size(); + cursor.movePosition(QTextCursor::Down); + cursor.movePosition(QTextCursor::StartOfLine); + } + + cursor.endEditBlock(); +} + +void PropertyLuaCodeEdit::unindentSelection() +{ + QTextCursor cursor = textCursor(); + + cursor.beginEditBlock(); + + const int start = cursor.selectionStart(); + int end = cursor.selectionEnd(); + + cursor.setPosition(start); + cursor.movePosition(QTextCursor::StartOfLine); + + while(cursor.position() < end) + { + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, indent.size()); + const QString leading = cursor.selectedText(); + cursor.movePosition(QTextCursor::StartOfLine); + for(auto c : leading) + { + if(c != ' ') + { + break; + } + cursor.deleteChar(); + end--; + } + cursor.clearSelection(); + cursor.movePosition(QTextCursor::Down); + } + + cursor.endEditBlock(); +} + PropertyLuaCodeEdit::LineNumbers::LineNumbers(PropertyLuaCodeEdit* parent) : QWidget(parent) diff --git a/client/src/widget/propertyluacodeedit.hpp b/client/src/widget/propertyluacodeedit.hpp index 350e21cf..6c31c1af 100644 --- a/client/src/widget/propertyluacodeedit.hpp +++ b/client/src/widget/propertyluacodeedit.hpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2019-2020 Reinder Feenstra + * Copyright (C) 2019-2025 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -80,12 +80,16 @@ class PropertyLuaCodeEdit : public QPlainTextEdit Highlighter(QTextDocument* parent = nullptr); }; + void indentSelection(); + void unindentSelection(); + protected: Property& m_property; LineNumbers* m_lineNumbers; int calcLineNumbersWidth() const; void updateViewportMargins(); + void keyPressEvent(QKeyEvent* event) override; void resizeEvent(QResizeEvent* event); void paintLineNumbers(QPaintEvent* event);