fix: 更好的代码填充和一些 Bug 修复;
This commit is contained in:
parent
2ee3051a7d
commit
cf3d4da8e8
|
@ -109,6 +109,15 @@ QString QConsoleWidget::getCommandLine() {
|
|||
return code;
|
||||
}
|
||||
|
||||
void QConsoleWidget::paste() {
|
||||
QTextCursor textCursor = this->textCursor();
|
||||
const QMimeData *const clipboard = QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isNull()) {
|
||||
textCursor.insertText(text, channelCharFormat(StandardInput));
|
||||
}
|
||||
}
|
||||
|
||||
void QConsoleWidget::handleReturnKey() {
|
||||
QString code = getCommandLine();
|
||||
|
||||
|
@ -189,12 +198,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
|
|||
// Allow paste only if the selection is in the interactive area ...
|
||||
if (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier) {
|
||||
if (selectionInEditZone || isCursorInEditZone()) {
|
||||
const QMimeData *const clipboard =
|
||||
QApplication::clipboard()->mimeData();
|
||||
const QString text = clipboard->text();
|
||||
if (!text.isNull()) {
|
||||
textCursor.insertText(text, channelCharFormat(StandardInput));
|
||||
}
|
||||
paste();
|
||||
}
|
||||
|
||||
e->accept();
|
||||
|
|
|
@ -77,6 +77,8 @@ public:
|
|||
// get the current command line
|
||||
QString getCommandLine();
|
||||
|
||||
virtual void paste();
|
||||
|
||||
public slots:
|
||||
|
||||
// write to StandardOutput
|
||||
|
@ -94,6 +96,7 @@ signals:
|
|||
protected:
|
||||
bool canPaste() const;
|
||||
bool canCut() const;
|
||||
|
||||
virtual void handleReturnKey();
|
||||
virtual void handleTabKey();
|
||||
// reimp QPlainTextEdit functions
|
||||
|
|
|
@ -253,8 +253,6 @@ set(CLASS_SRC
|
|||
src/class/ascompletion.h
|
||||
src/class/asbuilder.h
|
||||
src/class/asbuilder.cpp
|
||||
src/class/ascontextmgr.h
|
||||
src/class/ascontextmgr.cpp
|
||||
src/class/clangformatmanager.h
|
||||
src/class/clangformatmanager.cpp
|
||||
src/class/aspreprocesser.h
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -45,6 +45,8 @@ AppManager::AppManager(int &argc, char *argv[])
|
|||
: QtSingleApplication(argc, argv) {
|
||||
ASSERT_SINGLETON;
|
||||
|
||||
_instance = this;
|
||||
|
||||
LanguageManager::instance();
|
||||
InspectQtLogHelper::instance().init();
|
||||
CrashHandler::instance().init();
|
||||
|
@ -102,6 +104,8 @@ AppManager::AppManager(int &argc, char *argv[])
|
|||
his.add(cmd);
|
||||
}
|
||||
|
||||
_timer.start();
|
||||
|
||||
_w = new MainWindow(splash);
|
||||
|
||||
setActivationWindow(_w);
|
||||
|
@ -133,7 +137,6 @@ AppManager::AppManager(int &argc, char *argv[])
|
|||
|
||||
connect(_w, &MainWindow::closed, this,
|
||||
[]() { AppManager::instance()->exit(); });
|
||||
_instance = this;
|
||||
|
||||
if (splash)
|
||||
splash->close();
|
||||
|
@ -152,6 +155,8 @@ AppManager *AppManager::instance() { return _instance; }
|
|||
|
||||
MainWindow *AppManager::mainWindow() const { return _w; }
|
||||
|
||||
uint AppManager::currentMSecsSinceEpoch() { return _timer.elapsed(); }
|
||||
|
||||
void AppManager::openFile(const QString &file, bool autoDetect) {
|
||||
EditorView *editor = nullptr;
|
||||
Q_ASSERT(_w);
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "dialog/mainwindow.h"
|
||||
#include "qtsingleapplication/src/qtsingleapplication.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
|
||||
class AppManager : public QtSingleApplication {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -36,6 +38,8 @@ public:
|
|||
QApplication::tr("WingCloudStudio");
|
||||
}
|
||||
|
||||
uint currentMSecsSinceEpoch();
|
||||
|
||||
public slots:
|
||||
void openFile(const QString &file, bool autoDetect = true);
|
||||
void openRawFile(const QString &file);
|
||||
|
@ -43,6 +47,8 @@ public slots:
|
|||
|
||||
private:
|
||||
MainWindow *_w = nullptr;
|
||||
QElapsedTimer _timer;
|
||||
|
||||
static AppManager *_instance;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "wingcodeedit.h"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
#include <QEvent>
|
||||
|
@ -41,8 +42,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, LEFT_PARE_TRIGGER, ("("))
|
|||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, SEMI_COLON_TRIGGER, (";"))
|
||||
|
||||
AsCompletion::AsCompletion(WingCodeEdit *p)
|
||||
: WingCompleter(p), parser(ScriptMachine::instance().engine()),
|
||||
m_parseDocument(true) {
|
||||
: WingCompleter(p), parser(ScriptMachine::instance().engine()) {
|
||||
setTriggerList({*DOT_TRIGGER, *DBL_COLON_TRIGGER,
|
||||
// unleash the power of call tips
|
||||
*LEFT_PARE_TRIGGER,
|
||||
|
@ -126,10 +126,43 @@ void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) {
|
|||
nodes = clsNodes;
|
||||
}
|
||||
|
||||
bool AsCompletion::parseDocument() const { return m_parseDocument; }
|
||||
int AsCompletion::includeCallBack(const QString &include, bool quotedInclude,
|
||||
const QString &from, AsPreprocesser *builder,
|
||||
void *userParam) {
|
||||
Q_UNUSED(userParam);
|
||||
|
||||
void AsCompletion::setParseDocument(bool newParseDocument) {
|
||||
m_parseDocument = newParseDocument;
|
||||
QFileInfo info(include);
|
||||
bool isAbsolute = info.isAbsolute();
|
||||
bool hasNoExt = info.suffix().isEmpty();
|
||||
QString inc;
|
||||
if (quotedInclude) {
|
||||
if (isAbsolute) {
|
||||
inc = include;
|
||||
} else {
|
||||
auto pwd = QFileInfo(from).absoluteDir();
|
||||
inc = pwd.absoluteFilePath(include);
|
||||
}
|
||||
} else {
|
||||
// absolute include is not allowed in #include<>
|
||||
if (isAbsolute) {
|
||||
// ignored in code completion
|
||||
return asSUCCESS;
|
||||
}
|
||||
|
||||
QDir dir(qApp->applicationDirPath());
|
||||
if (!dir.cd(QStringLiteral("aslib"))) {
|
||||
// someone crash the software, ignored
|
||||
return asSUCCESS;
|
||||
}
|
||||
inc = dir.absoluteFilePath(include);
|
||||
}
|
||||
|
||||
if (hasNoExt) {
|
||||
inc += QStringLiteral(".as");
|
||||
}
|
||||
|
||||
builder->loadSectionFromFile(inc);
|
||||
return asSUCCESS;
|
||||
}
|
||||
|
||||
void AsCompletion::clearFunctionTip() { emit onFunctionTip({}); }
|
||||
|
@ -235,10 +268,7 @@ bool AsCompletion::processTrigger(const QString &trigger,
|
|||
return true;
|
||||
}
|
||||
|
||||
QList<CodeInfoTip> docNodes;
|
||||
if (m_parseDocument) {
|
||||
docNodes = parseDocument();
|
||||
}
|
||||
QList<CodeInfoTip> docNodes = parseDocument();
|
||||
|
||||
// if trigger is empty, it's making editing
|
||||
if (trigger.isEmpty()) {
|
||||
|
@ -383,8 +413,7 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
|
||||
// first preprocess the code
|
||||
AsPreprocesser prepc(engine);
|
||||
// TODO: set include callback
|
||||
// prepc.setIncludeCallback();
|
||||
prepc.setIncludeCallback(&AsCompletion::includeCallBack, this);
|
||||
|
||||
auto r = prepc.loadSectionFromMemory(QStringLiteral("ASCOMPLETION"),
|
||||
code.toUtf8());
|
||||
|
@ -396,9 +425,23 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
QList<CodeInfoTip> ret;
|
||||
|
||||
for (auto &d : data) {
|
||||
qsizetype offset = -1;
|
||||
if (d.section == QStringLiteral("ASCOMPLETION")) {
|
||||
offset = editor->textCursor().position();
|
||||
}
|
||||
ret.append(parseScriptData(offset, d.script));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<CodeInfoTip> AsCompletion::parseScriptData(qsizetype offset,
|
||||
const QByteArray &code) {
|
||||
QList<CodeInfoTip> ret;
|
||||
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
QAsCodeParser parser(engine);
|
||||
auto syms =
|
||||
parser.parseAndIntell(editor->textCursor().position(), d.script);
|
||||
auto syms = parser.parseAndIntell(offset, code);
|
||||
|
||||
for (auto &sym : syms) {
|
||||
CodeInfoTip tip;
|
||||
|
@ -459,22 +502,19 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
ctip.type = CodeInfoTip::Type::Function;
|
||||
ctip.addinfo.insert(CodeInfoTip::RetType,
|
||||
QString::fromUtf8(mem.type));
|
||||
ctip.addinfo.insert(
|
||||
CodeInfoTip::Args,
|
||||
ctip.addinfo.insert(CodeInfoTip::Args,
|
||||
QString::fromUtf8(mem.additonalInfo));
|
||||
for (auto &var : mem.children) {
|
||||
CodeInfoTip va;
|
||||
va.dontAddGlobal = true;
|
||||
va.name = var.name;
|
||||
va.nameSpace =
|
||||
QString::fromUtf8(var.scope.join("::"));
|
||||
va.nameSpace = QString::fromUtf8(var.scope.join("::"));
|
||||
va.addinfo.insert(CodeInfoTip::RetType, var.type);
|
||||
va.type = CodeInfoTip::Type::Variable;
|
||||
tip.children.append(va);
|
||||
}
|
||||
tip.children.append(ctip);
|
||||
} else if (mem.symtype ==
|
||||
QAsCodeParser::SymbolType::Variable) {
|
||||
} else if (mem.symtype == QAsCodeParser::SymbolType::Variable) {
|
||||
ctip.addinfo.insert(CodeInfoTip::RetType, mem.type);
|
||||
ctip.type = CodeInfoTip::Type::Variable;
|
||||
tip.children.append(ctip);
|
||||
|
@ -489,7 +529,6 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
|
||||
ret.append(tip);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "WingCodeEdit/wingcompleter.h"
|
||||
#include "class/asdatabase.h"
|
||||
|
||||
class AsPreprocesser;
|
||||
|
||||
class AsCompletion : public WingCompleter {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -32,9 +34,6 @@ public:
|
|||
public:
|
||||
virtual QString wordSeperators() const override;
|
||||
|
||||
bool parseDocument() const;
|
||||
void setParseDocument(bool newParseDocument);
|
||||
|
||||
void clearFunctionTip();
|
||||
|
||||
protected:
|
||||
|
@ -43,6 +42,9 @@ protected:
|
|||
|
||||
virtual QList<CodeInfoTip> parseDocument();
|
||||
|
||||
QList<CodeInfoTip> parseScriptData(qsizetype offset,
|
||||
const QByteArray &code);
|
||||
|
||||
signals:
|
||||
void onFunctionTip(const QString &content);
|
||||
|
||||
|
@ -55,9 +57,13 @@ private:
|
|||
const QList<CodeInfoTip> &docNodes);
|
||||
void applyClassNodes(QList<CodeInfoTip> &nodes);
|
||||
|
||||
private:
|
||||
static int includeCallBack(const QString &include, bool quotedInclude,
|
||||
const QString &from, AsPreprocesser *builder,
|
||||
void *userParam);
|
||||
|
||||
private:
|
||||
ASDataBase parser;
|
||||
bool m_parseDocument;
|
||||
};
|
||||
|
||||
#endif // _CPP_COMPLETION_H_
|
||||
|
|
|
@ -17,9 +17,46 @@
|
|||
|
||||
#include "asconsolecompletion.h"
|
||||
|
||||
#include "class/qascodeparser.h"
|
||||
#include "control/scriptingconsole.h"
|
||||
|
||||
AsConsoleCompletion::AsConsoleCompletion(ScriptingConsole *p)
|
||||
: AsCompletion(p), _console(p) {
|
||||
setParseDocument(false);
|
||||
: AsCompletion(p), _console(p) {}
|
||||
|
||||
QList<CodeInfoTip> AsConsoleCompletion::parseDocument() {
|
||||
auto editor = _console;
|
||||
if (editor == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto code = editor->currentCodes();
|
||||
auto engine = ScriptMachine::instance().engine();
|
||||
|
||||
QAsCodeParser parser(engine);
|
||||
auto seg = parser.parse(code.toUtf8());
|
||||
if (std::find_if(seg.begin(), seg.end(),
|
||||
[](const QAsCodeParser::CodeSegment &seg) {
|
||||
return seg.isValid();
|
||||
}) == seg.end()) {
|
||||
// wrap it to let code-completion work
|
||||
code.prepend("void main(){").append('}');
|
||||
}
|
||||
|
||||
// first preprocess the code
|
||||
AsPreprocesser prepc(engine);
|
||||
|
||||
// including is not supported in console
|
||||
auto r = prepc.loadSectionFromMemory(QStringLiteral("ASConCOMPLETION"),
|
||||
code.toUtf8());
|
||||
if (r <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto data = prepc.scriptData();
|
||||
if (data.size() == 1) {
|
||||
auto d = data[0];
|
||||
return parseScriptData(d.script.length() - 1, d.script);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ public:
|
|||
explicit AsConsoleCompletion(ScriptingConsole *p);
|
||||
virtual ~AsConsoleCompletion() = default;
|
||||
|
||||
protected:
|
||||
virtual QList<CodeInfoTip> parseDocument();
|
||||
|
||||
private:
|
||||
ScriptingConsole *_console;
|
||||
};
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "ascontextmgr.h"
|
||||
|
||||
// copy from base class
|
||||
struct SContextInfo {
|
||||
asUINT sleepUntil;
|
||||
std::vector<asIScriptContext *> coRoutines;
|
||||
asUINT currentCoRoutine;
|
||||
asIScriptContext *keepCtxAfterExecution;
|
||||
};
|
||||
|
||||
asContextMgr::asContextMgr() : CContextMgr() {}
|
||||
|
||||
bool asContextMgr::findThreadWithUserData(asPWORD index, void *data) const {
|
||||
for (auto &th : m_threads) {
|
||||
auto ctx = th->keepCtxAfterExecution;
|
||||
if (ctx) {
|
||||
auto user = ctx->GetUserData(index);
|
||||
if (user == data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program 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 Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef ASCONTEXTMGR_H
|
||||
#define ASCONTEXTMGR_H
|
||||
|
||||
#include "AngelScript/sdk/add_on/contextmgr/contextmgr.h"
|
||||
|
||||
class asContextMgr : public CContextMgr {
|
||||
public:
|
||||
asContextMgr();
|
||||
|
||||
bool findThreadWithUserData(asPWORD index, void *data) const;
|
||||
};
|
||||
|
||||
#endif // ASCONTEXTMGR_H
|
|
@ -71,6 +71,9 @@ void asDebugger::takeCommands(asIScriptContext *ctx) {
|
|||
void asDebugger::lineCallback(asIScriptContext *ctx) {
|
||||
Q_ASSERT(ctx);
|
||||
|
||||
// prevent UI freezing
|
||||
qApp->processEvents();
|
||||
|
||||
// This should never happen, but it doesn't hurt to validate it
|
||||
if (ctx == nullptr)
|
||||
return;
|
||||
|
|
|
@ -456,7 +456,7 @@ void CTypeParser::stripComments(QStringList &lines) const {
|
|||
QStringLiteral("]");
|
||||
|
||||
// search comment start
|
||||
while ((pos = line.indexOf(kSlash, pos)) != -1) {
|
||||
while ((pos = line.indexOf(char(kSlash), pos)) != -1) {
|
||||
if (line.length() <= pos + 1)
|
||||
break; // the 1st '/' is at the end of line, so not a comment
|
||||
|
||||
|
@ -1070,7 +1070,7 @@ bool CTypeParser::parseDeclaration(const QString &line,
|
|||
if (line.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (line[line.length() - 1] != kSemicolon)
|
||||
if (line[line.length() - 1] != char(kSemicolon))
|
||||
return false;
|
||||
|
||||
QStringList tokens;
|
||||
|
@ -1090,7 +1090,7 @@ bool CTypeParser::parseDeclaration(const QString &line,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (tokens[++index].at(0) == kAsterisk) {
|
||||
if (tokens[++index].at(0) == char(kAsterisk)) {
|
||||
decl.is_pointer = true;
|
||||
// size of a pointer is 4 types on a 32-bit system
|
||||
length =
|
||||
|
@ -1148,14 +1148,14 @@ bool CTypeParser::parseEnumDeclaration(const QString &line, int &last_value,
|
|||
break;
|
||||
|
||||
case 2:
|
||||
if (kComma != tokens[1].at(0)) {
|
||||
if (char(kComma) != tokens[1].at(0)) {
|
||||
return false;
|
||||
}
|
||||
decl.second = ++last_value;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (kEqual != tokens[1].at(0)) {
|
||||
if (char(kEqual) != tokens[1].at(0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1171,7 +1171,8 @@ bool CTypeParser::parseEnumDeclaration(const QString &line, int &last_value,
|
|||
break;
|
||||
|
||||
case 4:
|
||||
if (!(kEqual == tokens[1].at(0) && kComma == tokens[3].at(0))) {
|
||||
if (!(char(kEqual) == tokens[1].at(0) &&
|
||||
char(kComma) == tokens[3].at(0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1208,8 +1209,8 @@ bool CTypeParser::parseAssignExpression(const QString &line) {
|
|||
|
||||
// only 4 tokens for an assignment expression: var = number;
|
||||
if (4 == splitLineIntoTokens(line, tokens) &&
|
||||
kEqual == tokens[1].at(tokens[1].length() - 1) &&
|
||||
kSemicolon == tokens[3].at(tokens[3].length() - 1) &&
|
||||
char(kEqual) == tokens[1].at(tokens[1].length() - 1) &&
|
||||
char(kSemicolon) == tokens[3].at(tokens[3].length() - 1) &&
|
||||
isNumericToken(tokens[2], number)) {
|
||||
const_defs_.insert(tokens[0], number);
|
||||
return true;
|
||||
|
@ -1244,7 +1245,7 @@ bool CTypeParser::parsePreProcDirective(const QString &src, qsizetype &pos) {
|
|||
}
|
||||
|
||||
// only handle header file included with ""
|
||||
if (kQuotation == token[token.length() - 1]) {
|
||||
if (char(kQuotation) == token[token.length() - 1]) {
|
||||
// get included header file name
|
||||
if (!getNextToken(src, pos, token, false)) {
|
||||
return false;
|
||||
|
@ -1371,7 +1372,7 @@ bool CTypeParser::parseStructUnion(const bool is_struct, const bool is_typedef,
|
|||
if (is_typedef) {
|
||||
// format 1
|
||||
if (!(getNextToken(src, pos, next_token) &&
|
||||
kSemicolon == next_token.at(0))) {
|
||||
char(kSemicolon) == next_token.at(0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1392,7 +1393,7 @@ bool CTypeParser::parseStructUnion(const bool is_struct, const bool is_typedef,
|
|||
type_maps_[type_name] = type_maps_[type_alias];
|
||||
}
|
||||
} else { // non-typedef
|
||||
if (kSemicolon == token.at(0)) {
|
||||
if (char(kSemicolon) == token.at(0)) {
|
||||
// format 2
|
||||
is_decl = false;
|
||||
if (type_name.isEmpty()) {
|
||||
|
@ -1547,7 +1548,7 @@ bool CTypeParser::parseEnum(const bool is_typedef, const QString &src,
|
|||
if (is_typedef) {
|
||||
// format 1
|
||||
if (!(getNextToken(src, pos, next_token) &&
|
||||
kSemicolon == next_token.at(0))) {
|
||||
char(kSemicolon) == next_token.at(0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1564,7 +1565,7 @@ bool CTypeParser::parseEnum(const bool is_typedef, const QString &src,
|
|||
;
|
||||
}
|
||||
} else { // non-typedef
|
||||
if (kSemicolon == token.at(0)) {
|
||||
if (char(kSemicolon) == token.at(0)) {
|
||||
// format 2
|
||||
is_decl = false;
|
||||
if (type_name.isEmpty()) {
|
||||
|
|
|
@ -1194,7 +1194,7 @@ QList<QAsCodeParser::CodeSegment> QAsCodeParser::parseScript(bool inBlock) {
|
|||
seg.offset = begin;
|
||||
seg.scope = currentNs;
|
||||
seg.type = SymbolType::Variable;
|
||||
seg.codes = _code.sliced(begin, end - begin + 1);
|
||||
seg.codes = _code.sliced(begin, end - begin);
|
||||
rewindTo(&t1);
|
||||
|
||||
segs.append(seg);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "AngelScript/sdk/add_on/weakref/weakref.h"
|
||||
|
||||
#include "angelobjstring.h"
|
||||
#include "class/appmanager.h"
|
||||
#include "class/asbuilder.h"
|
||||
#include "class/pluginsystem.h"
|
||||
#include "class/qascodeparser.h"
|
||||
|
@ -42,13 +43,7 @@
|
|||
#include <QProcess>
|
||||
#include <QScopeGuard>
|
||||
|
||||
ScriptMachine::~ScriptMachine() {
|
||||
if (_ctxMgr) {
|
||||
delete _ctxMgr;
|
||||
}
|
||||
|
||||
destoryMachine();
|
||||
}
|
||||
ScriptMachine::~ScriptMachine() { destoryMachine(); }
|
||||
|
||||
bool ScriptMachine::init() {
|
||||
if (isInited()) {
|
||||
|
@ -74,9 +69,7 @@ bool ScriptMachine::init() {
|
|||
bool ScriptMachine::isInited() const { return _engine != nullptr; }
|
||||
|
||||
bool ScriptMachine::isRunning(ConsoleMode mode) const {
|
||||
return _ctxMgr->findThreadWithUserData(
|
||||
AsUserDataType::UserData_ContextMode,
|
||||
reinterpret_cast<void *>(asPWORD(mode)));
|
||||
return _ctx.value(mode) != nullptr;
|
||||
}
|
||||
|
||||
bool ScriptMachine::configureEngine() {
|
||||
|
@ -171,9 +164,12 @@ bool ScriptMachine::configureEngine() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Setup the context manager and register the support for co-routines
|
||||
_ctxMgr = new asContextMgr();
|
||||
_ctxMgr = new CContextMgr;
|
||||
_ctxMgr->RegisterCoRoutineSupport(_engine);
|
||||
_ctxMgr->SetGetTimeCallback([]() -> asUINT {
|
||||
return AppManager::instance()->currentMSecsSinceEpoch();
|
||||
});
|
||||
_ctxMgr->RegisterThreadSupport(_engine);
|
||||
|
||||
// Tell the engine to use our context pool. This will also
|
||||
// allow us to debug internal script calls made by the engine
|
||||
|
@ -227,6 +223,9 @@ QString ScriptMachine::getCallStack(asIScriptContext *context) {
|
|||
}
|
||||
|
||||
void ScriptMachine::destoryMachine() {
|
||||
_ctxMgr->AbortAll();
|
||||
delete _ctxMgr;
|
||||
|
||||
_debugger->setEngine(nullptr);
|
||||
_engine->ShutDownAndRelease();
|
||||
_engine = nullptr;
|
||||
|
@ -389,9 +388,10 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
outputMessage(mode, info);
|
||||
}
|
||||
|
||||
// Once we have the main function, we first need to initialize the global
|
||||
// variables Since we've set up the request context callback we will be able
|
||||
// to debug the initialization without passing in a pre-created context
|
||||
// Once we have the main function, we first need to initialize the
|
||||
// global variables Since we've set up the request context callback we
|
||||
// will be able to debug the initialization without passing in a
|
||||
// pre-created context
|
||||
r = mod->ResetGlobalVars(0);
|
||||
if (r < 0) {
|
||||
MessageInfo info;
|
||||
|
@ -405,9 +405,11 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
// The context manager will request the context from the
|
||||
// pool, which will automatically attach the debugger
|
||||
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
|
||||
_ctx[mode] = ctx;
|
||||
|
||||
ctx->SetUserData(reinterpret_cast<void *>(isDbg),
|
||||
AsUserDataType::UserData_isDbg);
|
||||
|
||||
mod->SetUserData(reinterpret_cast<void *>(isDbg),
|
||||
AsUserDataType::UserData_isDbg);
|
||||
|
||||
|
@ -421,8 +423,11 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
// Execute the script until completion
|
||||
// The script may create co-routines. These will automatically
|
||||
// be managed by the context manager
|
||||
while (_ctxMgr->ExecuteScripts())
|
||||
;
|
||||
while (_ctxMgr->ExecuteScripts()) {
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
_ctx[mode] = nullptr;
|
||||
|
||||
// Check if the main script finished normally
|
||||
r = ctx->GetState();
|
||||
|
@ -479,13 +484,24 @@ bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script,
|
|||
return r >= 0;
|
||||
}
|
||||
|
||||
void ScriptMachine::abortDbgScript(ConsoleMode mode) {
|
||||
void ScriptMachine::abortDbgScript() {
|
||||
if (_debugger->getEngine()) {
|
||||
_debugger->runDebugAction(asDebugger::ABORT);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptMachine::abortScript() { _ctxMgr->AbortAll(); }
|
||||
void ScriptMachine::abortScript(ConsoleMode mode) {
|
||||
auto ctx = _ctx.value(mode, nullptr);
|
||||
if (ctx) {
|
||||
ctx->Abort();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptMachine::abortScript() {
|
||||
abortScript(ConsoleMode::Interactive);
|
||||
abortScript(ConsoleMode::Scripting);
|
||||
abortScript(ConsoleMode::Background);
|
||||
}
|
||||
|
||||
void ScriptMachine::messageCallback(const asSMessageInfo *msg, void *param) {
|
||||
MessageType t = MessageType::Print;
|
||||
|
@ -1805,16 +1821,6 @@ asDebugger *ScriptMachine::debugger() const { return _debugger; }
|
|||
|
||||
bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
||||
asIScriptModule *mod = createModuleIfNotExist(mode);
|
||||
|
||||
QScopeGuard guard([mod, mode]() {
|
||||
if (mode != ConsoleMode::Interactive) {
|
||||
// Before leaving, allow the engine to clean up remaining objects by
|
||||
// discarding the module and doing a full garbage collection so that
|
||||
// this can also be debugged if desired
|
||||
mod->Discard();
|
||||
}
|
||||
});
|
||||
|
||||
_engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, false);
|
||||
|
||||
// first, preparse the code
|
||||
|
@ -1824,16 +1830,30 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
asIScriptFunction *func = nullptr;
|
||||
|
||||
auto ret = parser.parse(ccode);
|
||||
|
||||
// check whether there is any enum/class
|
||||
if (std::find_if(ret.begin(), ret.end(),
|
||||
[](const QAsCodeParser::CodeSegment &seg) {
|
||||
return seg.isValid();
|
||||
}) == ret.end()) {
|
||||
switch (seg.type) {
|
||||
case QAsCodeParser::SymbolType::Enum:
|
||||
case QAsCodeParser::SymbolType::Class:
|
||||
case QAsCodeParser::SymbolType::Function:
|
||||
case QAsCodeParser::SymbolType::Interface:
|
||||
case QAsCodeParser::SymbolType::Import:
|
||||
case QAsCodeParser::SymbolType::Variable:
|
||||
return false;
|
||||
case QAsCodeParser::SymbolType::Invalid:
|
||||
case QAsCodeParser::SymbolType::TypeDef:
|
||||
case QAsCodeParser::SymbolType::FnDef:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}) != ret.end()) {
|
||||
// ok, wrap the codes
|
||||
ccode.prepend("void main(){").append("}");
|
||||
ccode.prepend("void f(){").append("}");
|
||||
// start to compile
|
||||
auto r = mod->CompileFunction(nullptr, ccode, -1, 0, &func);
|
||||
if (r < 0) {
|
||||
auto cr = mod->CompileFunction(nullptr, ccode, 0, 0, &func);
|
||||
if (cr < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Script failed to build");
|
||||
|
@ -1841,40 +1861,12 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
outputMessage(mode, info);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mod->AddScriptSection("Runner", ccode, ccode.size(), 0);
|
||||
|
||||
auto r = mod->Build();
|
||||
if (r < 0) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("Script failed to build");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the main function
|
||||
func = mod->GetFunctionByDecl("void main()");
|
||||
if (func == nullptr) {
|
||||
// Try again with "int main()"
|
||||
func = mod->GetFunctionByDecl("int main()");
|
||||
}
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up a context to execute the script
|
||||
// The context manager will request the context from the
|
||||
// pool, which will automatically attach the debugger
|
||||
asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true);
|
||||
_ctx[mode] = ctx;
|
||||
|
||||
asPWORD isDbg = 0;
|
||||
ctx->SetUserData(reinterpret_cast<void *>(isDbg),
|
||||
|
@ -1886,14 +1878,17 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
ctx->SetUserData(reinterpret_cast<void *>(umode),
|
||||
AsUserDataType::UserData_ContextMode);
|
||||
|
||||
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback), this,
|
||||
asCALL_THISCALL);
|
||||
ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback),
|
||||
this, asCALL_THISCALL);
|
||||
|
||||
// Execute the script until completion
|
||||
// The script may create co-routines. These will automatically
|
||||
// be managed by the context manager
|
||||
while (_ctxMgr->ExecuteScripts())
|
||||
;
|
||||
while (_ctxMgr->ExecuteScripts()) {
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
_ctx[mode] = nullptr;
|
||||
|
||||
// Check if the main script finished normally
|
||||
int r = ctx->GetState();
|
||||
|
@ -1901,7 +1896,8 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
if (r == asEXECUTION_EXCEPTION) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("The script failed with an exception") +
|
||||
info.message =
|
||||
tr("The script failed with an exception") +
|
||||
QStringLiteral("\n") +
|
||||
QString::fromStdString(GetExceptionInfo(ctx, true));
|
||||
info.type = MessageType::Error;
|
||||
|
@ -1928,11 +1924,36 @@ bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) {
|
|||
r = 0;
|
||||
}
|
||||
|
||||
func->Release();
|
||||
|
||||
// Return the context after retrieving the return value
|
||||
_ctxMgr->DoneWithContext(ctx);
|
||||
_engine->GarbageCollect();
|
||||
|
||||
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) {
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("GlobalBadDecl");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MessageInfo info;
|
||||
info.mode = mode;
|
||||
info.message = tr("ScriptRunUnsupported");
|
||||
info.type = MessageType::Error;
|
||||
outputMessage(mode, info);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ScriptMachine::scriptGetExceptionInfo() {
|
||||
|
|
|
@ -18,13 +18,15 @@
|
|||
#ifndef SCRIPTMACHINE_H
|
||||
#define SCRIPTMACHINE_H
|
||||
|
||||
#include "AngelScript/sdk/add_on/contextmgr/contextmgr.h"
|
||||
#include "AngelScript/sdk/angelscript/include/angelscript.h"
|
||||
|
||||
#include "class/aspreprocesser.h"
|
||||
|
||||
#include "asdebugger.h"
|
||||
#include "class/ascontextmgr.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QQueue>
|
||||
|
||||
class ScriptMachine : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -97,7 +99,7 @@ private:
|
|||
explicit ScriptMachine();
|
||||
Q_DISABLE_COPY_MOVE(ScriptMachine)
|
||||
|
||||
public:
|
||||
private:
|
||||
asIScriptModule *createModule(ConsoleMode mode);
|
||||
asIScriptModule *createModuleIfNotExist(ConsoleMode mode);
|
||||
asIScriptModule *module(ConsoleMode mode);
|
||||
|
@ -143,7 +145,8 @@ public slots:
|
|||
bool executeScript(ConsoleMode mode, const QString &script,
|
||||
bool isInDebug = false);
|
||||
|
||||
void abortDbgScript(ConsoleMode mode);
|
||||
void abortDbgScript();
|
||||
void abortScript(ConsoleMode mode);
|
||||
void abortScript();
|
||||
|
||||
protected:
|
||||
|
@ -196,11 +199,13 @@ signals:
|
|||
private:
|
||||
asIScriptEngine *_engine = nullptr;
|
||||
asDebugger *_debugger = nullptr;
|
||||
asContextMgr *_ctxMgr = nullptr;
|
||||
QVector<asIScriptContext *> _ctxPool;
|
||||
CContextMgr *_ctxMgr = nullptr;
|
||||
|
||||
QQueue<asIScriptContext *> _ctxPool;
|
||||
|
||||
QVector<asITypeInfo *> _rtypes;
|
||||
QMap<ConsoleMode, RegCallBacks> _regcalls;
|
||||
QMap<ConsoleMode, asIScriptContext *> _ctx;
|
||||
ConsoleMode _curMode = ConsoleMode::Background;
|
||||
};
|
||||
|
||||
|
|
|
@ -250,16 +250,18 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) {
|
|||
}
|
||||
|
||||
void ScriptManager::runScript(const QString &filename) {
|
||||
// ScriptMachine::instance().executeScript(filename);
|
||||
auto &ins = ScriptMachine::instance();
|
||||
if (ins.isRunning(ScriptMachine::Background)) {
|
||||
auto ret = QMessageBox::question(nullptr, tr("ScriptRunning"),
|
||||
tr("ScriptRunningRequestLastStop?"));
|
||||
if (ret == QMessageBox::Yes) {
|
||||
ins.abortScript(ScriptMachine::Background);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Q_ASSERT(_console);
|
||||
// _console->setMode(ScriptingConsole::Output);
|
||||
// _console->stdWarn(tr("Excuting:") + filename);
|
||||
// _console->newLine();
|
||||
// // TODO
|
||||
// // _console->machine()->executeScript(filename);
|
||||
// _console->appendCommandPrompt();
|
||||
// _console->setMode(ScriptingConsole::Input);
|
||||
ins.executeScript(ScriptMachine::Background, filename);
|
||||
}
|
||||
|
||||
QStringList ScriptManager::usrScriptsDbCats() const {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
constexpr qsizetype FILE_MAX_BUFFER = 0x6400000; // 100MB
|
||||
constexpr qsizetype FILE_MAX_BUFFER = 0x32000000; // 800MB
|
||||
constexpr auto CLONE_LIMIT = 3;
|
||||
|
||||
constexpr auto VIEW_PROPERTY = "__VIEW__";
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "scriptingconsole.h"
|
||||
#include "QConsoleWidget/QConsoleIODevice.h"
|
||||
#include "class/logger.h"
|
||||
#include "class/scriptmachine.h"
|
||||
#include "class/scriptsettings.h"
|
||||
#include "class/skinmanager.h"
|
||||
|
@ -84,19 +83,15 @@ void ScriptingConsole::handleReturnKey() {
|
|||
if (iodevice_->isOpen())
|
||||
iodevice_->consoleWidgetInput(code);
|
||||
|
||||
if (!_isWaitingRead) {
|
||||
emit consoleCommand(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptingConsole::init() {
|
||||
_getInputFn = std::bind(&ScriptingConsole::getInput, this);
|
||||
|
||||
// _sp = new ScriptConsoleMachine(_getInputFn, this);
|
||||
// connect(_sp, &ScriptConsoleMachine::onClearConsole, this,
|
||||
// &ScriptingConsole::clear);
|
||||
// connect(this, &ScriptingConsole::abortEvaluation, _sp,
|
||||
// &ScriptConsoleMachine::abortScript);
|
||||
|
||||
connect(this, &QConsoleWidget::consoleCommand, this,
|
||||
&ScriptingConsole::runConsoleCommand);
|
||||
|
||||
|
@ -177,7 +172,7 @@ void ScriptingConsole::onOutput(const ScriptMachine::MessageInfo &message) {
|
|||
flush();
|
||||
break;
|
||||
case ScriptMachine::MessageType::Print:
|
||||
if (lastInfo.first != message.type) {
|
||||
if (lastInfo.first != message.type && isNotBlockStart) {
|
||||
newLine();
|
||||
}
|
||||
stdOut(message.message);
|
||||
|
@ -219,7 +214,13 @@ void ScriptingConsole::applyScriptSettings() {
|
|||
|
||||
void ScriptingConsole::runConsoleCommand(const QString &code) {
|
||||
auto exec = code.trimmed();
|
||||
if (exec.endsWith('\\')) {
|
||||
if (exec == QStringLiteral("#ls")) {
|
||||
|
||||
} else if (exec == QStringLiteral("#del")) {
|
||||
|
||||
} else if (exec == QStringLiteral("#cls")) {
|
||||
|
||||
} else if (exec.endsWith('\\')) {
|
||||
static QRegularExpression ex(QStringLiteral("[\\\\\\s]+$"));
|
||||
_codes += exec.remove(ex);
|
||||
setMode(Output);
|
||||
|
@ -228,10 +229,8 @@ void ScriptingConsole::runConsoleCommand(const QString &code) {
|
|||
} else {
|
||||
setMode(Output);
|
||||
_codes += exec;
|
||||
if (!ScriptMachine::instance().executeCode(ScriptMachine::Interactive,
|
||||
_codes)) {
|
||||
// WingMessageBox::
|
||||
}
|
||||
ScriptMachine::instance().executeCode(ScriptMachine::Interactive,
|
||||
_codes);
|
||||
_codes.clear();
|
||||
appendCommandPrompt();
|
||||
setMode(Input);
|
||||
|
@ -239,11 +238,18 @@ void ScriptingConsole::runConsoleCommand(const QString &code) {
|
|||
}
|
||||
|
||||
QString ScriptingConsole::getInput() {
|
||||
auto &s = consoleStream();
|
||||
appendCommandPrompt(true);
|
||||
setMode(Input);
|
||||
consoleStream().device()->waitForReadyRead(-1);
|
||||
s.status();
|
||||
auto d = s.device();
|
||||
auto ba = d->bytesAvailable();
|
||||
d->skip(ba);
|
||||
_isWaitingRead = true;
|
||||
d->waitForReadyRead(-1);
|
||||
QString instr;
|
||||
consoleStream() >> instr;
|
||||
s >> instr;
|
||||
_isWaitingRead = false;
|
||||
setMode(Output);
|
||||
return instr;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ protected slots:
|
|||
private:
|
||||
QString _codes;
|
||||
|
||||
bool _isWaitingRead = false;
|
||||
std::function<QString(void)> _getInputFn;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ enum class CrashCode : int {
|
|||
AlreadyStart,
|
||||
LanguageFile,
|
||||
PluginSetting,
|
||||
ScriptInitFailed,
|
||||
GenericCallNotSupported
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "class/wingmessagebox.h"
|
||||
#include "class/wingupdater.h"
|
||||
#include "control/toast.h"
|
||||
#include "define.h"
|
||||
#include "encodingdialog.h"
|
||||
#include "fileinfodialog.h"
|
||||
#include "finddialog.h"
|
||||
|
@ -254,7 +255,11 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
std::placeholders::_1);
|
||||
sm.registerCallBack(ScriptMachine::Background, callbacks);
|
||||
} else {
|
||||
// TODO
|
||||
QMessageBox::critical(this, qAppName(),
|
||||
tr("ScriptEngineInitFailed"));
|
||||
set.setScriptEnabled(false);
|
||||
set.save(SettingManager::SCRIPT);
|
||||
throw CrashCode::ScriptInitFailed;
|
||||
}
|
||||
|
||||
// At this time, AngelScript service plugin has started
|
||||
|
@ -1011,6 +1016,10 @@ 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);
|
||||
});
|
||||
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("ScriptConsole"),
|
||||
tr("ScriptConsole"), m_scriptConsole);
|
||||
|
@ -3167,8 +3176,20 @@ void MainWindow::connectEditorView(EditorView *editor) {
|
|||
editor->setProperty("__RELOAD__", false);
|
||||
connect(editor, &EditorView::need2Reload, this, [editor, this]() {
|
||||
if (editor->isBigFile()) {
|
||||
editor->reload();
|
||||
auto fileName = editor->fileName();
|
||||
if (!QFile::exists(fileName)) {
|
||||
editor->raise();
|
||||
WingMessageBox::critical(this, tr("Error"),
|
||||
tr("FileCloseBigFile"));
|
||||
closeEditor(editor, true);
|
||||
}
|
||||
if (currentEditor() == editor) {
|
||||
editor->reload();
|
||||
} else {
|
||||
editor->setProperty("__RELOAD__", true);
|
||||
}
|
||||
} else {
|
||||
editor->hexEditor()->document()->setDocSaved(false);
|
||||
if (currentEditor() == editor) {
|
||||
auto ret = WingMessageBox::question(this, tr("Reload"),
|
||||
tr("ReloadNeededYesOrNo"));
|
||||
|
@ -3178,6 +3199,7 @@ void MainWindow::connectEditorView(EditorView *editor) {
|
|||
} else {
|
||||
editor->setProperty("__RELOAD__", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3207,11 +3229,15 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
auto hexeditor = cur->hexEditor();
|
||||
auto needReload = cur->property("__RELOAD__").toBool();
|
||||
if (needReload) {
|
||||
if (cur->isBigFile()) {
|
||||
cur->reload();
|
||||
} else {
|
||||
auto ret = WingMessageBox::question(this, tr("Reload"),
|
||||
tr("ReloadNeededYesOrNo"));
|
||||
if (ret == QMessageBox::Yes) {
|
||||
cur->reload();
|
||||
}
|
||||
}
|
||||
cur->setProperty("__RELOAD__", false);
|
||||
}
|
||||
connect(hexeditor, &QHexView::cursorLocationChanged, this,
|
||||
|
|
Loading…
Reference in New Issue