UI: Add vertically expanding LineEdit Widget

Meant to behave like a QLineEdit (disallowing newlines and having a
maximum length), but show multiple lines.
master
gxalpha 2022-05-11 21:04:49 +02:00 committed by Ryan Foster
parent e14f6280c2
commit 5a298106bc
3 changed files with 128 additions and 0 deletions

View File

@ -188,6 +188,8 @@ target_sources(
focus-list.hpp
hotkey-edit.cpp
hotkey-edit.hpp
lineedit-autoresize.cpp
lineedit-autoresize.hpp
locked-checkbox.cpp
locked-checkbox.hpp
log-viewer.cpp

View File

@ -0,0 +1,94 @@
#include "lineedit-autoresize.hpp"
LineEditAutoResize::LineEditAutoResize()
{
connect(this, SIGNAL(textChanged()), this, SLOT(checkTextLength()));
connect(document()->documentLayout(),
SIGNAL(documentSizeChanged(const QSizeF &)), this,
SLOT(resizeVertically(const QSizeF &)));
}
void LineEditAutoResize::checkTextLength()
{
QString text = toPlainText();
if (text.length() > m_maxLength) {
setPlainText(text.left(m_maxLength));
QTextCursor cursor = textCursor();
cursor.setPosition(m_maxLength);
setTextCursor(cursor);
}
}
int LineEditAutoResize::maxLength()
{
return m_maxLength;
}
void LineEditAutoResize::setMaxLength(int length)
{
m_maxLength = length;
}
void LineEditAutoResize::keyPressEvent(QKeyEvent *event)
{
/* Always allow events with modifiers, for example to Copy content */
Qt::KeyboardModifiers modifiers = event->modifiers();
if (modifiers != Qt::NoModifier && modifiers != Qt::ShiftModifier) {
QTextEdit::keyPressEvent(event);
return;
}
switch (event->key()) {
/* Always ignore the return key and send the signal instead */
case Qt::Key_Return:
event->ignore();
emit returnPressed();
break;
/* Always allow navigation and deletion */
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_PageUp:
case Qt::Key_PageDown:
case Qt::Key_Delete:
case Qt::Key_Backspace:
QTextEdit::keyPressEvent(event);
break;
/* Allow only if the content is not already at max length.
* Some keys with modifiers should still be allowed though
* (for example for Copy), and we don't want to make assumptions
* about which modifiers are okay and which aren't, so let's
* allow all. Actions that will still exceed the limit (like
* Paste) can be caught in a later step. */
default:
if (toPlainText().length() >= m_maxLength &&
event->modifiers() == Qt::NoModifier &&
!textCursor().hasSelection())
event->ignore();
else
QTextEdit::keyPressEvent(event);
break;
}
}
void LineEditAutoResize::resizeVertically(const QSizeF &newSize)
{
setMaximumHeight(newSize.height() + 7);
}
QString LineEditAutoResize::text()
{
return toPlainText();
}
void LineEditAutoResize::setText(const QString &text)
{
QMetaObject::invokeMethod(this, "SetPlainText", Qt::QueuedConnection,
Q_ARG(const QString &, text));
}
void LineEditAutoResize::SetPlainText(const QString &text)
{
setPlainText(text);
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <QTextEdit>
#include <QAbstractTextDocumentLayout>
#include <QKeyEvent>
class LineEditAutoResize : public QTextEdit {
Q_OBJECT
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
public:
LineEditAutoResize();
int maxLength();
void setMaxLength(int length);
QString text();
void setText(const QString &text);
private:
int m_maxLength;
signals:
void returnPressed();
private slots:
void checkTextLength();
void resizeVertically(const QSizeF &newSize);
void SetPlainText(const QString &text);
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
};