Pārlūkot izejas kodu

UI: Add vertically expanding LineEdit Widget

Meant to behave like a QLineEdit (disallowing newlines and having a
maximum length), but show multiple lines.
gxalpha 3 gadi atpakaļ
vecāks
revīzija
5a298106bc
3 mainītis faili ar 128 papildinājumiem un 0 dzēšanām
  1. 2 0
      UI/CMakeLists.txt
  2. 94 0
      UI/lineedit-autoresize.cpp
  3. 32 0
      UI/lineedit-autoresize.hpp

+ 2 - 0
UI/CMakeLists.txt

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

+ 94 - 0
UI/lineedit-autoresize.cpp

@@ -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);
+}

+ 32 - 0
UI/lineedit-autoresize.hpp

@@ -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;
+};