servatrice/cockatrice/src/lineeditcompleter.cpp
Xenos6666 63b4f9b2f0
Add keyboard shorcuts to focus and unfocus chat (#3898)
* Added keyboard shorcuts to focus and unfocus chat

* Fixed format

* Changed the Esc behavior to work on any QLineEdit in the main Window and ignore shortcut conflicts

* Fixed a conflict with shortcuts

* Configurable unfocus shortcut and format fixes

* minor style fix
2020-03-16 21:48:05 -04:00

133 lines
4.5 KiB
C++

#include "lineeditcompleter.h"
#include <QAbstractItemView>
#include <QCompleter>
#include <QFocusEvent>
#include <QKeyEvent>
#include <QScrollBar>
#include <QStringListModel>
#include <QTextCursor>
#include <QWidget>
LineEditCompleter::LineEditCompleter(QWidget *parent) : LineEditUnfocusable(parent), c(nullptr)
{
}
void LineEditCompleter::focusOutEvent(QFocusEvent *e)
{
LineEditUnfocusable::focusOutEvent(e);
if (c->popup()->isVisible()) {
// Remove Popup
c->popup()->hide();
// Truncate the line to last space or whole string
QString textValue = text();
int lastIndex = textValue.length();
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
int leftShift = qMin(lastIndex, lastWordStartIndex);
setText(textValue.left(leftShift));
// Insert highlighted line from popup
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
// Set focus back to the textbox since tab was pressed
setFocus();
}
}
void LineEditCompleter::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
case Qt::Key_Escape:
if (c->popup()->isVisible()) {
event->ignore();
// Remove Popup
c->popup()->hide();
// Truncate the line to last space or whole string
QString textValue = text();
int lastIndexof = qMax(0, textValue.lastIndexOf(" "));
QString finalString = textValue.left(lastIndexof);
// Add a space if there's a word
if (finalString != "")
finalString += " ";
setText(finalString);
return;
}
break;
case Qt::Key_Space:
if (c->popup()->isVisible()) {
event->ignore();
// Remove Popup
c->popup()->hide();
// Truncate the line to last space or whole string
QString textValue = text();
int lastIndex = textValue.length();
int lastWordStartIndex = textValue.lastIndexOf(" ") + 1;
int leftShift = qMin(lastIndex, lastWordStartIndex);
setText(textValue.left(leftShift));
// Insert highlighted line from popup
insert(c->completionModel()->index(c->popup()->currentIndex().row(), 0).data().toString() + " ");
return;
}
break;
default:
break;
}
LineEditUnfocusable::keyPressEvent(event);
// return if the completer is null or if the most recently typed char was '@'.
// Only want the popup AFTER typing the first char of the mention.
if (!c || text().right(1).contains("@")) {
c->popup()->hide();
return;
}
// Set new completion prefix
c->setCompletionPrefix(cursorWord(text()));
if (c->completionPrefix().length() < 1) {
c->popup()->hide();
return;
}
// Draw completion box
QRect cr = cursorRect();
cr.setWidth(c->popup()->sizeHintForColumn(0) + c->popup()->verticalScrollBar()->sizeHint().width());
c->complete(cr);
// Select first item in the completion popup
QItemSelectionModel *sm = new QItemSelectionModel(c->completionModel());
c->popup()->setSelectionModel(sm);
sm->select(c->completionModel()->index(0, 0), QItemSelectionModel::ClearAndSelect);
sm->setCurrentIndex(c->completionModel()->index(0, 0), QItemSelectionModel::NoUpdate);
}
QString LineEditCompleter::cursorWord(const QString &line) const
{
return line.mid(line.left(cursorPosition()).lastIndexOf(" ") + 1,
cursorPosition() - line.left(cursorPosition()).lastIndexOf(" ") - 1);
}
void LineEditCompleter::insertCompletion(QString arg)
{
QString s_arg = arg + " ";
setText(text().replace(text().left(cursorPosition()).lastIndexOf(" ") + 1,
cursorPosition() - text().left(cursorPosition()).lastIndexOf(" ") - 1, s_arg));
}
void LineEditCompleter::setCompleter(QCompleter *completer)
{
c = completer;
c->setWidget(this);
connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
}
void LineEditCompleter::setCompletionList(QStringList completionList)
{
if (!c || c->popup()->isVisible())
return;
QStringListModel *model;
model = (QStringListModel *)(c->model());
if (model == NULL)
model = new QStringListModel();
model->setStringList(completionList);
}