feat: 更好用的代码填充;更强大的控制台;一些 Bug 修复;
This commit is contained in:
parent
cf3d4da8e8
commit
d8069aedde
|
@ -365,14 +365,14 @@ void QConsoleWidget::replaceCommandLine(const QString &str) {
|
|||
}
|
||||
|
||||
QString QConsoleWidget::currentCommandLine() const {
|
||||
// Select the text after the last command prompt ...
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
textCursor.movePosition(QTextCursor::End);
|
||||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
|
||||
return textCursor.selectedText();
|
||||
}
|
||||
|
||||
int QConsoleWidget::currentHeaderPos() const { return inpos_; }
|
||||
|
||||
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
|
||||
QTextCharFormat currfmt = currentCharFormat();
|
||||
QTextCursor tc = textCursor();
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
|
||||
virtual void paste();
|
||||
|
||||
int currentHeaderPos() const;
|
||||
|
||||
public slots:
|
||||
|
||||
// write to StandardOutput
|
||||
|
@ -115,7 +117,6 @@ protected:
|
|||
static History history_;
|
||||
ConsoleMode mode_;
|
||||
int inpos_;
|
||||
QString currentMultiLineCode_;
|
||||
QConsoleIODevice *iodevice_;
|
||||
QTextCharFormat chanFormat_[nConsoleChannels];
|
||||
};
|
||||
|
|
|
@ -33,7 +33,8 @@ QtLocalPeer::QtLocalPeer(QObject *parent, const QString &appId)
|
|||
#endif
|
||||
prefix = id.section(QLatin1Char('/'), -1);
|
||||
}
|
||||
prefix.remove(QRegularExpression("[^a-zA-Z]"));
|
||||
static QRegularExpression regex("[^a-zA-Z]");
|
||||
prefix.remove(regex);
|
||||
prefix.truncate(6);
|
||||
|
||||
QByteArray idc = id.toUtf8();
|
||||
|
@ -69,6 +70,8 @@ QtLocalPeer::QtLocalPeer(QObject *parent, const QString &appId)
|
|||
lockFile.open(QIODevice::ReadWrite);
|
||||
}
|
||||
|
||||
QtLocalPeer::~QtLocalPeer() { server->close(); }
|
||||
|
||||
bool QtLocalPeer::isClient() {
|
||||
if (lockFile.isLocked())
|
||||
return false;
|
||||
|
|
|
@ -15,6 +15,8 @@ class QtLocalPeer : public QObject {
|
|||
|
||||
public:
|
||||
QtLocalPeer(QObject *parent = nullptr, const QString &appId = QString());
|
||||
~QtLocalPeer();
|
||||
|
||||
bool isClient();
|
||||
bool sendMessage(const QByteArray &uMsg, int timeout);
|
||||
QString applicationId() const { return id; }
|
||||
|
|
|
@ -8,7 +8,7 @@ set(CMAKE_AUTORCC ON)
|
|||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(PROJECT_VERSION "2.2.1")
|
||||
set(PROJECT_VERSION "2.2.2")
|
||||
|
||||
find_package(
|
||||
QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network Concurrent
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"Id": "WingAngelAPI",
|
||||
"Author": "wingsummer",
|
||||
"Version": "2.1.0",
|
||||
"Version": "2.2.2",
|
||||
"Vendor": "WingCloudStudio",
|
||||
"License": "AGPL-3.0",
|
||||
"Url": "https://github.com/Wing-summer/WingHexExplorer2"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"Id" : "WingCStruct",
|
||||
"Version" : "0.0.1",
|
||||
"Version" : "0.0.2",
|
||||
"Vendor" : "WingCloudStudio",
|
||||
"Author" : "wingsummer",
|
||||
"License" : "AGPL-v3.0",
|
||||
|
|
|
@ -145,9 +145,9 @@ AppManager::AppManager(int &argc, char *argv[])
|
|||
AppManager::~AppManager() {
|
||||
InspectQtLogHelper::instance().destory();
|
||||
ClangFormatManager::instance().save();
|
||||
// CommandHistoryManager::save(QConsoleWidget::history().strings_);
|
||||
CommandHistoryManager::save(QConsoleWidget::history().strings_);
|
||||
|
||||
_w->deleteLater();
|
||||
delete _w;
|
||||
_w = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "asconsolecompletion.h"
|
||||
|
||||
#include "AngelScript/sdk/angelscript/source/as_module.h"
|
||||
#include "class/qascodeparser.h"
|
||||
#include "control/scriptingconsole.h"
|
||||
|
||||
|
@ -39,7 +40,7 @@ QList<CodeInfoTip> AsConsoleCompletion::parseDocument() {
|
|||
return seg.isValid();
|
||||
}) == seg.end()) {
|
||||
// wrap it to let code-completion work
|
||||
code.prepend("void main(){").append('}');
|
||||
code.prepend("void f(){").append('}');
|
||||
}
|
||||
|
||||
// first preprocess the code
|
||||
|
@ -52,11 +53,37 @@ QList<CodeInfoTip> AsConsoleCompletion::parseDocument() {
|
|||
return {};
|
||||
}
|
||||
|
||||
QList<CodeInfoTip> citips;
|
||||
// first, global variables should be added into
|
||||
auto rmod = ScriptMachine::instance().module(ScriptMachine::Interactive);
|
||||
// I think hijack the internal will do the better
|
||||
auto mod = dynamic_cast<asCModule *>(rmod);
|
||||
if (mod) {
|
||||
auto it = mod->m_scriptGlobals.List();
|
||||
while (it) {
|
||||
// lamda expression is great!
|
||||
auto CString2ByteArray = [](const asCString &str) -> QByteArray {
|
||||
return QByteArray(str.AddressOf(), str.GetLength());
|
||||
};
|
||||
|
||||
CodeInfoTip tip;
|
||||
tip.type = CodeInfoTip::Type::Variable;
|
||||
tip.addinfo.insert(
|
||||
CodeInfoTip::RetType,
|
||||
CString2ByteArray(it->type.Format(mod->m_defaultNamespace)));
|
||||
tip.nameSpace = CString2ByteArray(it->nameSpace->name);
|
||||
tip.name = CString2ByteArray(it->name);
|
||||
citips.append(tip);
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
auto data = prepc.scriptData();
|
||||
if (data.size() == 1) {
|
||||
auto d = data[0];
|
||||
return parseScriptData(d.script.length() - 1, d.script);
|
||||
return citips + parseScriptData(d.script.length() - 1, d.script);
|
||||
} else {
|
||||
return {};
|
||||
return citips;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,11 +243,12 @@ void ScriptMachine::exceptionCallback(asIScriptContext *context) {
|
|||
|
||||
const char *section;
|
||||
MessageInfo msg;
|
||||
msg.mode = mode;
|
||||
msg.row = context->GetExceptionLineNumber(&msg.col, §ion);
|
||||
msg.type = MessageType::Error;
|
||||
msg.message = message;
|
||||
|
||||
outputMessage(mode, msg);
|
||||
outputMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,10 +259,11 @@ void ScriptMachine::print(void *ref, int typeId) {
|
|||
context->GetUserData(AsUserDataType::UserData_ContextMode)));
|
||||
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.type = MessageType::Print;
|
||||
info.message = _debugger->toString(ref, typeId, _engine);
|
||||
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,8 +281,8 @@ QString ScriptMachine::getInput() {
|
|||
return {};
|
||||
}
|
||||
|
||||
void ScriptMachine::outputMessage(ConsoleMode mode, const MessageInfo &info) {
|
||||
auto cbs = _regcalls.value(mode);
|
||||
void ScriptMachine::outputMessage(const MessageInfo &info) {
|
||||
auto cbs = _regcalls.value(info.mode);
|
||||
if (cbs.printMsgFn) {
|
||||
cbs.printMsgFn(info);
|
||||
}
|
||||
|
@ -356,12 +358,14 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
return false;
|
||||
}
|
||||
|
||||
_curMode = mode;
|
||||
r = builder.build(mod);
|
||||
if (r < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Script failed to build");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -374,18 +378,20 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
|
||||
if (func == nullptr) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Cannot find 'int main()' or 'void main()'");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isInDebug) {
|
||||
// Allow the user to initialize the debugging before moving on
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Debugging, waiting for commands.");
|
||||
info.type = MessageType::Info;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
}
|
||||
|
||||
// Once we have the main function, we first need to initialize the
|
||||
|
@ -395,9 +401,10 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
r = mod->ResetGlobalVars(0);
|
||||
if (r < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Failed while initializing global variables");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -434,26 +441,29 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
if (r != asEXECUTION_FINISHED) {
|
||||
if (r == asEXECUTION_EXCEPTION) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script failed with an exception") +
|
||||
QStringLiteral("\n") +
|
||||
QString::fromStdString(GetExceptionInfo(ctx, true));
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
} else if (r == asEXECUTION_ABORTED) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script was aborted");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
} else {
|
||||
auto e = QMetaEnum::fromType<asEContextState>();
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script terminated unexpectedly") +
|
||||
QStringLiteral(" (") + e.valueToKey(r) +
|
||||
QStringLiteral(")");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
}
|
||||
} else {
|
||||
|
@ -465,9 +475,10 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
}
|
||||
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script exited with ") + QString::number(r);
|
||||
info.type = MessageType::Info;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
|
||||
// Return the context after retrieving the return value
|
||||
_ctxMgr->DoneWithContext(ctx);
|
||||
|
@ -523,12 +534,13 @@ void ScriptMachine::messageCallback(const asSMessageInfo *msg, void *param) {
|
|||
return;
|
||||
}
|
||||
MessageInfo info;
|
||||
info.mode = ins->_curMode;
|
||||
info.row = msg->row;
|
||||
info.col = msg->col;
|
||||
info.section = msg->section;
|
||||
info.message = m;
|
||||
info.type = t;
|
||||
ins->outputMessage(ins->_curMode, info);
|
||||
ins->outputMessage(info);
|
||||
}
|
||||
|
||||
void ScriptMachine::cleanUpDbgContext(asIScriptContext *context) {
|
||||
|
@ -1852,13 +1864,14 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
// ok, wrap the codes
|
||||
ccode.prepend("void f(){").append("}");
|
||||
// start to compile
|
||||
_curMode = mode;
|
||||
auto cr = mod->CompileFunction(nullptr, ccode, 0, 0, &func);
|
||||
if (cr < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Script failed to build");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1901,23 +1914,24 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
QStringLiteral("\n") +
|
||||
QString::fromStdString(GetExceptionInfo(ctx, true));
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
} else if (r == asEXECUTION_ABORTED) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script was aborted");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
} else {
|
||||
auto e = QMetaEnum::fromType<asEContextState>();
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script terminated unexpectedly") +
|
||||
QStringLiteral(" (") + e.valueToKey(r) +
|
||||
QStringLiteral(")");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
r = -1;
|
||||
}
|
||||
} else {
|
||||
|
@ -1932,26 +1946,39 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
|
||||
return r >= 0;
|
||||
} else {
|
||||
if (ret.length() == 1) {
|
||||
auto s = ret.first();
|
||||
if (s.type == QAsCodeParser::SymbolType::Variable) {
|
||||
auto r = mod->CompileGlobalVar(nullptr, ccode, 0);
|
||||
if (r < 0 || mod->ResetGlobalVars() < 0) {
|
||||
if (std::all_of(ret.begin(), ret.end(),
|
||||
[](const QAsCodeParser::CodeSegment &seg) {
|
||||
return seg.type ==
|
||||
QAsCodeParser::SymbolType::Variable;
|
||||
})) {
|
||||
_curMode = mode;
|
||||
|
||||
for (auto &s : ret) {
|
||||
auto r = mod->CompileGlobalVar(nullptr, s.codes, 0);
|
||||
if (r < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("GlobalBadDecl");
|
||||
info.message = tr("BadDecl:") + s.codes;
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
return false;
|
||||
outputMessage(info);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mod->ResetGlobalVars() < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("GlobalBadDecl");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(info);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("ScriptRunUnsupported");
|
||||
info.message = tr("Script failed to build");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
outputMessage(info);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -102,10 +102,11 @@ private:
|
|||
private:
|
||||
asIScriptModule *createModule(ConsoleMode mode);
|
||||
asIScriptModule *createModuleIfNotExist(ConsoleMode mode);
|
||||
asIScriptModule *module(ConsoleMode mode);
|
||||
bool isModuleExists(ConsoleMode mode);
|
||||
|
||||
public:
|
||||
asIScriptModule *module(ConsoleMode mode);
|
||||
|
||||
static ScriptMachine &instance();
|
||||
|
||||
virtual ~ScriptMachine();
|
||||
|
@ -113,7 +114,7 @@ public:
|
|||
public:
|
||||
bool init();
|
||||
bool isInited() const;
|
||||
bool isRunning(ConsoleMode mode = Scripting) const;
|
||||
bool isRunning(ConsoleMode mode) const;
|
||||
|
||||
static void registerEngineAddon(asIScriptEngine *engine);
|
||||
static void registerEngineAssert(asIScriptEngine *engine);
|
||||
|
@ -159,7 +160,8 @@ protected:
|
|||
private:
|
||||
void print(void *ref, int typeId);
|
||||
QString getInput();
|
||||
void outputMessage(ConsoleMode mode, const MessageInfo &info);
|
||||
|
||||
void outputMessage(const MessageInfo &info);
|
||||
|
||||
bool isType(asITypeInfo *tinfo, RegisteredType type);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "utilities.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
#include <QResizeEvent>
|
||||
|
||||
WingMessageBox::WingMessageBox() {}
|
||||
|
@ -161,5 +162,10 @@ WingMessageBox::msgbox(QWidget *parent, QMessageBox::Icon icon,
|
|||
QObject::connect(msgbox, &QMessageBox::finished, &d,
|
||||
&FramelessDialogBase::done);
|
||||
|
||||
return static_cast<QMessageBox::StandardButton>(d.exec());
|
||||
auto ret = d.exec();
|
||||
if (ret == 0) {
|
||||
return msgbox->standardButton(msgbox->defaultButton());
|
||||
}
|
||||
|
||||
return static_cast<QMessageBox::StandardButton>(ret);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
#include "class/scriptmachine.h"
|
||||
#include "class/scriptsettings.h"
|
||||
#include "class/skinmanager.h"
|
||||
#include "class/wingmessagebox.h"
|
||||
#include "model/codecompletionmodel.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QColor>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextBlock>
|
||||
|
||||
|
@ -102,9 +106,35 @@ void ScriptingConsole::init() {
|
|||
|
||||
void ScriptingConsole::clearConsole() {
|
||||
setMode(Output);
|
||||
|
||||
auto cur = this->textCursor();
|
||||
auto off = cur.position() - this->currentHeaderPos();
|
||||
auto lastCmd = this->currentCommandLine();
|
||||
auto dis = lastCmd.length() - off;
|
||||
|
||||
clear();
|
||||
appendCommandPrompt(lastCommandPrompt());
|
||||
|
||||
if (lastCommandPrompt()) {
|
||||
auto lines = _codes.split('\n');
|
||||
auto pl = lines.begin();
|
||||
appendCommandPrompt(false);
|
||||
writeStdOut(*pl);
|
||||
pl++;
|
||||
for (; pl != lines.end(); pl++) {
|
||||
appendCommandPrompt(true);
|
||||
writeStdOut(*pl);
|
||||
}
|
||||
appendCommandPrompt(true);
|
||||
} else {
|
||||
appendCommandPrompt(false);
|
||||
}
|
||||
|
||||
setMode(Input);
|
||||
replaceCommandLine(lastCmd);
|
||||
cur = this->textCursor();
|
||||
cur.movePosition(QTextCursor::EndOfBlock);
|
||||
cur.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, dis);
|
||||
setTextCursor(cur);
|
||||
}
|
||||
|
||||
void ScriptingConsole::processKeyEvent(QKeyEvent *e) { keyPressEvent(e); }
|
||||
|
@ -183,6 +213,13 @@ void ScriptingConsole::onOutput(const ScriptMachine::MessageInfo &message) {
|
|||
lastInfo.second = qMakePair(message.row, message.col);
|
||||
}
|
||||
|
||||
void ScriptingConsole::abortCurrentCode() {
|
||||
setMode(Output);
|
||||
_codes.clear();
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
}
|
||||
|
||||
void ScriptingConsole::applyScriptSettings() {
|
||||
auto &set = ScriptSettings::instance();
|
||||
auto dfont = QFont(set.consoleFontFamily());
|
||||
|
@ -215,13 +252,95 @@ void ScriptingConsole::applyScriptSettings() {
|
|||
void ScriptingConsole::runConsoleCommand(const QString &code) {
|
||||
auto exec = code.trimmed();
|
||||
if (exec == QStringLiteral("#ls")) {
|
||||
auto &ins = ScriptMachine::instance();
|
||||
auto mod = ins.module(ScriptMachine::Interactive);
|
||||
if (mod) {
|
||||
QList<QPair<QByteArray, QByteArray>> vars;
|
||||
auto total = mod->GetGlobalVarCount();
|
||||
|
||||
} else if (exec == QStringLiteral("#del")) {
|
||||
// generate codes to print
|
||||
QString codes;
|
||||
if (total == 0) {
|
||||
codes = QStringLiteral("print(\"<none>\");");
|
||||
} else {
|
||||
for (asUINT i = 0; i < total; ++i) {
|
||||
const char *name;
|
||||
int typeId;
|
||||
auto decl = mod->GetGlobalVarDeclaration(i);
|
||||
if (decl && mod->GetGlobalVar(i, &name) == asSUCCESS) {
|
||||
vars.emplaceBack(decl, name);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &var : vars) {
|
||||
codes.append("print(\"" + var.first + " = \");print(" +
|
||||
var.second + ");print(\";\\n\");");
|
||||
}
|
||||
}
|
||||
|
||||
setMode(Output);
|
||||
ScriptMachine::instance().executeCode(ScriptMachine::Interactive,
|
||||
codes);
|
||||
_codes.clear();
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
}
|
||||
} else if (exec.startsWith(QStringLiteral("#del"))) {
|
||||
// this is special command
|
||||
auto &ins = ScriptMachine::instance();
|
||||
auto mod = ins.module(ScriptMachine::Interactive);
|
||||
if (mod) {
|
||||
// first check whether contains \n
|
||||
auto idx = exec.indexOf('\n');
|
||||
if (idx >= 0) {
|
||||
setMode(Output);
|
||||
stdErr(tr("InvalidDelCmd"));
|
||||
} else {
|
||||
// ok, then tokens should be devided by the space
|
||||
exec.remove(0, 4);
|
||||
auto vars = exec.split(' ', Qt::SkipEmptyParts);
|
||||
|
||||
QList<asUINT> indices;
|
||||
|
||||
// then check
|
||||
setMode(Output);
|
||||
for (auto &v : vars) {
|
||||
auto idx = mod->GetGlobalVarIndexByName(v.toUtf8());
|
||||
if (idx >= 0) {
|
||||
indices.append(idx);
|
||||
} else {
|
||||
stdWarn(tr("NotFoundIgnore:") + v);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(indices.begin(), indices.end(), std::greater<int>());
|
||||
|
||||
// ok, remove
|
||||
for (auto &i : indices) {
|
||||
mod->RemoveGlobalVar(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
_codes.clear();
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
} else if (exec == QStringLiteral("#cls")) {
|
||||
|
||||
auto &ins = ScriptMachine::instance();
|
||||
auto mod = ins.module(ScriptMachine::Interactive);
|
||||
if (mod) {
|
||||
auto total = mod->GetGlobalVarCount();
|
||||
asUINT i = total;
|
||||
do {
|
||||
--i;
|
||||
mod->RemoveGlobalVar(i);
|
||||
} while (i);
|
||||
}
|
||||
_codes.clear();
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
} else if (exec.endsWith('\\')) {
|
||||
static QRegularExpression ex(QStringLiteral("[\\\\\\s]+$"));
|
||||
_codes.append('\n');
|
||||
_codes += exec.remove(ex);
|
||||
setMode(Output);
|
||||
appendCommandPrompt(true);
|
||||
|
@ -281,8 +400,49 @@ void ScriptingConsole::onCompletion(const QModelIndex &index) {
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptingConsole::paste() {
|
||||
if (ScriptMachine::instance().isRunning(ScriptMachine::Interactive)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QMimeData *const clipboard = QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isEmpty()) {
|
||||
if (text.indexOf('\n') < 0) {
|
||||
replaceCommandLine(text);
|
||||
} else {
|
||||
auto ret = WingMessageBox::question(
|
||||
nullptr, tr("MultiCodeCanNotUndo"), text);
|
||||
if (ret == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
auto lines = text.split('\n');
|
||||
if (lines.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setMode(Output);
|
||||
auto pl = lines.begin();
|
||||
auto pend = std::prev(lines.end());
|
||||
writeStdOut(*pl);
|
||||
pl++;
|
||||
for (; pl != pend; pl++) {
|
||||
appendCommandPrompt(true);
|
||||
writeStdOut(*pl);
|
||||
}
|
||||
appendCommandPrompt(true);
|
||||
setMode(Input);
|
||||
replaceCommandLine(*pl);
|
||||
lines.removeLast();
|
||||
_codes = lines.join('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString ScriptingConsole::currentCodes() const {
|
||||
return _codes + currentCommandLine();
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
|
||||
return _codes + textCursor.selectedText();
|
||||
}
|
||||
|
||||
void ScriptingConsole::contextMenuEvent(QContextMenuEvent *event) {
|
||||
|
@ -297,6 +457,15 @@ void ScriptingConsole::contextMenuEvent(QContextMenuEvent *event) {
|
|||
menu.addAction(QIcon(QStringLiteral(":/qeditor/paste.png")), tr("Paste"),
|
||||
QKeySequence(QKeySequence::Paste), this,
|
||||
&ScriptingConsole::paste);
|
||||
menu.addAction(ICONRES(QStringLiteral("del")), tr("Clear"),
|
||||
QKeySequence(Qt::ControlModifier | Qt::Key_L), this,
|
||||
&ScriptingConsole::clearConsole);
|
||||
menu.addSeparator();
|
||||
menu.addAction(ICONRES(QStringLiteral("dbgstop")), tr("AbortScript"),
|
||||
QKeySequence(Qt::ControlModifier | Qt::Key_Q), []() {
|
||||
ScriptMachine::instance().abortScript(
|
||||
ScriptMachine::Background);
|
||||
});
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ public slots:
|
|||
|
||||
void onOutput(const ScriptMachine::MessageInfo &message);
|
||||
|
||||
void abortCurrentCode();
|
||||
|
||||
private slots:
|
||||
void applyScriptSettings();
|
||||
|
||||
|
@ -64,6 +66,7 @@ protected:
|
|||
|
||||
protected slots:
|
||||
virtual void onCompletion(const QModelIndex &index) override;
|
||||
virtual void paste() override;
|
||||
|
||||
private:
|
||||
QString _codes;
|
||||
|
|
|
@ -1016,10 +1016,15 @@ MainWindow::buildUpScriptConsoleDock(ads::CDockManager *dock,
|
|||
showStatus(QStringLiteral("<b><font color=\"gold\">") +
|
||||
content + QStringLiteral("</font></b>"));
|
||||
});
|
||||
connect(
|
||||
m_scriptConsole, &ScriptingConsole::abortEvaluation, this, [this]() {
|
||||
ScriptMachine::instance().abortScript(ScriptMachine::Interactive);
|
||||
});
|
||||
connect(m_scriptConsole, &ScriptingConsole::abortEvaluation, this,
|
||||
[this]() {
|
||||
auto &sm = ScriptMachine::instance();
|
||||
if (sm.isRunning(ScriptMachine::Interactive)) {
|
||||
sm.abortScript(ScriptMachine::Interactive);
|
||||
} else {
|
||||
m_scriptConsole->abortCurrentCode();
|
||||
}
|
||||
});
|
||||
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("ScriptConsole"),
|
||||
tr("ScriptConsole"), m_scriptConsole);
|
||||
|
@ -1031,8 +1036,32 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
|
|||
ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw) {
|
||||
m_bgScriptOutput = new QPlainTextEdit(this);
|
||||
m_bgScriptOutput->setPlaceholderText(tr("BgScriptOutputHere"));
|
||||
m_bgScriptOutput->setReadOnly(true);
|
||||
|
||||
auto a = newAction(
|
||||
ICONRES(QStringLiteral("mStr")), tr("SelectAll"),
|
||||
[this]() { m_bgScriptOutput->selectAll(); }, QKeySequence::SelectAll);
|
||||
m_bgScriptOutput->addAction(a);
|
||||
a = newAction(
|
||||
ICONRES(QStringLiteral("copy")), tr("Copy"),
|
||||
[this]() { m_bgScriptOutput->copy(); }, QKeySequence::Copy);
|
||||
m_bgScriptOutput->addAction(a);
|
||||
a = newAction(ICONRES(QStringLiteral("del")), tr("Clear"),
|
||||
[this]() { m_bgScriptOutput->clear(); });
|
||||
m_bgScriptOutput->addAction(a);
|
||||
a = new QAction(this);
|
||||
a->setSeparator(true);
|
||||
m_bgScriptOutput->addAction(a);
|
||||
a = newAction(
|
||||
ICONRES(QStringLiteral("dbgstop")), tr("AbortScript"),
|
||||
[]() {
|
||||
ScriptMachine::instance().abortScript(ScriptMachine::Background);
|
||||
},
|
||||
QKeySequence(Qt::ControlModifier | Qt::Key_Q));
|
||||
m_bgScriptOutput->addAction(a);
|
||||
m_bgScriptOutput->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("BgScriptOutput"),
|
||||
tr("BgScriptOutput"), m_bgScriptOutput);
|
||||
return dock->addDockWidget(area, dw, areaw);
|
||||
|
|
|
@ -506,7 +506,7 @@ RibbonTabContent *ScriptingDialog::buildDebugPage(RibbonTabContent *tab) {
|
|||
bool isDbg = false;
|
||||
bool isPaused = false;
|
||||
|
||||
isRun = runner.isRunning();
|
||||
isRun = runner.isRunning(ScriptMachine::Scripting);
|
||||
isDbg = runner.isDebugMode();
|
||||
auto dbg = runner.debugger();
|
||||
isPaused = dbg->currentState() == asDebugger::PAUSE;
|
||||
|
@ -740,7 +740,8 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) {
|
|||
Q_ASSERT(m_views.contains(editor));
|
||||
|
||||
auto &m = ScriptMachine::instance();
|
||||
if (m.isRunning() && _DebugingEditor == editor) {
|
||||
if (m.isRunning(ScriptMachine::Scripting) &&
|
||||
_DebugingEditor == editor) {
|
||||
if (WingMessageBox::warning(
|
||||
this, this->windowTitle(), tr("ScriptStillRunning"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
|
@ -881,7 +882,7 @@ void ScriptingDialog::updateRunDebugMode(bool disable) {
|
|||
bool isDbg = false;
|
||||
bool isPaused = false;
|
||||
|
||||
isRun = runner.isRunning();
|
||||
isRun = runner.isRunning(ScriptMachine::Scripting);
|
||||
isDbg = runner.isDebugMode();
|
||||
auto dbg = runner.debugger();
|
||||
isPaused = dbg->currentState() == asDebugger::PAUSE;
|
||||
|
@ -1437,7 +1438,7 @@ void ScriptingDialog::on_removebreakpoint() {
|
|||
|
||||
void ScriptingDialog::closeEvent(QCloseEvent *event) {
|
||||
auto &runner = ScriptMachine::instance();
|
||||
if (runner.isRunning()) {
|
||||
if (runner.isRunning(ScriptMachine::Scripting)) {
|
||||
if (WingMessageBox::warning(
|
||||
this, this->windowTitle(), tr("ScriptStillRunning"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
|
|
Loading…
Reference in New Issue