2019-09-14 13:03:34 -04:00
|
|
|
#include "cmd_line.h"
|
|
|
|
|
|
|
|
// This file is part of Cmdr.
|
|
|
|
|
|
|
|
// Cmdr is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// Cmdr is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Cmdr under the LICENSE.md file. If not, see
|
|
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
CmdLine::CmdLine(QWidget *parent) : QComboBox(parent)
|
|
|
|
{
|
|
|
|
localData = Shared::localData;
|
|
|
|
flags = 0;
|
|
|
|
|
|
|
|
setEditable(true);
|
|
|
|
setDuplicatesEnabled(true);
|
2020-03-10 19:04:48 -04:00
|
|
|
loadTheme(localData, this);
|
2019-09-14 13:03:34 -04:00
|
|
|
|
|
|
|
if (!localData->contains("command_hist"))
|
|
|
|
{
|
|
|
|
localData->insert("command_hist", QJsonArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!localData->contains("hist_limit"))
|
|
|
|
{
|
|
|
|
localData->insert("hist_limit", DEFAULT_HIST_LIMIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
saveLocalData(localData);
|
|
|
|
syncHistFromFile();
|
|
|
|
|
|
|
|
connect(lineEdit(), SIGNAL(selectionChanged()), this, SLOT(selectionCheck()));
|
|
|
|
connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(hideText(QString)));
|
|
|
|
connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(checkForHistReset(QString)));
|
|
|
|
}
|
|
|
|
|
2019-12-04 22:01:52 -05:00
|
|
|
void CmdLine::cacheTxt(quint8 typeId, QString txt)
|
|
|
|
{
|
|
|
|
Shared::cacheTxt(Shared::TXT_IN, typeId, txt);
|
|
|
|
|
|
|
|
if (!(*Shared::activeDisp))
|
|
|
|
{
|
|
|
|
emit txtInCache();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-14 13:03:34 -04:00
|
|
|
void CmdLine::setFlags(int flgs)
|
|
|
|
{
|
|
|
|
flags |= flgs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::unsetFlags(int flgs)
|
|
|
|
{
|
2019-12-04 22:01:52 -05:00
|
|
|
flags &= ~flgs;
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::selectionCheck()
|
|
|
|
{
|
|
|
|
if (flags & HIDDEN) lineEdit()->deselect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::hideText(const QString &txt)
|
|
|
|
{
|
|
|
|
if (flags & HIDDEN)
|
|
|
|
{
|
|
|
|
int currentPos = lineEdit()->cursorPosition();
|
|
|
|
|
|
|
|
if (txt.size() > hiddenText.size())
|
|
|
|
{
|
|
|
|
int len = txt.size() - hiddenText.size();
|
|
|
|
|
|
|
|
hiddenText.insert(currentPos - len, txt.mid(currentPos - len, len));
|
|
|
|
|
|
|
|
lineEdit()->setText(QString(hiddenText.size(), '#'));
|
|
|
|
}
|
|
|
|
else if (hiddenText.size() > txt.size())
|
|
|
|
{
|
|
|
|
int len = hiddenText.size() - txt.size();
|
|
|
|
|
|
|
|
hiddenText.remove(currentPos, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
lineEdit()->setCursorPosition(currentPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::checkForHistReset(const QString &txt)
|
|
|
|
{
|
|
|
|
if (txt.isEmpty()) setCurrentIndex(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString CmdLine::cmdNameOnly(const QString &line)
|
|
|
|
{
|
|
|
|
QString ret = line;
|
|
|
|
int pos = line.indexOf(" ");
|
|
|
|
|
|
|
|
if (pos != -1)
|
|
|
|
{
|
|
|
|
ret = line.left(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret.toLower();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::echo(const QString &line)
|
|
|
|
{
|
|
|
|
if (!line.trimmed().isEmpty())
|
|
|
|
{
|
2019-12-04 22:01:52 -05:00
|
|
|
cacheTxt(TEXT, line + "\n\n");
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::clearHist()
|
|
|
|
{
|
|
|
|
localData->insert("command_hist", QJsonArray());
|
|
|
|
|
|
|
|
saveLocalData(localData);
|
|
|
|
clear();
|
|
|
|
|
|
|
|
lineEdit()->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::syncHistToFile()
|
|
|
|
{
|
|
|
|
QJsonArray hist;
|
|
|
|
|
|
|
|
for (int i = 0; i < count(); ++i)
|
|
|
|
{
|
|
|
|
hist.append(itemData(i, Qt::DisplayRole).toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
localData->insert("command_hist", hist);
|
|
|
|
|
|
|
|
saveLocalData(localData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::syncHistFromFile()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
|
|
|
|
QJsonArray hist = localData->value("command_hist").toArray();
|
|
|
|
|
|
|
|
for (auto item : hist)
|
|
|
|
{
|
|
|
|
addItem(item.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
setCurrentIndex(-1);
|
|
|
|
setInsertPolicy(QComboBox::InsertAtTop);
|
|
|
|
|
|
|
|
lineEdit()->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::toHost(const QString &cmdName, const QString &args)
|
|
|
|
{
|
|
|
|
if (flags & HOST_HOOK)
|
|
|
|
{
|
2020-08-09 17:22:31 -04:00
|
|
|
emit dataToHookedHost(args.toUtf8(), TEXT);
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
else if (!cmdName.isEmpty())
|
|
|
|
{
|
|
|
|
quint16 cmdId = Shared::hostCmds->key(cmdName);
|
|
|
|
|
|
|
|
if (!Shared::hostCmds->values().contains(cmdName))
|
|
|
|
{
|
2019-12-04 22:01:52 -05:00
|
|
|
cacheTxt(ERR, "err: No such command: " + cmdName + "\n\n");
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
else if (Shared::genfileCmds->contains(cmdId))
|
|
|
|
{
|
2019-12-14 13:50:36 -05:00
|
|
|
emit setHostCmdId(cmdId);
|
|
|
|
emit setGenfileType(Shared::genfileTypes->value(cmdId));
|
2020-08-09 17:22:31 -04:00
|
|
|
emit dataToGenFile(args.toUtf8());
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-09 17:22:31 -04:00
|
|
|
emit dataToHost(cmdId, args.toUtf8(), TEXT);
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::toLocalCmd(const QString &cmdName, const QString &args)
|
|
|
|
{
|
|
|
|
if (flags & LOCAL_HOOK)
|
|
|
|
{
|
|
|
|
emit dataToHookedCmdObj(args);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit dataToCommandObj(cmdName, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::procCmdLine(const QString &line)
|
|
|
|
{
|
|
|
|
QString cmdName;
|
|
|
|
QString argsLine;
|
|
|
|
|
|
|
|
if (!(flags & (GEN_HOOK | HOST_HOOK | LOCAL_HOOK)))
|
|
|
|
{
|
|
|
|
cmdName = cmdNameOnly(line.trimmed());
|
|
|
|
argsLine = line.trimmed().mid(cmdName.size() + 1);
|
|
|
|
}
|
|
|
|
else if (Shared::hookBypass->contains(cmdNameOnly(line), Qt::CaseInsensitive))
|
|
|
|
{
|
|
|
|
cmdName = cmdNameOnly(line.trimmed());
|
|
|
|
argsLine = line.trimmed().mid(cmdName.size() + 1);
|
|
|
|
}
|
|
|
|
else if (flags & HIDDEN)
|
|
|
|
{
|
|
|
|
argsLine = hiddenText;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
argsLine = line.trimmed();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & GEN_HOOK)
|
|
|
|
{
|
2020-08-09 17:22:31 -04:00
|
|
|
emit dataToGenFile(argsLine.toUtf8());
|
2019-09-14 13:03:34 -04:00
|
|
|
}
|
|
|
|
else if (Shared::clientCmds->contains(cmdName))
|
|
|
|
{
|
|
|
|
toLocalCmd(cmdName, argsLine);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
toHost(cmdName, argsLine);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::contextMenuEvent(QContextMenuEvent *event)
|
|
|
|
{
|
|
|
|
QMenu *menu = lineEdit()->createStandardContextMenu();
|
|
|
|
|
|
|
|
menu->addAction("Clear History", this, SLOT(clearHist()));
|
|
|
|
menu->exec(event->globalPos());
|
|
|
|
menu->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::duplicateScan(const QString &txt)
|
|
|
|
{
|
|
|
|
// this will remove any duplicates in the command line history, skipping over 1st line.
|
|
|
|
// why not setDuplicatesEnabled(false)? the problem with that is it does an "inplace
|
|
|
|
// replace" which means the duplicate item does not move from its position on the list
|
|
|
|
// when inserted. i want this app to "float the duplicate to the top" when inserted
|
|
|
|
// hence why i created this function.
|
|
|
|
|
|
|
|
if (!(flags & HIDDEN))
|
|
|
|
{
|
|
|
|
for (int i = 1; i < count(); ++i)
|
|
|
|
{
|
|
|
|
if (itemText(i) == txt)
|
|
|
|
{
|
|
|
|
removeItem(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CmdLine::keyReleaseEvent(QKeyEvent *event)
|
|
|
|
{
|
|
|
|
if (event->key() == Qt::Key_Return)
|
|
|
|
{
|
|
|
|
echo(lineEdit()->text());
|
|
|
|
procCmdLine(lineEdit()->text());
|
|
|
|
duplicateScan(lineEdit()->text());
|
|
|
|
|
|
|
|
if (flags & HIDDEN)
|
|
|
|
{
|
|
|
|
removeItem(0);
|
|
|
|
unsetFlags(HIDDEN);
|
|
|
|
|
|
|
|
hiddenText.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
lineEdit()->clear();
|
|
|
|
|
|
|
|
syncHistToFile();
|
|
|
|
setCurrentIndex(-1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QComboBox::keyReleaseEvent(event);
|
|
|
|
}
|
|
|
|
}
|