feat: 十六进制编辑区注册的菜单支持编辑器上下文;用户交互优化;
This commit is contained in:
parent
af15ffc8aa
commit
6678c7b9ff
|
@ -25,6 +25,7 @@ option(BUILD_TEST_PLUGIN OFF)
|
|||
option(BUILD_SHARED_MEM_EXT OFF)
|
||||
|
||||
add_definitions(-DAS_NO_THREADS)
|
||||
add_definitions(-DWING_SYSTEM_NAME="${CMAKE_SYSTEM_NAME}")
|
||||
|
||||
if(BUILD_TEST_PLUGIN)
|
||||
add_subdirectory(TestPlugin)
|
||||
|
@ -308,7 +309,9 @@ set(CLASS_SRC
|
|||
src/class/changedstringlist.h
|
||||
src/class/changedstringlist.cpp
|
||||
src/class/editorviewcontext.h
|
||||
src/class/editorviewcontext.cpp)
|
||||
src/class/editorviewcontext.cpp
|
||||
src/class/consolehighlighanim.h
|
||||
src/class/consolehighlighanim.cpp)
|
||||
|
||||
set(INTERNAL_PLG_SRC
|
||||
src/class/wingangelapi.h src/class/wingangelapi.cpp
|
||||
|
|
|
@ -31,6 +31,7 @@ TestHexExt::TestHexExt() : WingHex::IWingHexEditorPlugin() {
|
|||
a->setChecked(true);
|
||||
connect(a, &QAction::toggled, this, &TestHexExt::setColVisible);
|
||||
m_context->addAction(a);
|
||||
m_aVisCol = a;
|
||||
}
|
||||
|
||||
bool TestHexExt::init(const std::unique_ptr<QSettings> &set) {
|
||||
|
@ -52,7 +53,8 @@ TestHexExt::registeredRibbonTools() const {
|
|||
}
|
||||
|
||||
QMargins TestHexExt::contentMargins(WingHex::HexEditorContext *context) const {
|
||||
if (!_visCol) {
|
||||
auto visCol = context->property("TestHexExt.colVis").toBool();
|
||||
if (!visCol) {
|
||||
return {};
|
||||
}
|
||||
auto lines = context->documentLines();
|
||||
|
@ -65,9 +67,23 @@ QMargins TestHexExt::contentMargins(WingHex::HexEditorContext *context) const {
|
|||
return {int(colLen) + 1, 0, 0, 0};
|
||||
}
|
||||
|
||||
void TestHexExt::prepareCallEditorContext(WingHex::HexEditorContext *context) {
|
||||
_curContext = context;
|
||||
auto b = isShowLinePannel(context);
|
||||
m_aVisCol->blockSignals(true);
|
||||
m_aVisCol->setChecked(b);
|
||||
m_aVisCol->blockSignals(false);
|
||||
}
|
||||
|
||||
void TestHexExt::finishCallEditorContext(WingHex::HexEditorContext *context) {
|
||||
Q_UNUSED(context);
|
||||
_curContext = nullptr;
|
||||
}
|
||||
|
||||
void TestHexExt::onPaintEvent(QPainter *painter, const QWidget *w,
|
||||
WingHex::HexEditorContext *context) {
|
||||
if (!_visCol) {
|
||||
auto visCol = isShowLinePannel(context);
|
||||
if (!visCol) {
|
||||
return;
|
||||
}
|
||||
painter->save();
|
||||
|
@ -104,4 +120,17 @@ void TestHexExt::onPaintEvent(QPainter *painter, const QWidget *w,
|
|||
painter->restore();
|
||||
}
|
||||
|
||||
void TestHexExt::setColVisible(bool b) { _visCol = b; }
|
||||
bool TestHexExt::isShowLinePannel(WingHex::HexEditorContext *context) {
|
||||
auto pp = context->property("TestHexExt.colVis");
|
||||
if (pp.isNull()) {
|
||||
context->setProperty("TestHexExt.colVis", true);
|
||||
return true;
|
||||
}
|
||||
return pp.toBool();
|
||||
}
|
||||
|
||||
void TestHexExt::setColVisible(bool b) {
|
||||
if (_curContext) {
|
||||
_curContext->setProperty("TestHexExt.colVis", b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,16 +52,26 @@ public:
|
|||
virtual QMargins
|
||||
contentMargins(WingHex::HexEditorContext *context) const override;
|
||||
|
||||
public:
|
||||
virtual void
|
||||
prepareCallEditorContext(WingHex::HexEditorContext *context) override;
|
||||
virtual void
|
||||
finishCallEditorContext(WingHex::HexEditorContext *context) override;
|
||||
|
||||
public:
|
||||
virtual void onPaintEvent(QPainter *painter, const QWidget *w,
|
||||
WingHex::HexEditorContext *context) override;
|
||||
|
||||
private:
|
||||
bool isShowLinePannel(WingHex::HexEditorContext *context);
|
||||
|
||||
private slots:
|
||||
void setColVisible(bool b);
|
||||
|
||||
private:
|
||||
QMenu *m_context;
|
||||
bool _visCol = true;
|
||||
QAction *m_aVisCol;
|
||||
WingHex::HexEditorContext *_curContext = nullptr;
|
||||
};
|
||||
|
||||
#endif // TESTHEXEXT_H
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit fad774858664d6a137c21b0c2af73ca209cc2f47
|
||||
Subproject commit 4492bf2aaba267b80ec324c456f0584dcd0efc03
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
147
main.cpp
147
main.cpp
|
@ -1,8 +1,118 @@
|
|||
#include "class/appmanager.h"
|
||||
#include "class/languagemanager.h"
|
||||
#include "class/settingmanager.h"
|
||||
#include "class/wingmessagebox.h"
|
||||
|
||||
#include "define.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QSettings>
|
||||
|
||||
void loadEnvConfig(int argc, char *argv[]) {
|
||||
QFileInfo info(argv[0]);
|
||||
QDir appDir(info.absoluteDir());
|
||||
|
||||
if (!appDir.exists(QStringLiteral("config.ini"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto path = appDir.absoluteFilePath(QStringLiteral("config.ini"));
|
||||
QSettings set(path, QSettings::IniFormat);
|
||||
|
||||
// General
|
||||
for (auto &kv : set.childKeys()) {
|
||||
qputenv(qPrintable(kv), set.value(kv).toByteArray());
|
||||
}
|
||||
|
||||
auto groups = set.childGroups();
|
||||
auto evaluate = [](const QProcessEnvironment &env,
|
||||
const QString &statement) {
|
||||
// Parse and evaluate statements:
|
||||
// $NAME -> check existence
|
||||
// $NAME=VALUE -> ignore-case full match
|
||||
// $NAME==VALUE -> case-sensitive full match
|
||||
// $NAME:=VALUE -> ignore-case contains
|
||||
// $NAME::=VALUE -> case-sensitive contains
|
||||
// VALUE: unless pure digits, must be enclosed in "" or ''
|
||||
|
||||
static const QRegularExpression re(
|
||||
R"(^\$([A-Za-z_][A-Za-z0-9_]*)(?:\s*(==|::=|:=|=)\s*(\d+|"[^"]*"|'[^']*'))?$)");
|
||||
auto match = re.match(statement);
|
||||
if (!match.hasMatch()) {
|
||||
qWarning("[main::loadEnvConfig] Invalid syntax: %s",
|
||||
qUtf8Printable(statement));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto name = match.captured(1);
|
||||
auto op = match.captured(2);
|
||||
auto value = match.captured(3);
|
||||
|
||||
// Existence check: no operator provided
|
||||
if (op.isEmpty()) {
|
||||
return env.contains(name);
|
||||
}
|
||||
|
||||
if (!value.isEmpty() &&
|
||||
((value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith('\'') && value.endsWith('\'')))) {
|
||||
value.removeFirst().removeLast();
|
||||
}
|
||||
|
||||
auto var = env.value(name);
|
||||
|
||||
// Evaluate based on operator
|
||||
if (op == QStringLiteral(":=") || op == QStringLiteral("::=")) {
|
||||
const QStringList items = var.split(QDir::listSeparator());
|
||||
for (const QString &item : items) {
|
||||
if (op == QStringLiteral(":=")) {
|
||||
if (item.contains(value, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (item.contains(value, Qt::CaseSensitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op == "=") {
|
||||
return QString::compare(var, value, Qt::CaseInsensitive) == 0;
|
||||
} else if (op == "==") {
|
||||
return var == value;
|
||||
} else {
|
||||
qWarning("[main::loadEnvConfig] Unknown operator: %s",
|
||||
qUtf8Printable(op));
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto env = QProcessEnvironment::systemEnvironment();
|
||||
|
||||
constexpr auto syslen = std::char_traits<char>::length(WING_SYSTEM_NAME);
|
||||
if (syslen) {
|
||||
set.beginGroup(WING_SYSTEM_NAME);
|
||||
for (auto &kv : set.childKeys()) {
|
||||
qputenv(qPrintable(kv), set.value(kv).toByteArray());
|
||||
}
|
||||
set.endGroup();
|
||||
}
|
||||
|
||||
for (auto &g : groups) {
|
||||
if (evaluate(env, g)) {
|
||||
set.beginGroup(g);
|
||||
for (auto &kv : set.childKeys()) {
|
||||
qputenv(qPrintable(kv), set.value(kv).toByteArray());
|
||||
}
|
||||
set.endGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
/* 有关对在 QT5 的 Win 平台禁用高 dpi 支持
|
||||
* 的原因说明:
|
||||
|
@ -18,23 +128,13 @@ int main(int argc, char *argv[]) {
|
|||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
|
||||
loadEnvConfig(argc, argv);
|
||||
|
||||
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// fix wayland issue (a workaround): floating dock not work
|
||||
// reference:
|
||||
// https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/
|
||||
// issues/714#issuecomment-2802752677
|
||||
auto denv = qgetenv("XDG_SESSION_TYPE");
|
||||
if (denv.isEmpty() ||
|
||||
denv.compare(QByteArrayLiteral("wayland"), Qt::CaseInsensitive) == 0) {
|
||||
qputenv("QT_QPA_PLATFORM", "xcb");
|
||||
}
|
||||
#endif
|
||||
|
||||
QApplication::setApplicationName(APP_NAME);
|
||||
QApplication::setOrganizationName(APP_ORG);
|
||||
QApplication::setApplicationVersion(WINGHEX_VERSION);
|
||||
QApplication::setApplicationName(QStringLiteral(APP_NAME));
|
||||
QApplication::setOrganizationName(QStringLiteral(APP_ORG));
|
||||
QApplication::setApplicationVersion(QStringLiteral(WINGHEX_VERSION));
|
||||
|
||||
try {
|
||||
AppManager a(argc, argv);
|
||||
|
@ -61,5 +161,22 @@ int main(int argc, char *argv[]) {
|
|||
return a.exec();
|
||||
} catch (CrashCode errCode) {
|
||||
return int(errCode);
|
||||
} catch (const std::bad_alloc &) {
|
||||
auto &lang = LanguageManager::instance();
|
||||
auto df = lang.defaultLocale();
|
||||
|
||||
// this exception can only occur when your memory are too limit or
|
||||
// you are writing more than 2GB with QByteArray on 32-bit operating
|
||||
// system.
|
||||
if (QLocale::China == df.territory()) {
|
||||
WingMessageBox::critical(
|
||||
nullptr, QStringLiteral(APP_NAME),
|
||||
QStringLiteral("崩溃啦!发生内存溢出异常!"));
|
||||
} else {
|
||||
WingMessageBox::critical(
|
||||
nullptr, QStringLiteral(APP_NAME),
|
||||
QStringLiteral("WingHexExplorer2 is out of memory. Crashed!"));
|
||||
}
|
||||
return int(CrashCode::OutofMemory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
; ========= 羽云十六进制编辑器2应用环境配置文件说明 ==========
|
||||
;
|
||||
; 如果区块名开头没有 $ ,则认为普通区块,General 会在所有的操作系统生效
|
||||
; 如果你想在某些操作系统生效,可以指定区块名为:Windows, Linux 和 Darwin
|
||||
; 对于 Linux 系统,如果包含 uname 工具,则区块名为 uname -s 的输出结果
|
||||
;
|
||||
|
||||
; ================= 配置文件区块扩展语法说明 =================
|
||||
;
|
||||
; 语句格式:
|
||||
; $NAME [OPERATOR VALUE]
|
||||
;
|
||||
; 各字段说明:
|
||||
; $ • 语句起始标记,必需
|
||||
;
|
||||
; NAME • 环境变量名
|
||||
; • 以字母或“_”开头,后续可包含字母、数字或“_”
|
||||
;
|
||||
; OPERATOR • 可选运算符:
|
||||
; = 忽略大小写全匹配
|
||||
; == 区分大小写全匹配
|
||||
; := 忽略大小写子串包含
|
||||
; ::= 区分大小写子串包含
|
||||
;
|
||||
; VALUE • 可选比较值,仅在 OPERATOR 存在时使用
|
||||
; • 格式必须是:
|
||||
; — 纯数字(例如 12345)
|
||||
; — 或用双引号包裹的字符串("text")
|
||||
; — 或用单引号包裹的字符串('text')
|
||||
;
|
||||
; 存在性检查:
|
||||
; 若仅写 “$NAME”,无 OPERATOR 和 VALUE,即检查该环境变量是否已定义
|
||||
;
|
||||
; --------------------- 示例 ---------------------
|
||||
; $XDG_SESSION_TYPE="wayland"
|
||||
; → 忽略大小写地检查 XDG_SESSION_TYPE 是否等于 “wayland”
|
||||
;
|
||||
; $PATH:="/usr/local/bin"
|
||||
; → 忽略大小写地检查 PATH 中是否包含 “/usr/local/bin”
|
||||
;
|
||||
; $HOME==12345
|
||||
; → 区分大小写地检查 HOME 是否等于数字 12345
|
||||
;
|
||||
; $LD_LIBRARY_PATH::="/lib64"
|
||||
; → 区分大小写地检查 LD_LIBRARY_PATH 中是否包含 “/lib64”
|
||||
;
|
||||
; $HOME
|
||||
; → 检查 HOME 是否已定义(存在性检查)
|
||||
; =====================================================
|
||||
|
||||
[General]
|
||||
WING_DISABLE_PLUGIN_SYSTEM=0
|
||||
WING_DISABLE_EXTDRV=0
|
||||
WING_DISABLE_PLUGIN=0
|
||||
WING_DEBUG=0
|
||||
|
||||
[$XDG_SESSION_TYPE="wayland"]
|
||||
QT_QPA_PLATFORM=xcb
|
||||
|
||||
|
|
@ -497,7 +497,6 @@ QList<CodeInfoTip> AsCompletion::parseDocument() {
|
|||
|
||||
// first preprocess the code
|
||||
AsPreprocesser prepc(engine);
|
||||
prepc.setIsCodeCompleteMode(true);
|
||||
prepc.setIncludeCallback(&AsCompletion::includeCallBack, this);
|
||||
|
||||
auto r = prepc.loadSectionFromMemory(QStringLiteral("ASCOMPLETION"),
|
||||
|
|
|
@ -186,13 +186,15 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
QStack<std::optional<bool>> m_condtionStack;
|
||||
|
||||
bool isEndLine = true;
|
||||
|
||||
while (pos < modifiedScript.size()) {
|
||||
auto SECTION = sectionname.toUtf8();
|
||||
|
||||
asUINT len = 0;
|
||||
asETokenClass t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos, &len);
|
||||
if (t == asTC_UNKNOWN && modifiedScript[pos] == '#' &&
|
||||
if (isEndLine && t == asTC_UNKNOWN && modifiedScript[pos] == '#' &&
|
||||
(pos + 1 < modifiedScript.size())) {
|
||||
int start = pos++;
|
||||
|
||||
|
@ -217,12 +219,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
if (std::any_of(modifiedScript.data() + pos,
|
||||
modifiedScript.data() + pos + len,
|
||||
[](char ch) { return ch == '\n'; })) {
|
||||
if (_isCodeCompleteMode) {
|
||||
pos = modifiedScript.indexOf('\n', pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto str = QObject::tr("IfDefNoWord");
|
||||
auto str = tr("IfDefNoWord");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -234,16 +231,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
}
|
||||
|
||||
if (isIfDef || isIfnDef) {
|
||||
if (_isCodeCompleteMode) {
|
||||
auto pos = modifiedScript.indexOf('\n', start);
|
||||
if (pos < 0) {
|
||||
overwriteCode(modifiedScript, start,
|
||||
modifiedScript.size() - start - 1);
|
||||
} else {
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
QByteArray word = modifiedScript.sliced(pos, len);
|
||||
|
||||
|
@ -267,23 +254,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
qDebug().noquote() << modifiedScript;
|
||||
#endif
|
||||
} else {
|
||||
auto str = QObject::tr("IfDefInvalidWord");
|
||||
auto str = tr("IfDefInvalidWord");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else if (isIf) {
|
||||
if (_isCodeCompleteMode) {
|
||||
auto pos = modifiedScript.indexOf('\n', start);
|
||||
if (pos < 0) {
|
||||
overwriteCode(modifiedScript, start,
|
||||
modifiedScript.size() - start - 1);
|
||||
} else {
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// evalutate the string
|
||||
auto npos = modifiedScript.indexOf('\n', pos);
|
||||
QByteArray codes;
|
||||
|
@ -303,7 +280,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
ok);
|
||||
|
||||
if (ret < 0) {
|
||||
auto str = QObject::tr("CalIfFailed");
|
||||
auto str = tr("CalIfFailed");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -324,20 +301,6 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
QByteArray word = modifiedScript.sliced(pos, len);
|
||||
pos += len;
|
||||
|
||||
if (_isCodeCompleteMode) {
|
||||
defineWord(word, {});
|
||||
auto pos = modifiedScript.indexOf('\n', start);
|
||||
if (pos < 0) {
|
||||
overwriteCode(modifiedScript, start,
|
||||
modifiedScript.size() - start -
|
||||
1);
|
||||
} else {
|
||||
overwriteCode(modifiedScript, start,
|
||||
pos - start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
t = engine->ParseToken(modifiedScript.data() + pos,
|
||||
modifiedScript.size() - pos,
|
||||
&len);
|
||||
|
@ -366,7 +329,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
defineWord(word, v);
|
||||
} break;
|
||||
default:
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
|
@ -381,42 +344,20 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else {
|
||||
if (_isCodeCompleteMode) {
|
||||
auto pos = modifiedScript.indexOf('\n', start);
|
||||
if (pos < 0) {
|
||||
overwriteCode(modifiedScript, start,
|
||||
modifiedScript.size() - start -
|
||||
1);
|
||||
} else {
|
||||
overwriteCode(modifiedScript, start,
|
||||
pos - start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto str = QObject::tr("InvalidDef");
|
||||
auto str = tr("InvalidDef");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else if (isUnDef) {
|
||||
if (_isCodeCompleteMode) {
|
||||
auto pos = modifiedScript.indexOf('\n', start);
|
||||
if (pos < 0) {
|
||||
overwriteCode(modifiedScript, start,
|
||||
modifiedScript.size() - start - 1);
|
||||
} else {
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
QByteArray word = modifiedScript.sliced(pos, len);
|
||||
|
||||
|
@ -427,13 +368,13 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
constexpr auto PREFIX = "__";
|
||||
if (word.startsWith(PREFIX) && word.endsWith(PREFIX)) {
|
||||
// Warning
|
||||
auto str = QObject::tr("ReservedMarcoType");
|
||||
auto str = tr("ReservedMarcoType");
|
||||
engine->WriteMessage(
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_WARNING, str.toUtf8());
|
||||
} else {
|
||||
if (!definedWords.remove(word)) {
|
||||
auto str = QObject::tr("MarcoNotFound:") + word;
|
||||
auto str = tr("MarcoNotFound:") + word;
|
||||
engine->WriteMessage(
|
||||
SECTION, getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_WARNING, str.toUtf8());
|
||||
|
@ -442,14 +383,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else {
|
||||
auto str = QObject::tr("InvalidDef");
|
||||
auto str = tr("InvalidDef");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -457,12 +398,8 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
}
|
||||
}
|
||||
} else if (token == "else") {
|
||||
if (_isCodeCompleteMode) {
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
continue;
|
||||
}
|
||||
if (m_condtionStack.isEmpty()) {
|
||||
auto str = QObject::tr("NoMatchingIf");
|
||||
auto str = tr("NoMatchingIf");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -478,14 +415,14 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos - 1)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(
|
||||
SECTION, getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
}
|
||||
} else {
|
||||
auto str = QObject::tr("DupElseDef");
|
||||
auto str = tr("DupElseDef");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -496,13 +433,9 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
qDebug().noquote() << modifiedScript;
|
||||
#endif
|
||||
} else if (token == "endif") {
|
||||
if (_isCodeCompleteMode) {
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
continue;
|
||||
}
|
||||
// Only remove the #endif if there was a matching #if
|
||||
if (m_condtionStack.isEmpty()) {
|
||||
auto str = QObject::tr("NoMatchingIf");
|
||||
auto str = tr("NoMatchingIf");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -514,7 +447,7 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
|
||||
// ensure end line
|
||||
if (endLinePassFailed(modifiedScript, pos)) {
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
|
@ -524,67 +457,71 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
qDebug().noquote() << modifiedScript;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (!_isCodeCompleteMode) {
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
// define replace
|
||||
auto word = modifiedScript.sliced(pos, len);
|
||||
if (word == PROMISE_AWAIT) {
|
||||
auto npos = pos + len;
|
||||
asUINT total = 0;
|
||||
auto t = engine->ParseToken(
|
||||
modifiedScript.data() + npos,
|
||||
modifiedScript.size() - npos, &total);
|
||||
if (t == asTC_WHITESPACE) {
|
||||
npos += total;
|
||||
t = engine->ParseToken(modifiedScript.data() + npos,
|
||||
modifiedScript.size() - npos,
|
||||
&total);
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
// ok
|
||||
auto word = modifiedScript.sliced(npos, total);
|
||||
auto data = "(" + word +
|
||||
")." PROMISE_YIELD
|
||||
"()." PROMISE_UNWRAP "()";
|
||||
auto oldLen = npos - pos + word.length();
|
||||
modifiedScript.replace(pos, oldLen, data);
|
||||
pos = npos;
|
||||
pos += data.length() - oldLen + word.length();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto str = QObject::tr("UnexceptedToken");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos),
|
||||
1, asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
} else if (word == "__LINE__") {
|
||||
auto data = QByteArray::number(
|
||||
getLineCount(modifiedScript, pos));
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else if (word == "__SECTION__") {
|
||||
auto data = SECTION;
|
||||
data.prepend('"').append('"');
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else if (word == "__SECTION_BASE__") {
|
||||
auto data = QFileInfo(SECTION).baseName().toUtf8();
|
||||
data.prepend('"').append('"');
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else {
|
||||
auto rword = findReplaceResult(word);
|
||||
if (word != rword) {
|
||||
modifiedScript.replace(pos, len, rword);
|
||||
len = rword.length();
|
||||
isEndLine = true;
|
||||
} else {
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
// define replace
|
||||
auto word = modifiedScript.sliced(pos, len);
|
||||
if (word == PROMISE_AWAIT) {
|
||||
auto npos = pos + len;
|
||||
asUINT total = 0;
|
||||
auto t = engine->ParseToken(modifiedScript.data() + npos,
|
||||
modifiedScript.size() - npos,
|
||||
&total);
|
||||
if (t == asTC_WHITESPACE) {
|
||||
npos += total;
|
||||
t = engine->ParseToken(modifiedScript.data() + npos,
|
||||
modifiedScript.size() - npos,
|
||||
&total);
|
||||
if (t == asTC_IDENTIFIER) {
|
||||
// ok
|
||||
auto word = modifiedScript.sliced(npos, total);
|
||||
auto data = "(" + word +
|
||||
")." PROMISE_YIELD "()." PROMISE_UNWRAP
|
||||
"()";
|
||||
auto oldLen = npos - pos + word.length();
|
||||
modifiedScript.replace(pos, oldLen, data);
|
||||
pos = npos;
|
||||
pos += data.length() - oldLen + word.length();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto str = tr("UnexceptedToken");
|
||||
engine->WriteMessage(SECTION,
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
return asERROR;
|
||||
} else if (word == "__LINE__") {
|
||||
auto data =
|
||||
QByteArray::number(getLineCount(modifiedScript, pos));
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else if (word == "__SECTION__") {
|
||||
auto data = SECTION;
|
||||
data.prepend('"').append('"');
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else if (word == "__SECTION_BASE__") {
|
||||
auto data = QFileInfo(SECTION).baseName().toUtf8();
|
||||
data.prepend('"').append('"');
|
||||
modifiedScript.replace(pos, len, data);
|
||||
pos += data.length();
|
||||
continue;
|
||||
} else {
|
||||
auto rword = findReplaceResult(word);
|
||||
if (word != rword) {
|
||||
modifiedScript.replace(pos, len, rword);
|
||||
len = rword.length();
|
||||
}
|
||||
}
|
||||
} else if (t == asTC_WHITESPACE) {
|
||||
isEndLine = std::any_of(modifiedScript.data() + pos,
|
||||
modifiedScript.data() + pos + len,
|
||||
[](char ch) { return ch == '\n'; });
|
||||
}
|
||||
pos += len;
|
||||
}
|
||||
|
@ -644,11 +581,11 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// line breaks
|
||||
auto p = includefile.indexOf('\n');
|
||||
if (p >= 0) {
|
||||
auto str =
|
||||
QObject::tr("Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") + includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
auto str = tr("Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") +
|
||||
includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
|
@ -690,12 +627,11 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
auto p = includefile.indexOf('\n');
|
||||
auto ws = includefile.indexOf(' ');
|
||||
if (!includefile.isEmpty() && p >= 0 && ws >= 0) {
|
||||
auto str =
|
||||
QObject::tr(
|
||||
"Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") + includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
auto str = tr("Invalid file name for #include; "
|
||||
"it contains a line-break: ") +
|
||||
QStringLiteral("'") +
|
||||
includefile.left(p) +
|
||||
QStringLiteral("'");
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
|
@ -710,10 +646,9 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
pos - start);
|
||||
}
|
||||
} else {
|
||||
auto str =
|
||||
QObject::tr("Invalid file name for #include; "
|
||||
"it contains a line-break or "
|
||||
"unpaired symbol");
|
||||
auto str = tr("Invalid file name for #include; "
|
||||
"it contains a line-break or "
|
||||
"unpaired symbol");
|
||||
engine->WriteMessage(sectionname.toUtf8(), 0, 0,
|
||||
asMSGTYPE_ERROR, str.toUtf8());
|
||||
}
|
||||
|
@ -734,20 +669,17 @@ int AsPreprocesser::processScriptSection(const QByteArray &script,
|
|||
// to avoid compiler error
|
||||
overwriteCode(modifiedScript, start, pos - start);
|
||||
|
||||
if (!_isCodeCompleteMode) {
|
||||
int r = pragmaCallback
|
||||
? pragmaCallback(pragmaText, this,
|
||||
sectionname, pragmaParam)
|
||||
: -1;
|
||||
if (r < 0) {
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR,
|
||||
QObject::tr("Invalid #pragma directive")
|
||||
.toUtf8());
|
||||
return r;
|
||||
}
|
||||
int r = pragmaCallback
|
||||
? pragmaCallback(pragmaText, this, sectionname,
|
||||
pragmaParam)
|
||||
: -1;
|
||||
if (r < 0) {
|
||||
engine->WriteMessage(
|
||||
sectionname.toUtf8(),
|
||||
getLineCount(modifiedScript, pos), 1,
|
||||
asMSGTYPE_ERROR,
|
||||
tr("Invalid #pragma directive").toUtf8());
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -810,8 +742,7 @@ int AsPreprocesser::loadScriptSection(const QString &filename) {
|
|||
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
// Write a message to the engine's message callback
|
||||
auto msg = QObject::tr("Failed to open script file ") +
|
||||
QStringLiteral("'") +
|
||||
auto msg = tr("Failed to open script file ") + QStringLiteral("'") +
|
||||
QFileInfo(filename).absoluteFilePath() + QStringLiteral("'");
|
||||
engine->WriteMessage(filename.toUtf8(), 0, 0, asMSGTYPE_ERROR,
|
||||
msg.toUtf8());
|
||||
|
@ -1022,12 +953,6 @@ QByteArray AsPreprocesser::findReplaceResult(const QByteArray &v) {
|
|||
return r;
|
||||
}
|
||||
|
||||
bool AsPreprocesser::isCodeCompleteMode() const { return _isCodeCompleteMode; }
|
||||
|
||||
void AsPreprocesser::setIsCodeCompleteMode(bool newIsCodeCompleteMode) {
|
||||
_isCodeCompleteMode = newIsCodeCompleteMode;
|
||||
}
|
||||
|
||||
QHash<QString, QByteArray> AsPreprocesser::definedMacros() const {
|
||||
return definedWords;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#pragma warning(disable : 4786)
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QEventLoop>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
|
@ -74,6 +75,7 @@ typedef int (*PRAGMACALLBACK_t)(const QByteArray &pragmaText,
|
|||
* * #ifndef <word>
|
||||
*/
|
||||
class AsPreprocesser {
|
||||
Q_DECLARE_TR_FUNCTIONS(AsPreprocesser)
|
||||
public:
|
||||
explicit AsPreprocesser(asIScriptEngine *engine);
|
||||
virtual ~AsPreprocesser();
|
||||
|
@ -113,9 +115,6 @@ public:
|
|||
|
||||
QString sectionName(unsigned int idx) const;
|
||||
|
||||
bool isCodeCompleteMode() const;
|
||||
void setIsCodeCompleteMode(bool newIsCodeCompleteMode);
|
||||
|
||||
QHash<QString, QByteArray> definedMacros() const;
|
||||
|
||||
protected:
|
||||
|
@ -155,9 +154,6 @@ protected:
|
|||
QStringList includedScripts;
|
||||
|
||||
QHash<QString, QByteArray> definedWords;
|
||||
|
||||
private:
|
||||
bool _isCodeCompleteMode = false;
|
||||
};
|
||||
|
||||
#endif // ASPREPROCESSER_H
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*==============================================================================
|
||||
** 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 "consolehighlighanim.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QWidget>
|
||||
|
||||
ConsoleHighlighAnim::ConsoleHighlighAnim(QObject *parent)
|
||||
: QObject(parent), m_highlightColor(qApp->palette().highlight().color()),
|
||||
m_alpha(0), _w(nullptr), _anim(nullptr) {
|
||||
_anim = new QPropertyAnimation(this, QByteArrayLiteral("alpha"), this);
|
||||
_anim->setStartValue(10);
|
||||
_anim->setEndValue(100);
|
||||
_anim->setDuration(1000);
|
||||
_anim->setEasingCurve(QEasingCurve::InOutQuad);
|
||||
_anim->setLoopCount(5);
|
||||
connect(_anim, &QPropertyAnimation::finished, this, [this]() {
|
||||
if (_w) {
|
||||
_w->setStyleSheet({});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int ConsoleHighlighAnim::getAlpha() const { return m_alpha; }
|
||||
|
||||
void ConsoleHighlighAnim::setAlpha(int newAlpha) {
|
||||
if (m_alpha == newAlpha)
|
||||
return;
|
||||
m_alpha = newAlpha;
|
||||
|
||||
auto clsname = _w->metaObject()->className();
|
||||
auto ss = QStringLiteral("background-color: rgba(%1, %2, %3, %4);")
|
||||
.arg(m_highlightColor.red())
|
||||
.arg(m_highlightColor.green())
|
||||
.arg(m_highlightColor.blue())
|
||||
.arg(m_alpha);
|
||||
if (clsname) {
|
||||
ss.prepend('{').prepend(clsname).append('}');
|
||||
}
|
||||
|
||||
if (_w) {
|
||||
_w->setStyleSheet(ss);
|
||||
}
|
||||
|
||||
Q_EMIT alphaChanged();
|
||||
}
|
||||
|
||||
QWidget *ConsoleHighlighAnim::widget() const { return _w; }
|
||||
|
||||
void ConsoleHighlighAnim::setWidget(QWidget *newW) {
|
||||
if (_w) {
|
||||
_w->setStyleSheet({});
|
||||
}
|
||||
_w = newW;
|
||||
auto ss = QStringLiteral("background-color: rgba(%1, %2, %3, %4);")
|
||||
.arg(m_highlightColor.red())
|
||||
.arg(m_highlightColor.green())
|
||||
.arg(m_highlightColor.blue())
|
||||
.arg(m_alpha);
|
||||
if (_w) {
|
||||
_w->setStyleSheet(ss);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleHighlighAnim::start() {
|
||||
if (_w == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (_anim->state() == QPropertyAnimation::Stopped) {
|
||||
_anim->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleHighlighAnim::stop() {
|
||||
if (_anim->state() == QPropertyAnimation::Running) {
|
||||
_anim->stop();
|
||||
|
||||
if (_w) {
|
||||
_w->setStyleSheet({});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*==============================================================================
|
||||
** 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 CONSOLEHIGHLIGHANIM_H
|
||||
#define CONSOLEHIGHLIGHANIM_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QObject>
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
class ConsoleHighlighAnim : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int alpha READ getAlpha WRITE setAlpha NOTIFY alphaChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit ConsoleHighlighAnim(QObject *parent = nullptr);
|
||||
|
||||
public:
|
||||
int getAlpha() const;
|
||||
void setAlpha(int newAlpha);
|
||||
|
||||
QWidget *widget() const;
|
||||
void setWidget(QWidget *newW);
|
||||
|
||||
public:
|
||||
void start();
|
||||
|
||||
// 停止动画并清除样式
|
||||
void stop();
|
||||
|
||||
signals:
|
||||
void alphaChanged();
|
||||
|
||||
private:
|
||||
QColor m_highlightColor;
|
||||
int m_alpha;
|
||||
QWidget *_w;
|
||||
QPropertyAnimation *_anim;
|
||||
};
|
||||
|
||||
#endif // CONSOLEHIGHLIGHANIM_H
|
|
@ -18,10 +18,14 @@
|
|||
#include "editorviewcontext.h"
|
||||
|
||||
EditorViewContext::EditorViewContext(QHexView *view)
|
||||
: WingHex::HexEditorContext(), _view(view) {
|
||||
: WingHex::HexEditorContext(view), _view(view) {
|
||||
Q_ASSERT(view);
|
||||
}
|
||||
|
||||
QString EditorViewContext::docFileName() const {
|
||||
return _view->windowFilePath();
|
||||
}
|
||||
|
||||
QFontMetricsF EditorViewContext::fontMetrics() const {
|
||||
return _view->fontMetrics();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
|
||||
// HexEditorPalette interface
|
||||
public:
|
||||
virtual QString docFileName() const override;
|
||||
virtual QFontMetricsF fontMetrics() const override;
|
||||
virtual QColor headerColor() const override;
|
||||
virtual QColor addressColor() const override;
|
||||
|
|
|
@ -4063,12 +4063,7 @@ void PluginSystem::try2LoadHexExtPlugin() {
|
|||
|
||||
_manHexInfo = m;
|
||||
|
||||
{
|
||||
auto menu = p->registeredHexContextMenu();
|
||||
if (menu) {
|
||||
_win->m_hexContextMenu.append(menu);
|
||||
}
|
||||
}
|
||||
registerHexContextMenu(p);
|
||||
registerRibbonTools(p->registeredRibbonTools());
|
||||
registeredSettingPages(QVariant::fromValue(p),
|
||||
p->registeredSettingPages());
|
||||
|
@ -4142,6 +4137,30 @@ void PluginSystem::registerEvents(IWingPlugin *plg) {
|
|||
}
|
||||
}
|
||||
|
||||
void PluginSystem::registerHexContextMenu(IWingHexEditorInterface *inter) {
|
||||
Q_ASSERT(inter);
|
||||
auto menu = inter->registeredHexContextMenu();
|
||||
if (menu) {
|
||||
_win->m_hexContextMenu.append(menu);
|
||||
connect(menu, &QMenu::aboutToShow, this, [menu, inter]() {
|
||||
auto pp = menu->property("__CONTEXT__");
|
||||
auto ptr =
|
||||
reinterpret_cast<HexEditorContext *>(pp.value<quintptr>());
|
||||
if (ptr) {
|
||||
inter->prepareCallEditorContext(ptr);
|
||||
}
|
||||
});
|
||||
connect(menu, &QMenu::triggered, this, [menu, inter]() {
|
||||
auto pp = menu->property("__CONTEXT__");
|
||||
auto ptr =
|
||||
reinterpret_cast<HexEditorContext *>(pp.value<quintptr>());
|
||||
if (ptr) {
|
||||
inter->finishCallEditorContext(ptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSystem::applyFunctionTables(QObject *plg, const CallTable &fns) {
|
||||
plg->setProperty("__CALL_TABLE__", QVariant::fromValue(fns));
|
||||
plg->setProperty("__CALL_POINTER__", quintptr(this));
|
||||
|
@ -4217,13 +4236,7 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
|
|||
// ensure call only once
|
||||
registerRibbonTools(p->registeredRibbonTools());
|
||||
registerPluginDockWidgets(p);
|
||||
|
||||
{
|
||||
auto menu = p->registeredHexContextMenu();
|
||||
if (menu) {
|
||||
_win->m_hexContextMenu.append(menu);
|
||||
}
|
||||
}
|
||||
registerHexContextMenu(p);
|
||||
|
||||
{
|
||||
auto vieww = p->registeredEditorViewWidgets();
|
||||
|
|
|
@ -224,6 +224,8 @@ private:
|
|||
private:
|
||||
void registerEvents(IWingPlugin *plg);
|
||||
|
||||
void registerHexContextMenu(IWingHexEditorInterface *inter);
|
||||
|
||||
void applyFunctionTables(QObject *plg, const CallTable &fns);
|
||||
|
||||
bool isPluginLoaded(const WingDependency &d);
|
||||
|
|
|
@ -333,8 +333,9 @@ ErrFile EditorView::newFile(size_t index) {
|
|||
|
||||
removeMonitorPaths();
|
||||
auto istr = QString::number(index);
|
||||
m_fileName = tr("Untitled") + istr;
|
||||
this->setWindowTitle(m_fileName);
|
||||
auto fname = tr("Untitled") + istr;
|
||||
m_hex->setWindowFilePath(fname);
|
||||
this->setWindowTitle(fname);
|
||||
m_docType = DocumentType::File;
|
||||
m_isWorkSpace = false;
|
||||
m_isNewFile = true;
|
||||
|
@ -371,7 +372,8 @@ ErrFile EditorView::openFile(const QString &filename) {
|
|||
m_hex->setKeepSize(true);
|
||||
|
||||
m_docType = DocumentType::File;
|
||||
m_fileName = info.absoluteFilePath();
|
||||
auto fName = info.absoluteFilePath();
|
||||
m_hex->setWindowFilePath(fName);
|
||||
m_isNewFile = false;
|
||||
p->setDocSaved();
|
||||
|
||||
|
@ -379,8 +381,8 @@ ErrFile EditorView::openFile(const QString &filename) {
|
|||
connectDocSavedFlag(this);
|
||||
|
||||
auto tab = this->tabWidget();
|
||||
tab->setIcon(Utilities::getIconFromFile(style(), m_fileName));
|
||||
tab->setToolTip(m_fileName);
|
||||
tab->setIcon(Utilities::getIconFromFile(style(), fName));
|
||||
tab->setToolTip(fName);
|
||||
|
||||
addMonitorPath();
|
||||
}
|
||||
|
@ -435,7 +437,7 @@ ErrFile EditorView::openExtFile(const QString &ext, const QString &file) {
|
|||
_file = file;
|
||||
|
||||
m_docType = DocumentType::Extension;
|
||||
m_fileName = fileName;
|
||||
m_hex->setWindowFilePath(fileName);
|
||||
m_isNewFile = false;
|
||||
p->setDocSaved();
|
||||
|
||||
|
@ -513,7 +515,7 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
|||
return this->cloneParent()->save(workSpaceName, path, isExport,
|
||||
workSpaceAttr);
|
||||
}
|
||||
auto fileName = path.isEmpty() ? m_fileName : path;
|
||||
auto fileName = path.isEmpty() ? m_hex->windowFilePath() : path;
|
||||
auto doc = m_hex->document();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
|
@ -589,7 +591,8 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
|||
}
|
||||
}
|
||||
|
||||
if (!doc->isDocSaved() || m_fileName != fileName || isNewFile()) {
|
||||
if (!doc->isDocSaved() || m_hex->windowFilePath() != fileName ||
|
||||
isNewFile()) {
|
||||
if (m_docType == DocumentType::Extension) {
|
||||
if (_dev->isOpen()) {
|
||||
_dev->close();
|
||||
|
@ -611,7 +614,8 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
|||
if (doc->saveTo(&file, !isExport)) {
|
||||
file.close();
|
||||
if (!isExport) {
|
||||
m_fileName = QFileInfo(fileName).absoluteFilePath();
|
||||
m_hex->setWindowFilePath(
|
||||
QFileInfo(fileName).absoluteFilePath());
|
||||
|
||||
if (isNewFile()) {
|
||||
auto buffer = new QFileBuffer;
|
||||
|
@ -660,7 +664,7 @@ ErrFile EditorView::reload() {
|
|||
|
||||
switch (documentType()) {
|
||||
case DocumentType::File:
|
||||
return openFile(m_fileName);
|
||||
return openFile(m_hex->windowFilePath());
|
||||
case DocumentType::Extension:
|
||||
return openExtFile(_ext, _file);
|
||||
default:
|
||||
|
@ -741,13 +745,14 @@ void EditorView::connectDocSavedFlag(EditorView *editor) {
|
|||
connect(editor->m_hex->document().get(), &QHexDocument::documentSaved, this,
|
||||
[=](bool b) {
|
||||
QString fileName;
|
||||
auto fName = m_hex->windowFilePath();
|
||||
if (editor->isNewFile()) {
|
||||
fileName = m_fileName;
|
||||
fileName = fName;
|
||||
} else if (editor->isExtensionFile()) {
|
||||
auto idx = m_fileName.indexOf('}');
|
||||
fileName = m_fileName.mid(idx);
|
||||
auto idx = fName.indexOf('}');
|
||||
fileName = fName.mid(idx);
|
||||
} else {
|
||||
fileName = QFileInfo(m_fileName).fileName();
|
||||
fileName = QFileInfo(fName).fileName();
|
||||
}
|
||||
QString content;
|
||||
|
||||
|
@ -770,7 +775,7 @@ void EditorView::connectDocSavedFlag(EditorView *editor) {
|
|||
auto tab = this->tabWidget();
|
||||
if (tab->icon().isNull()) {
|
||||
tab->setIcon(
|
||||
Utilities::getIconFromFile(style(), m_fileName));
|
||||
Utilities::getIconFromFile(style(), fName));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -784,7 +789,7 @@ void EditorView::removeMonitorPaths() {
|
|||
_watcher.removePaths(files);
|
||||
}
|
||||
|
||||
void EditorView::addMonitorPath() { _watcher.addPath(m_fileName); }
|
||||
void EditorView::addMonitorPath() { _watcher.addPath(m_hex->windowFilePath()); }
|
||||
|
||||
BookMarksModel *EditorView::bookmarksModel() const { return m_bookmarks; }
|
||||
|
||||
|
@ -2144,12 +2149,12 @@ EditorView *EditorView::clone() {
|
|||
connect(ev, &EditorView::sigOnMetadata, this, &EditorView::sigOnMetadata);
|
||||
connect(ev, &EditorView::sigOnBookMark, this, &EditorView::sigOnBookMark);
|
||||
|
||||
auto doc = this->m_hex->document();
|
||||
auto doc = m_hex->document();
|
||||
|
||||
ev->m_cloneParent = this;
|
||||
ev->m_hex->setDocument(doc, ev->m_hex->cursor());
|
||||
|
||||
ev->m_fileName = this->m_fileName;
|
||||
ev->m_hex->setWindowFilePath(m_hex->windowFilePath());
|
||||
ev->setWindowTitle(this->windowTitle() + QStringLiteral(" : ") +
|
||||
QString::number(cloneIndex + 1));
|
||||
|
||||
|
@ -2234,7 +2239,7 @@ QString EditorView::fileName() const {
|
|||
if (isCloneFile()) {
|
||||
return this->cloneParent()->fileName();
|
||||
}
|
||||
return m_fileName;
|
||||
return m_hex->windowFilePath();
|
||||
}
|
||||
|
||||
bool EditorView::eventFilter(QObject *watched, QEvent *event) {
|
||||
|
@ -2247,3 +2252,5 @@ bool EditorView::eventFilter(QObject *watched, QEvent *event) {
|
|||
}
|
||||
return ads::CDockWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
EditorViewContext *EditorView::editorContext() const { return _context; }
|
||||
|
|
|
@ -217,6 +217,8 @@ public:
|
|||
|
||||
void applySettings();
|
||||
|
||||
EditorViewContext *editorContext() const;
|
||||
|
||||
private:
|
||||
inline qsizetype findAvailCloneIndex();
|
||||
|
||||
|
@ -570,7 +572,6 @@ private:
|
|||
QMenu *m_menu = nullptr;
|
||||
|
||||
QHash<QString, WingEditorViewWidget *> m_others;
|
||||
QString m_fileName;
|
||||
bool m_isNewFile = true;
|
||||
QByteArray m_md5;
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ enum class CrashCode : int {
|
|||
LanguageFile,
|
||||
PluginSetting,
|
||||
ScriptInitFailed,
|
||||
GenericCallNotSupported
|
||||
GenericCallNotSupported,
|
||||
OutofMemory
|
||||
};
|
||||
|
||||
namespace AsUserDataType {
|
||||
|
|
|
@ -465,6 +465,9 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
|
|||
swapEditor(m_curEditor, editview);
|
||||
_editorLock.unlock();
|
||||
} else {
|
||||
for (auto &menu : m_hexContextMenu) {
|
||||
menu->setProperty("__CONTEXT__", {});
|
||||
}
|
||||
m_findresult->setModel(_findEmptyResult);
|
||||
m_bookmarks->setModel(_bookMarkEmpty);
|
||||
m_metadatas->setModel(_metadataEmpty);
|
||||
|
@ -1083,10 +1086,13 @@ ads::CDockAreaWidget *
|
|||
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);
|
||||
|
||||
_hlAnim = new ConsoleHighlighAnim(m_bgScriptOutput);
|
||||
|
||||
auto a = newAction(
|
||||
ICONRES(QStringLiteral("mStr")), tr("SelectAll"),
|
||||
[this]() { m_bgScriptOutput->selectAll(); }, QKeySequence::SelectAll);
|
||||
|
@ -1116,6 +1122,13 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
|
|||
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("BgScriptOutput"),
|
||||
tr("BgScriptOutput"), m_bgScriptOutput);
|
||||
_hlAnim->setWidget(dw->tabWidget());
|
||||
|
||||
auto e = new EventFilter(QEvent::Show, dw);
|
||||
connect(e, &EventFilter::eventTriggered, this,
|
||||
[this]() { _hlAnim->stop(); });
|
||||
m_bgScriptOutput->installEventFilter(e);
|
||||
|
||||
return dock->addDockWidget(area, dw, areaw);
|
||||
}
|
||||
|
||||
|
@ -3333,7 +3346,6 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
doc->disconnect(m_aShowMetaComment);
|
||||
}
|
||||
|
||||
Q_ASSERT(cur);
|
||||
auto hexeditor = cur->hexEditor();
|
||||
auto needReload = cur->property("__RELOAD__").toBool();
|
||||
if (needReload) {
|
||||
|
@ -3434,6 +3446,10 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
m_metadatas->selectionModel()->hasSelection());
|
||||
});
|
||||
|
||||
for (auto &menu : m_hexContextMenu) {
|
||||
menu->setProperty("__CONTEXT__", quintptr(cur->editorContext()));
|
||||
}
|
||||
|
||||
_undoView->setStack(doc->undoStack());
|
||||
|
||||
m_curEditor = cur;
|
||||
|
@ -3959,6 +3975,10 @@ void MainWindow::onOutputBgScriptOutput(
|
|||
|
||||
lastInfo.first = message.type;
|
||||
lastInfo.second = qMakePair(message.row, message.col);
|
||||
|
||||
if (!m_bgScriptOutput->isVisible()) {
|
||||
_hlAnim->start();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "Qt-Advanced-Docking-System/src/DockManager.h"
|
||||
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
|
||||
#include "WingPlugin/iwingplugin.h"
|
||||
#include "class/consolehighlighanim.h"
|
||||
#include "class/recentfilemanager.h"
|
||||
#include "control/editorview.h"
|
||||
#include "control/qtableviewext.h"
|
||||
|
@ -479,6 +480,8 @@ private:
|
|||
ScriptingConsole *m_scriptConsole = nullptr;
|
||||
QPlainTextEdit *m_bgScriptOutput = nullptr;
|
||||
|
||||
ConsoleHighlighAnim *_hlAnim = nullptr;
|
||||
|
||||
bool m_isfinding = false;
|
||||
ads::CDockWidget *m_find = nullptr;
|
||||
QMenu *m_menuFind = nullptr;
|
||||
|
|
|
@ -2741,12 +2741,12 @@ ads--CDockWidgetTab[activeTab="true"]
|
|||
|
||||
ads--CDockWidgetTab QLabel
|
||||
{
|
||||
background-color: #1b1d20;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel
|
||||
ads--CDockWidgetTab[activeTab="false"]:hover
|
||||
{
|
||||
background-color: #202326;
|
||||
background-color: rgba(61, 173, 232, 0.1);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget > QSplitter{
|
||||
|
|
|
@ -2741,12 +2741,12 @@ ads--CDockWidgetTab[activeTab="true"]
|
|||
|
||||
ads--CDockWidgetTab QLabel
|
||||
{
|
||||
background-color: #d9d8d7;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
ads--CDockWidgetTab[activeTab="true"] QLabel
|
||||
ads--CDockWidgetTab[activeTab="false"]:hover
|
||||
{
|
||||
background-color: #eff0f1;
|
||||
background-color: rgba(61, 173, 232, 0.2);
|
||||
}
|
||||
|
||||
ads--CDockContainerWidget > QSplitter{
|
||||
|
|
Loading…
Reference in New Issue