CodeEditor improvements
- Block (un)indent (works for tabs and or spaces) - Block indent inserts spaces when m_useTabs == false - Tabsize based on number of chars (instead of pixels) default size is now 4 chars - Change fontsize with Ctrl + [-|+|=] (= is same key as +)
This commit is contained in:
parent
69473d65d2
commit
d129876d06
2 changed files with 128 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include "EditorGutter.h"
|
||||
#include <QPainter>
|
||||
#include <QTextBlock>
|
||||
#include <QDebug>
|
||||
//
|
||||
// Adapted from codeeditor example
|
||||
// http://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html
|
||||
|
|
@ -22,6 +23,7 @@ CodeEditor::CodeEditor(QWidget *parent)
|
|||
setWordWrapMode(QTextOption::NoWrap);
|
||||
|
||||
updateGutterAreaWidth(0);
|
||||
setTabSize(4);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ int CodeEditor::gutterAreaWidth()
|
|||
++digits;
|
||||
}
|
||||
|
||||
int space = 3 + fontMetrics().width(QLatin1Char('9')) * (digits + 2);
|
||||
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * (digits + 2);
|
||||
|
||||
return space;
|
||||
}
|
||||
|
|
@ -154,3 +156,118 @@ void CodeEditor::gutterAreaPaintEvent(QPaintEvent *event)
|
|||
++blockNumber;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
auto k = e->key();
|
||||
qDebug() << QString("%1").arg(k, 0, 16);
|
||||
if (k == Qt::Key_Tab) {
|
||||
// Function returns false if there was no selection to indent
|
||||
if (indentSelection(true))
|
||||
return;
|
||||
}
|
||||
else if (k == Qt::Key_Backtab) {
|
||||
// Function returns false if there was no selection to indent
|
||||
if (indentSelection(false))
|
||||
return;
|
||||
}
|
||||
else if (k == Qt::Key_Equal || k == Qt::Key_Plus) {
|
||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
auto f = font();
|
||||
f.setPointSize(f.pointSize() + 1);
|
||||
setFont(f);
|
||||
}
|
||||
}
|
||||
else if (k == Qt::Key_Minus) {
|
||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
auto f = font();
|
||||
f.setPointSize(f.pointSize() - 1);
|
||||
setFont(f);
|
||||
}
|
||||
}
|
||||
QPlainTextEdit::keyPressEvent(e);
|
||||
}
|
||||
|
||||
bool CodeEditor::indentSelection(bool indent)
|
||||
{
|
||||
auto cursor = textCursor();
|
||||
|
||||
if(!cursor.hasSelection())
|
||||
return false;
|
||||
|
||||
auto first_pos = cursor.anchor();
|
||||
auto end_pos = cursor.position();
|
||||
|
||||
if(first_pos > end_pos)
|
||||
std::swap(first_pos, end_pos);
|
||||
|
||||
cursor.setPosition(first_pos, QTextCursor::MoveAnchor);
|
||||
auto start_block = cursor.block().blockNumber();
|
||||
|
||||
cursor.setPosition(end_pos, QTextCursor::MoveAnchor);
|
||||
auto end_block = cursor.block().blockNumber();
|
||||
if (end_block == start_block)
|
||||
return false;
|
||||
|
||||
cursor.beginEditBlock();
|
||||
cursor.setPosition(first_pos, QTextCursor::MoveAnchor);
|
||||
const auto block_count = end_block - start_block;
|
||||
for(int block = 0; block <= block_count; ++block) {
|
||||
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
|
||||
if (indent) {
|
||||
if (m_useTab)
|
||||
cursor.insertText("\t");
|
||||
else
|
||||
cursor.insertText(QString(m_tabSize, ' '));
|
||||
}
|
||||
else {
|
||||
// remove tab if there is a tab
|
||||
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||
const QString text = cursor.selectedText();
|
||||
int index = 0;
|
||||
int pos = 0;
|
||||
while (pos < m_tabSize && index < text.length()) {
|
||||
QChar c = text[index++];
|
||||
if (c == ' ')
|
||||
++pos;
|
||||
else if (c == '\t')
|
||||
pos = ((pos + m_tabSize) / m_tabSize) * m_tabSize;
|
||||
else {
|
||||
--index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
|
||||
for (int i = 0; i < index; ++i)
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
}
|
||||
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor);
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
|
||||
cursor.setPosition(first_pos, QTextCursor::MoveAnchor);
|
||||
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
|
||||
while(cursor.block().blockNumber() < end_block)
|
||||
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
|
||||
|
||||
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||
|
||||
setTextCursor(cursor);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodeEditor::setFont(const QFont &f)
|
||||
{
|
||||
QWidget::setFont(f);
|
||||
auto orig_tab = m_tabSize;
|
||||
m_tabSize = 0;
|
||||
setTabSize(orig_tab);
|
||||
}
|
||||
|
||||
void CodeEditor::setTabSize(int chars)
|
||||
{
|
||||
m_tabSize = chars;
|
||||
int pixels = fontMetrics().horizontalAdvance(QString(chars, '0'));
|
||||
this->setTabStopDistance(pixels);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue