2026-04-06 00:20:51 -05:00

202 lines
7.5 KiB
C++

#ifndef KEYPRESSHANDLER_H
#define KEYPRESSHANDLER_H
#include <main.h>
#include <MainAdaptix.h>
#include <UI/MainUI.h>
#include <Client/AuthProfile.h>
class KPH_SearchInput : public QObject
{
Q_OBJECT
QLineEdit* inputLineEdit;
public:
KPH_SearchInput(QLineEdit *input, QObject *parent = nullptr) : QObject(parent), inputLineEdit(input) {
inputLineEdit->installEventFilter(this);
}
Q_SIGNALS:
void escPressed();
protected:
bool eventFilter(QObject *watched, QEvent *event) override {
if (watched == inputLineEdit && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if ( keyEvent->key() == Qt::Key_Escape ) {
Q_EMIT escPressed();
}
}
return QObject::eventFilter(watched, event);
}
};
class KPH_ConsoleInput : public QObject
{
Q_OBJECT
QLineEdit* inputLineEdit;
QPlainTextEdit* outputTextEdit;
QString tmpCommandLine;
QStringList history;
int historyIndex;
QStringList completions;
int completionIndex;
QString completionBase;
QString completionPrefix;
QString completionSuffix;
public:
KPH_ConsoleInput(QLineEdit *input, QPlainTextEdit *output, QObject *parent = nullptr) : QObject(parent), inputLineEdit(input), outputTextEdit(output), historyIndex(-1) {
inputLineEdit->installEventFilter(this);
}
void AddToHistory(const QString &command) {
history.prepend(command);
historyIndex = -1;
tmpCommandLine = "";
}
const QStringList& getHistory() const { return history; }
protected:
bool eventFilter(QObject *watched, QEvent *event) override {
if (watched == inputLineEdit && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Up) {
if ( history.size() == 0 )
return true;
if (historyIndex < history.size() - 1) {
if (historyIndex == -1)
tmpCommandLine = inputLineEdit->text();
historyIndex++;
inputLineEdit->setText(history[historyIndex]);
} else {
historyIndex = history.size() - 1;
inputLineEdit->setText(history[history.size() - 1]);
}
return true;
}
if (keyEvent->key() == Qt::Key_Down) {
if ( history.size() == 0 )
return true;
if (historyIndex > 0) {
historyIndex--;
inputLineEdit->setText(history[historyIndex]);
} else {
historyIndex = -1;
inputLineEdit->setText(tmpCommandLine);
}
return true;
}
if (keyEvent->key() == Qt::Key_L && (keyEvent->modifiers() & Qt::ControlModifier)) {
outputTextEdit->clear();
return true;
}
if (keyEvent->key() == Qt::Key_Tab) {
if (keyEvent->modifiers() & Qt::ControlModifier) {
QString baseDir;
if (GlobalClient && GlobalClient->mainUI) {
if (auto profile = GlobalClient->mainUI->GetCurrentProfile())
baseDir = profile->GetProjectDir();
}
QString filePath = QFileDialog::getOpenFileName(nullptr, "Select file", baseDir);
if (!filePath.isEmpty()) {
int cursorPos = inputLineEdit->cursorPosition();
QString text = inputLineEdit->text();
text.insert(cursorPos, "\"" + filePath + "\"");
inputLineEdit->setText(text);
inputLineEdit->setCursorPosition(cursorPos + filePath.length());
}
return true;
}
else {
if (completionIndex < 0) {
QString text = inputLineEdit->text();
int cursorPos = inputLineEdit->cursorPosition();
bool inQuotes = false;
int start = cursorPos;
while (start > 0) {
QChar prev = text.at(start - 1);
if (prev == '"' && (start < 2 || text.at(start - 2) != '\\'))
inQuotes = !inQuotes;
if (!inQuotes && prev.isSpace())
break;
start--;
}
completionPrefix = text.left(start);
completionBase = text.mid(start, cursorPos - start);
completionSuffix = text.mid(cursorPos);
if (completionBase.startsWith('"') && completionBase.endsWith('"'))
completionBase = completionBase.mid(1, completionBase.length() - 2);
QString expanded = completionBase;
if (expanded.startsWith("~/"))
expanded = QDir::homePath() + expanded.mid(1);
if (expanded == "") {
completionIndex = -1;
return true;
}
completions.clear();
completionIndex = 0;
QFileInfo fi(expanded);
QString dirPath = fi.path().isEmpty() ? QDir::currentPath() : fi.path();
QString nameStart = fi.fileName();
QDir dir(dirPath);
QStringList nameFilters{ nameStart + '*' };
QFileInfoList infos = dir.entryInfoList( nameFilters, QDir::NoDotAndDotDot | QDir::AllEntries, QDir::Name );
const QString home = QDir::homePath();
for (const QFileInfo &item : infos) {
QString path = item.absoluteFilePath();
if (path.startsWith(home))
path = '~' + path.mid(home.length());
if (item.isDir())
path += QDir::separator();
#ifdef Q_OS_WIN
path.replace('/', '\\');
#endif
if (path.contains(' '))
path = '"' + path + '"';
completions << path;
}
}
if (!completions.isEmpty()) {
QString chosen = completions[completionIndex];
QString newText = completionPrefix + chosen + completionSuffix;
inputLineEdit->setText(newText);
int selBaseOffset = completionPrefix.length();
int selOffset = completionBase.length();
int selStart = selBaseOffset + selOffset;
int selLen = chosen.length() - selOffset;
inputLineEdit->setSelection(selStart, selLen);
completionIndex = (completionIndex + 1) % completions.size();
}
return true;
}
}
completionIndex = -1;
}
return QObject::eventFilter(watched, event);
}
};
#endif