diff --git a/3rdparty/QHexView/document/commands/hex/appendcommand.cpp b/3rdparty/QHexView/document/commands/hex/appendcommand.cpp index 47d2f16..e42e67a 100644 --- a/3rdparty/QHexView/document/commands/hex/appendcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/appendcommand.cpp @@ -15,6 +15,7 @@ void AppendCommand::undo() { m_doc->insertBookMarkAdjustRevert(offset, m_length); m_doc->metadata()->insertAdjustRevert(offset, m_length); m_cursor->setPos(offset, m_nibbleindex); + HexCommand::undo(); } void AppendCommand::redo() { @@ -27,4 +28,5 @@ void AppendCommand::redo() { } else { m_cursor->setPos(offset + m_length, m_nibbleindex); } + HexCommand::redo(); } diff --git a/3rdparty/QHexView/document/commands/hex/hexcommand.cpp b/3rdparty/QHexView/document/commands/hex/hexcommand.cpp index 81c4b49..884e978 100644 --- a/3rdparty/QHexView/document/commands/hex/hexcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/hexcommand.cpp @@ -4,3 +4,10 @@ HexCommand::HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex, QUndoCommand *parent) : QUndoCommand(parent), m_doc(doc), m_cursor(cursor), m_offset(0), m_length(0), m_nibbleindex(nibbleindex) {} + +void HexCommand::undo() { + Q_ASSERT(m_doc->m_bytesModFlag > 0); + m_doc->m_bytesModFlag--; +} + +void HexCommand::redo() { m_doc->m_bytesModFlag++; } diff --git a/3rdparty/QHexView/document/commands/hex/hexcommand.h b/3rdparty/QHexView/document/commands/hex/hexcommand.h index 0d78f78..a4da328 100644 --- a/3rdparty/QHexView/document/commands/hex/hexcommand.h +++ b/3rdparty/QHexView/document/commands/hex/hexcommand.h @@ -11,6 +11,9 @@ public: HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex, QUndoCommand *parent = nullptr); + void undo() override; + void redo() override; + protected: QHexDocument *m_doc; QHexCursor *m_cursor; diff --git a/3rdparty/QHexView/document/commands/hex/insertcommand.cpp b/3rdparty/QHexView/document/commands/hex/insertcommand.cpp index 3299d66..2b3d003 100644 --- a/3rdparty/QHexView/document/commands/hex/insertcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/insertcommand.cpp @@ -14,6 +14,7 @@ void InsertCommand::undo() { m_doc->insertBookMarkAdjustRevert(m_offset, m_length); m_doc->metadata()->insertAdjustRevert(m_offset, m_length); m_cursor->setPos(m_offset, m_nibbleindex); + HexCommand::undo(); } void InsertCommand::redo() { m_doc->_insert(m_offset, m_data); @@ -24,4 +25,5 @@ void InsertCommand::redo() { } else { m_cursor->setPos(m_offset + m_length, m_nibbleindex); } + HexCommand::redo(); } diff --git a/3rdparty/QHexView/document/commands/hex/removecommand.cpp b/3rdparty/QHexView/document/commands/hex/removecommand.cpp index 359950f..f09ebde 100644 --- a/3rdparty/QHexView/document/commands/hex/removecommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/removecommand.cpp @@ -22,6 +22,7 @@ void RemoveCommand::undo() { m_cursor->setPos(m_offset, 0); } } + HexCommand::undo(); } void RemoveCommand::redo() { @@ -29,4 +30,5 @@ void RemoveCommand::redo() { m_doc->_remove(m_offset, m_length); _rmbms = m_doc->removeBookMarkAdjust(m_offset, m_length); _rmMetas = m_doc->metadata()->removeAdjust(m_offset, m_length); + HexCommand::redo(); } diff --git a/3rdparty/QHexView/document/commands/hex/replacecommand.cpp b/3rdparty/QHexView/document/commands/hex/replacecommand.cpp index 0ddac78..d70fe20 100644 --- a/3rdparty/QHexView/document/commands/hex/replacecommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/replacecommand.cpp @@ -5,7 +5,6 @@ ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset, const QByteArray &data, QHexCursor *cursor, int nibbleindex, QUndoCommand *parent) : HexCommand(doc, cursor, nibbleindex, parent) { - m_offset = offset; m_data = data; m_length = data.length(); @@ -15,6 +14,7 @@ ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset, void ReplaceCommand::undo() { m_doc->_replace(m_offset, m_olddata); m_cursor->setPos(m_offset, m_nibbleindex); + HexCommand::undo(); } void ReplaceCommand::redo() { @@ -24,4 +24,5 @@ void ReplaceCommand::redo() { } else { m_cursor->setPos(m_offset + m_length, !m_nibbleindex); } + HexCommand::redo(); } diff --git a/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp b/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp index ccc178d..ebfade7 100644 --- a/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp @@ -6,6 +6,6 @@ MetaReplaceCommand::MetaReplaceCommand(QHexMetadata *hexmeta, QUndoCommand *parent) : MetaCommand(hexmeta, meta, parent), m_old(oldmeta) {} -void MetaReplaceCommand::undo() { m_hexmeta->modifyMetadata(m_meta, m_old); } +void MetaReplaceCommand::undo() { m_hexmeta->modifyMetadata(m_old, m_meta); } -void MetaReplaceCommand::redo() { m_hexmeta->modifyMetadata(m_old, m_meta); } +void MetaReplaceCommand::redo() { m_hexmeta->modifyMetadata(m_meta, m_old); } diff --git a/3rdparty/QHexView/document/qhexcursor.h b/3rdparty/QHexView/document/qhexcursor.h index f2ddece..f27579e 100644 --- a/3rdparty/QHexView/document/qhexcursor.h +++ b/3rdparty/QHexView/document/qhexcursor.h @@ -115,8 +115,6 @@ public: qsizetype currentSelectionLength() const; - bool atEnd() const; - bool isLineSelected(qsizetype line) const; bool isSelected(const QHexPosition &pos) const; bool hasSelection() const; diff --git a/3rdparty/QHexView/document/qhexdocument.cpp b/3rdparty/QHexView/document/qhexdocument.cpp index 5107d58..ea3cd91 100644 --- a/3rdparty/QHexView/document/qhexdocument.cpp +++ b/3rdparty/QHexView/document/qhexdocument.cpp @@ -205,6 +205,8 @@ void QHexDocument::removeBookMarkAdjustRevert( bool QHexDocument::isDocSaved() { return m_isSaved; } +bool QHexDocument::isUndoByteModified() { return m_bytesModFlag > 0; } + void QHexDocument::setDocSaved(bool b) { if (b) { m_undostack->setClean(); diff --git a/3rdparty/QHexView/document/qhexdocument.h b/3rdparty/QHexView/document/qhexdocument.h index 8699d64..aa38b9b 100644 --- a/3rdparty/QHexView/document/qhexdocument.h +++ b/3rdparty/QHexView/document/qhexdocument.h @@ -12,6 +12,8 @@ class QHexDocument : public QObject { Q_OBJECT + friend class HexCommand; + private: explicit QHexDocument(QHexBuffer *buffer, bool readonly = false); // modified by wingsummer @@ -79,7 +81,9 @@ public: void findAllBytes( qsizetype begin, qsizetype end, QByteArray b, QList &results, const std::function &pred = [] { return true; }); + bool isDocSaved(); + bool isUndoByteModified(); void setDocSaved(bool b = true); void setMetafgVisible(bool b); @@ -222,7 +226,10 @@ signals: private: QHexBuffer *m_buffer; QHexMetadata *m_metadata; + QUndoStack *m_undostack; + size_t m_bytesModFlag = 0; + quintptr m_baseaddress; quint8 m_areaindent; quint8 m_hexlinewidth; diff --git a/3rdparty/QHexView/document/qhexmetadata.cpp b/3rdparty/QHexView/document/qhexmetadata.cpp index 8b45223..d4e659a 100644 --- a/3rdparty/QHexView/document/qhexmetadata.cpp +++ b/3rdparty/QHexView/document/qhexmetadata.cpp @@ -272,6 +272,10 @@ void QHexMetadata::applyMetas(const QVector &metas) { for (auto &meta : metas) { m_metadata.mergeAdd(meta); } + for (auto &meta : m_metadata) { + addMetaLines(meta); + } + emit metadataChanged(); } bool QHexMetadata::hasMetadata() { return m_metadata.count() > 0; } diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts index 28813c3..cb93bae 100644 --- a/lang/zh_CN/winghex_zh_CN.ts +++ b/lang/zh_CN/winghex_zh_CN.ts @@ -851,24 +851,24 @@ MainWindow - + File 文件 - - + + View 视图 - + About 关于 - + WingHexExplorer 羽云十六进制编辑器 @@ -883,351 +883,352 @@ 选长: - + Edit 编辑 - + Script 脚本 - - - + + + Plugin 插件 - + Setting 设置 - - + + Log 日志 - + ExportFindResult 导出搜索结果 - + ClearFindResult 清空记录 - + + FindResult 搜索结果 - - - - - - - + + + + + + + Copy 复制 - - - - - - - - + + + + + + + + CopyToClipBoard 数据已拷贝到粘贴板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 数值 - - + + CheckSum 校验和 - - + + DeleteBookMark 删除书签 - - + + ClearBookMark 清空书签 - - - - + + + + BookMark 书签 - - + + DecodeText 解码字符串 - + ScriptConsole 脚本控制台 - - + + DVList 可视化列表 - - + + DVTree 可视化树数据 - - + + DVTable 可视化表格 - - + + DVText 可视化文本 - - + + Basic 基础 - + New 新建 - + OpenF 打开文件 - + OpenFR 打开局部文件 - + OpenWorkSpace 打开工作区 - + OpenD 打开驱动器 - + RecentFiles 最近打开 - + Reload 重新加载 - - + + Save 保存 - + SaveAs 另存为 - + Export 导出 - + SaveSel 保存选区字节 - - - - + + + + General 基本 - + Undo 撤销 - + Redo 恢复 - + Cut 剪切 - + Paste 粘贴 - + Delete 删除 - + Clone 克隆 - + Lookup 查询 - + Find 查找 - + Goto 跳转 - - + + Encoding 编码 - + FileInfo 文件信息 - - + + Hex 十六进制 - + CutHex 剪切(十六进制) - + CopyHex 复制(十六进制) - + PasteHex 粘贴(十六进制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 标注 - + DeleteMetadata 删除标注 - + ClearMetadata 清空标注 - + MetaDataEdit 编辑标注 - + DeleteMetaData 删除标注 - + ClearMetaData 清空标注 - + Display 显示 - + ViewText 文本预览 - + Scale 缩放 @@ -1247,657 +1248,680 @@ 启动 Dock 服务 - + LaunchingLog 启动日志系统 - + SetupPluginSystem 启动插件系统 - + LoadingPlg: 加载插件中: - + SetupConsole 启动脚本控制台 - + SetupScriptManager 启动脚本管理器 - + SetupScriptService 启动脚本服务 - + SetupScriptEditor 构建脚本编辑器 - + SetupSetDialog 构建设置窗体 - + SetupPlgWidgets 启动插件组件 - + SetupDockingLayout 恢复 Dock 布局 - + SetupWaiting 启动即将完成 - + SetupFinished 启动完毕 - + NoExtension 无扩展 - - - - + + + + ExportResult 导出结果 - - - + + + NothingToSave 没有保存的数据模型 - - - - + + + + ClearResult 清空结果 - + OpenExt 打开 - 拓展 - + ResetScale 重置缩放 - + ShowMetafg 标注前景色 - + ShowMetabg 标注背景色 - + ShowMetaComment 批注 - + MetaShowAll 显示所有标注 - + MetaHideAll 隐藏所有标注 - + FileStatus 文件状态 - - + + InfoSave 是否保存 - - + + ReadOnly 可读写 - - + + SetLocked 启用/禁用锁定编辑 - + ErrUnLock 锁定编辑失败 - - + + SetOver 启用/禁用改变大小 - + ErrUnOver 锁定文件大小失败 - + Window 窗体 - + Editor 编辑器 - + Tools 工具 - + HexEditorLayout 编辑器布局 - + SetBaseAddr 设置基址 - + addressBase 基址 - + inputAddressBase 请输入基址 - + WarnBigBaseAddress 基址过大,你得到的地址将会不正确! - + ErrBaseAddress 非法基址输入 - + SetColInfo 显示/隐藏地址栏 - + SetHeaderInfo 显示/隐藏表头 - + SetAsciiString 显示/隐藏解码字符串 - + Layout 布局 - + Fullscreen 全屏 - + Default 默认 - + RestoreLayout 恢复布局 - - + + SaveLayout 保存布局 - + ExportLog 导出日志 - + ClearLog 清空日志 - + ScriptEditor 脚本编辑器 - + Scripts 脚本仓库 - + PluginFunctions 插件功能 - + ScriptSetting 脚本设置 - + PluginSettings 插件设置 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + CheckUpdate 检查更新 - + Wiki 网页 Wiki - + AboutQT 关于 QT - + SetPageIDEmptyTryUseName 设置页 ID 为空,尝试使用名称作为 ID - + SetPageDupNameIgnored 设置页重复的 ID 名称,已忽略加载 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重复 ID (%2),该 ID 已被插件 %3 注册 - - + + ChooseFile 选择文件 - - - - - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + Error 错误 - - - - + + + + FileNotExist 文件不存在! - - - - - - - - - - + + + + + + + + + + FilePermission 因文件权限无法继续! - + ProjectFile (*.wingpro) 项目文件 (*.wingpro) - + Root Required! 需要管理员权限继续操作! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - - - - - - - + + + + + + + ChooseSaveFile 请选择保存文件路径: - + NoMoreClone 克隆已到上限,无法继续操作! - + FindFininishBusy 查找任务繁忙,请勿重复查找! - + MayTooMuchFindResult 搜索数量已到达上限,结果可能不全,建议请按区段搜索。 - + SaveLayoutSuccess 保存布局成功 - + SaveLayoutError 保存布局失败 - + ConfirmSave 正在关闭未保存的文件或工作区,你确定保存吗? - + Column %1 列 %1 - + ConfirmAPPSave 你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗? - - - - - - + + + + + + SaveSuccessfully 保存成功! - + SaveWSError 保存工作区错误! - - - + + + Warn 警告 - + ScriptObjShow 脚本对象 - - - + + + SourceChanged 局部打开原始文件更改! - - + + SaveSourceFileError 由于原文件更改,保存文件失败! - + SaveUnSuccessfully 保存失败! - + ChooseExportFile 请选择导出文件路径: - + ExportSuccessfully 导出成功! - + ExportSourceFileError 由于原文件更改,导出文件失败! - + ExportUnSuccessfully 导出失败! - + SaveSelSuccess 保存选区字节成功! - + SaveSelError 保存选区字节失败,因文件不具有可写权限! - - + + CutToClipBoard 数据已剪切到粘贴板! - - + + UnCutToClipBoard 由于保持大小限制,数据剪切到粘贴板失败! - - + + UnCopyToClipBoard 由于保持大小限制,数据剪切到复制板失败! - + + Finding... + + + + FindFininish 查找结果完毕! - + PleaseInputFill 请输入填充字节值 - + FillInputError 填充字节输入错误 - - + + InputComment 请输入批注: - - - + + + NoSelection 没有选区,无法继续的操作! - + NoMetaData 无可编辑标记 - - + + EmptyFindResult 没有可导出的搜索结果! - + SaveFindResult 导出搜索结果成功! - + SaveFindResultError 导出结果失败! - + TooManyBytesDecode 超出解码字节限制…… - + PleaseInput 请输入 - + ExportLogError 导出日志失败! - + ExportLogSuccess 导出日志成功,路径: - + ClearLogSuccess 清空日志成功! - + BadNetwork 无法与远程服务器的更新检查建立连接,请检查网络。 - + NewestVersion 当前软件为最新版本 - - + + OlderVersion 你使用的软件为老版本,建议到 Github 和 Gitee 的仓库发行版下载更新。 - + CheckingUpdate 检查更新中…… - + Too much opened files 打开的文件过多,无法继续操作! - + + FilePermissionSure2Quit + + + + + UnknownErrorSure2Quit + + + + + WorkSpaceUnSavedSure2Quit + + + + CopyLimit 拷贝字节超出限制 - + ErrOpenFileBelow 打开文件出现错误(由于权限不足),如下为打开错误的文件: @@ -2080,12 +2104,12 @@ 插件: - + DevExtInfo 设备插件信息 - + DevExt: 设备插件: @@ -2096,64 +2120,64 @@ - + ID ID - + Name 名称 - + License 协议 - + Author 作者 - + Vendor 厂家 - - + + Version 版本 - - + + Comment 说明 - - + + URL 网址 - + pluginDependencies: 插件依赖 - + PUID: 插件唯一标志符: - + Version: 版本: diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts index 823fa3f..f524f2b 100644 --- a/lang/zh_TW/winghex_zh_TW.ts +++ b/lang/zh_TW/winghex_zh_TW.ts @@ -851,24 +851,24 @@ MainWindow - + File - - + + View 視圖 - + About 關於 - + WingHexExplorer 羽雲十六進制編輯器 @@ -883,351 +883,352 @@ 選長: - + Edit 編輯 - + Script 腳本 - - - + + + Plugin 插件 - + Setting 設置 - - + + Log 日誌 - + ExportFindResult 導出搜索結果 - + ClearFindResult 清空記錄 - + + FindResult 搜索結果 - - - - - - - + + + + + + + Copy 複製 - - - - - - - - + + + + + + + + CopyToClipBoard 數據已拷貝到粘貼板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 數值 - - + + CheckSum 校驗和 - - + + DeleteBookMark 刪除書簽 - - + + ClearBookMark 清空書簽 - - - - + + + + BookMark 書簽 - - + + DecodeText 解碼字串 - + ScriptConsole 腳本控制臺 - - + + DVList 可視化列表 - - + + DVTree 可視化樹數據 - - + + DVTable 可視化表格 - - + + DVText 可視化文本 - - + + Basic 基礎 - + New 新建 - + OpenF 打開檔 - + OpenFR 打開局部檔 - + OpenWorkSpace 打開工作區 - + OpenD 打開驅動器 - + RecentFiles 最近打開 - + Reload 重新加載 - - + + Save 保存 - + SaveAs 另存為 - + Export 導出 - + SaveSel 保存選區位元組 - - - - + + + + General 基本 - + Undo 撤銷 - + Redo 恢復 - + Cut 剪切 - + Paste 粘貼 - + Delete 刪除 - + Clone 克隆 - + Lookup 查詢 - + Find 查找 - + Goto 跳轉 - - + + Encoding 編碼 - + FileInfo 檔資訊 - - + + Hex 十六進制 - + CutHex 剪切(十六進制) - + CopyHex 複製(十六進制) - + PasteHex 粘貼(十六進制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 標注 - + DeleteMetadata 刪除標注 - + ClearMetadata 清空標注 - + MetaDataEdit 編輯標注 - + DeleteMetaData 刪除標注 - + ClearMetaData 清空標注 - + Display 顯示 - + ViewText 文本預覽 - + Scale 縮放 @@ -1247,657 +1248,680 @@ 啟動 Dock 服務 - + LaunchingLog 啟動日誌系統 - + SetupPluginSystem 啟動插件系統 - + LoadingPlg: 加載插件中: - + SetupConsole 啟動腳本控制臺 - + SetupScriptManager 啟動腳本管理器 - + SetupScriptService 啟動腳本服務 - + SetupScriptEditor 構建腳本編輯器 - + SetupSetDialog 構建設置窗體 - + SetupPlgWidgets 啟動插件組件 - + SetupDockingLayout 恢復 Dock 佈局 - + SetupWaiting 啟動即將完成 - + SetupFinished 啟動完畢 - + NoExtension 無擴展 - - - - + + + + ExportResult 導出結果 - - - + + + NothingToSave 沒有保存的數據模型 - - - - + + + + ClearResult 清空結果 - + OpenExt 打開 - 拓展 - + ResetScale 重置縮放 - + ShowMetafg 標注前景色 - + ShowMetabg 標注背景色 - + ShowMetaComment 批註 - + MetaShowAll 顯示所有標注 - + MetaHideAll 隱藏所有標注 - + FileStatus 檔狀態 - - + + InfoSave 是否保存 - - + + ReadOnly 可讀寫 - - + + SetLocked 啟用/禁用鎖定編輯 - + ErrUnLock 鎖定編輯失敗 - - + + SetOver 啟用/禁用改變大小 - + ErrUnOver 鎖定檔大小失敗 - + Window 窗體 - + Editor 編輯器 - + Tools 工具 - + HexEditorLayout 編輯器佈局 - + SetBaseAddr 設置基址 - + addressBase 基址 - + inputAddressBase 請輸入基址 - + WarnBigBaseAddress 基址過大,你得到的地址將會不正確! - + ErrBaseAddress 非法基址輸入 - + SetColInfo 顯示/隱藏地址欄 - + SetHeaderInfo 顯示/隱藏表頭 - + SetAsciiString 顯示/隱藏解碼字串 - + Layout 佈局 - + Fullscreen 全屏 - + Default 默認 - + RestoreLayout 恢復佈局 - - + + SaveLayout 保存佈局 - + ExportLog 導出日誌 - + ClearLog 清空日誌 - + ScriptEditor 腳本編輯器 - + Scripts 腳本倉庫 - + PluginFunctions 插件功能 - + ScriptSetting 腳本設置 - + PluginSettings 插件設置 - + Info 資訊 - + Software 軟體 - + Sponsor 贊助 - + CheckUpdate 檢查更新 - + Wiki 網頁 Wiki - + AboutQT 關於 QT - + SetPageIDEmptyTryUseName 設置頁 ID 為空,嘗試使用名稱作為 ID - + SetPageDupNameIgnored 設置頁重複的 ID 名稱,已忽略加載 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重複 ID (%2),該 ID 已被插件 %3 註冊 - - + + ChooseFile 選擇檔 - - - - - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + Error 錯誤 - - - - + + + + FileNotExist 檔不存在! - - - - - - - - - - + + + + + + + + + + FilePermission 因檔許可權無法繼續! - + ProjectFile (*.wingpro) 專案檔 (*.wingpro) - + Root Required! 需要管理員許可權繼續操作! - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - - - - - - - + + + + + + + ChooseSaveFile 請選擇保存檔路徑: - + NoMoreClone 克隆已到上限,無法繼續操作! - + FindFininishBusy 查找任務繁忙,請勿重複查找! - + MayTooMuchFindResult 搜索數量已到達上限,結果可能不全,建議請按區段搜索。 - + SaveLayoutSuccess 保存佈局成功 - + SaveLayoutError 保存佈局失敗 - + ConfirmSave 正在關閉未保存的檔或工作區,你確定保存嗎? - + Column %1 列 %1 - + ConfirmAPPSave 你嘗試關閉程式,但仍存在未保存的檔或工作區,你確定保存這些更改嗎? - - - - - - + + + + + + SaveSuccessfully 保存成功! - + SaveWSError 保存工作區錯誤! - - - + + + Warn 警告 - + ScriptObjShow 腳本對象 - - - + + + SourceChanged 局部打開原始檔更改! - - + + SaveSourceFileError 由於原文件更改,保存檔失敗! - + SaveUnSuccessfully 保存失敗! - + ChooseExportFile 請選擇導出檔路徑: - + ExportSuccessfully 導出成功! - + ExportSourceFileError 由於原文件更改,導出檔失敗! - + ExportUnSuccessfully 導出失敗! - + SaveSelSuccess 保存選區位元組成功! - + SaveSelError 保存選區位元組失敗,因檔不具有可寫許可權! - - + + CutToClipBoard 數據已剪切到粘貼板! - - + + UnCutToClipBoard 由於保持大小限制,數據剪切到粘貼板失敗! - - + + UnCopyToClipBoard 由於保持大小限制,數據剪切到複製板失敗! - + + Finding... + + + + FindFininish 查找結果完畢! - + PleaseInputFill 請輸入填充位元組值 - + FillInputError 填充位元組輸入錯誤 - - + + InputComment 請輸入批註: - - - + + + NoSelection 沒有選區,無法繼續的操作! - + NoMetaData 無可編輯標記 - - + + EmptyFindResult 沒有可導出的搜索結果! - + SaveFindResult 導出搜索結果成功! - + SaveFindResultError 導出結果失敗! - + TooManyBytesDecode 超出解碼位元組限制…… - + PleaseInput 請輸入 - + ExportLogError 導出日誌失敗! - + ExportLogSuccess 導出日誌成功,路徑: - + ClearLogSuccess 清空日誌成功! - + BadNetwork 無法與遠程伺服器的更新檢查建立連接,請檢查網路。 - + NewestVersion 當前軟體為最新版本 - - + + OlderVersion 你使用的軟體為老版本,建議到 Github 和 Gitee 的倉庫發行版下載更新。 - + CheckingUpdate 檢查更新中…… - + Too much opened files 打開的檔過多,無法繼續操作! - + + FilePermissionSure2Quit + + + + + UnknownErrorSure2Quit + + + + + WorkSpaceUnSavedSure2Quit + + + + CopyLimit 拷貝位元組超出限制 - + ErrOpenFileBelow 打開檔出現錯誤(由於許可權不足),如下為打開錯誤的檔: @@ -2080,12 +2104,12 @@ 插件: - + DevExtInfo 設備插件資訊 - + DevExt: 設備插件: @@ -2096,64 +2120,64 @@ - + ID ID - + Name 名稱 - + License 協議 - + Author 作者 - + Vendor 廠家 - - + + Version 版本 - - + + Comment 說明 - - + + URL 網址 - + pluginDependencies: 插件依賴 - + PUID: 插件唯一標誌符: - + Version: 版本: diff --git a/src/class/WingAngelAPI.json b/src/class/WingAngelAPI.json index 806e689..186ab0f 100644 --- a/src/class/WingAngelAPI.json +++ b/src/class/WingAngelAPI.json @@ -2,8 +2,9 @@ "Id": "WingAngelAPI", "Name": "WingAngelAPI", "Author": "wingsummer", - "Version": "0.0.1", + "Version": "2.1.0", "Vendor": "WingCloudStudio", "Copyright": "wingsummer", - "License": "AGPL-3.0" + "License": "AGPL-3.0", + "Url": "https://github.com/Wing-summer/WingHexExplorer2" } diff --git a/src/class/workspacemanager.cpp b/src/class/workspacemanager.cpp index cd05f45..44cd628 100644 --- a/src/class/workspacemanager.cpp +++ b/src/class/workspacemanager.cpp @@ -85,25 +85,26 @@ bool WorkSpaceManager::loadWorkSpace(const QString &filename, QString &file, auto nend = end.toString().toLongLong(&b); if (!b || nend >= maxbytes || nend < 0) continue; - auto nf = fgcolor.toString().toUInt(&b, 16); - if (!b) - continue; - auto nb = bgcolor.toString().toUInt(&b, 16); - if (!b) - continue; - auto fcolor = QColor::fromRgba(nf); - auto bcolor = QColor::fromRgba(nb); + + static auto NO_COLOR = QStringLiteral("-"); + + QColor fcolor, bcolor; + auto fgn = fgcolor.toString(); + if (fgn != NO_COLOR) { + fcolor = QColor(fgn); + } + + auto bgn = bgcolor.toString(); + if (bgn != NO_COLOR) { + bcolor = QColor(bgn); + } QHexMetadataItem metaitem; metaitem.begin = nbegin; metaitem.end = nend; metaitem.comment = comment.toString(); - metaitem.foreground = fcolor.alpha() > 0 - ? fcolor.toHsv() - : fcolor; - metaitem.background = bcolor.alpha() > 0 - ? fcolor.toHsv() - : bcolor; + metaitem.foreground = fcolor; + metaitem.background = bcolor; metas.append(metaitem); } } @@ -164,6 +165,14 @@ bool WorkSpaceManager::loadWorkSpace(const QString &filename, QString &file, return false; } +QString WorkSpaceManager::getColorString(const QColor &color) { + static auto NO_COLOR = QStringLiteral("-"); + if (color.isValid()) { + return color.name(); + } + return NO_COLOR; +} + bool WorkSpaceManager::saveWorkSpace( const QString &filename, const QString &file, const QMap &bookmarklist, @@ -190,8 +199,8 @@ bool WorkSpaceManager::saveWorkSpace( obj.insert("begin", QString::number(meta.begin)); obj.insert("end", QString::number(meta.end)); obj.insert("comment", meta.comment); - obj.insert("fgcolor", QString::number(meta.foreground.rgba(), 16)); - obj.insert("bgcolor", QString::number(meta.background.rgba(), 16)); + obj.insert("fgcolor", getColorString(meta.foreground)); + obj.insert("bgcolor", getColorString(meta.background)); metas.append(obj); } jobj.insert("metas", metas); diff --git a/src/class/workspacemanager.h b/src/class/workspacemanager.h index b036109..37638d9 100644 --- a/src/class/workspacemanager.h +++ b/src/class/workspacemanager.h @@ -47,6 +47,9 @@ public: QMap &bookmarks, QVector &metas, WorkSpaceInfo &infos); + +private: + QString static getColorString(const QColor &color); }; #endif // WORKSPACEMANAGER_H diff --git a/src/control/editorview.cpp b/src/control/editorview.cpp index d6e6d7d..eaa4b3e 100644 --- a/src/control/editorview.cpp +++ b/src/control/editorview.cpp @@ -465,24 +465,6 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path, } } - QFile file(fileName); - - switch (m_docType) { - case DocumentType::RegionFile: { - if (!ignoreMd5 && Utilities::getMd5(m_fileName) != m_md5) { - return ErrFile::SourceFileChanged; - } - if (!file.open(QFile::ReadWrite)) { - return ErrFile::Permission; - } - } break; - default: { - if (!file.open(QFile::WriteOnly)) { - return ErrFile::Permission; - } - } break; - } - if (workSpaceAttr == SaveWorkSpaceAttr::ForceWorkSpace || (workSpaceAttr == SaveWorkSpaceAttr::AutoWorkSpace && (m_isWorkSpace || hasMeta()))) { @@ -499,18 +481,43 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path, } } - if (doc->saveTo(&file, true)) { - file.close(); + if (doc->isUndoByteModified()) { + QFile file(fileName); - if (!isExport) { - m_fileName = QFileInfo(fileName).absoluteFilePath(); - doc->setDocSaved(); + switch (m_docType) { + case DocumentType::RegionFile: { + if (!ignoreMd5 && Utilities::getMd5(m_fileName) != m_md5) { + return ErrFile::SourceFileChanged; + } + if (!file.open(QFile::ReadWrite)) { + return ErrFile::Permission; + } + } break; + default: { + if (!file.open(QFile::WriteOnly)) { + return ErrFile::Permission; + } + } break; } - return ErrFile::Success; + if (doc->saveTo(&file, true)) { + file.close(); + + if (!isExport) { + m_fileName = QFileInfo(fileName).absoluteFilePath(); + doc->setDocSaved(); + } + + return ErrFile::Success; + } + + return ErrFile::Permission; + + } else { + doc->setDocSaved(); } - return ErrFile::Permission; + return ErrFile::Success; } ErrFile EditorView::reload() { diff --git a/src/control/qlistviewext.cpp b/src/control/qlistviewext.cpp index 3c62195..8c3e7b1 100644 --- a/src/control/qlistviewext.cpp +++ b/src/control/qlistviewext.cpp @@ -49,4 +49,6 @@ void QListViewExt::setModel(QAbstractItemModel *model) { vbar->blockSignals(false); QListView::setModel(model); + + emit modelChanged(); } diff --git a/src/control/qlistviewext.h b/src/control/qlistviewext.h index bfdd306..7c556b9 100644 --- a/src/control/qlistviewext.h +++ b/src/control/qlistviewext.h @@ -26,6 +26,9 @@ public: explicit QListViewExt(QWidget *parent = nullptr); void setModel(QAbstractItemModel *model) override; + +signals: + void modelChanged(); }; #endif // QLISTVIEWEXT_H diff --git a/src/control/qtableviewext.cpp b/src/control/qtableviewext.cpp index 3212f71..55a2407 100644 --- a/src/control/qtableviewext.cpp +++ b/src/control/qtableviewext.cpp @@ -49,4 +49,6 @@ void QTableViewExt::setModel(QAbstractItemModel *model) { vbar->blockSignals(false); QTableView::setModel(model); + + emit modelChanged(); } diff --git a/src/control/qtableviewext.h b/src/control/qtableviewext.h index 69ef466..87cdf30 100644 --- a/src/control/qtableviewext.h +++ b/src/control/qtableviewext.h @@ -26,6 +26,9 @@ public: explicit QTableViewExt(QWidget *parent = nullptr); void setModel(QAbstractItemModel *model) override; + +signals: + void modelChanged(); }; #endif // QTABLEVIEWEXT_H diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index 8f9d296..faee49c 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -127,6 +127,14 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() { m_status->addWidget(l); m_status->addWidget(m_lblsellen); + _status = new QLabel(m_status); + m_status->addPermanentWidget(_status); + + auto separator = new QFrame(m_status); + separator->setFrameShape(QFrame::VLine); + separator->setFrameShadow(QFrame::Sunken); + m_status->addPermanentWidget(separator); + auto disableStyle = QStringLiteral("border:none;background:transparent;"); @@ -547,6 +555,14 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock, m_findresult->setContextMenuPolicy( Qt::ContextMenuPolicy::CustomContextMenu); + auto se = [=]() { + auto model = qobject_cast(m_findresult->model()); + if (model) { + m_find->setWindowTitle(tr("FindResult") + QStringLiteral(" (") + + model->encoding() + QStringLiteral(")")); + } + }; + auto menu = new QMenu(tr("Encoding"), this); menu->setIcon(ICONRES(QStringLiteral("encoding"))); auto aGroup = new QActionGroup(this); @@ -556,6 +572,7 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock, auto model = qobject_cast(m_findresult->model()); if (model) { model->setEncoding(l); + se(); } }); aGroup->addAction(a); @@ -620,8 +637,10 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock, }); auto dw = buildDockWidget(dock, QStringLiteral("FindResult"), - tr("FindResult"), m_findresult); + tr("FindResult") + QStringLiteral(" (ASCII)"), + m_findresult); m_find = dw; + connect(m_findresult, &QTableViewExt::modelChanged, this, se); return dock->addDockWidget(area, dw, areaw); } @@ -857,6 +876,20 @@ MainWindow::buildUpDecodingStrShowDock(ads::CDockManager *dock, auto dw = buildDockWidget(dock, QStringLiteral("DecodeText"), tr("DecodeText") + QStringLiteral(" (ASCII)"), m_txtDecode); + + auto menu = m_txtDecode->createStandardContextMenu(); + menu->addSeparator(); + auto a = new QAction(tr("Encoding"), this); + a->setIcon(ICONRES(QStringLiteral("encoding"))); + connect(a, &QAction::triggered, this, &MainWindow::on_encoding); + menu->addAction(a); + + m_txtDecode->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_txtDecode, &QTextBrowser::customContextMenuRequested, this, + [=](const QPoint &pos) { + menu->popup(m_txtDecode->viewport()->mapToGlobal(pos)); + }); + connect(m_txtDecode, &QTextBrowser::windowTitleChanged, dw, &QDockWidget::setWindowTitle); return dock->addDockWidget(area, dw, areaw); @@ -1332,10 +1365,6 @@ RibbonTabContent *MainWindow::buildEditPage(RibbonTabContent *tab) { pannel, QStringLiteral("jmp"), tr("Goto"), &MainWindow::on_gotoline, shortcuts.keySequence(QKeySequences::Key::GOTO)); - addPannelAction(pannel, QStringLiteral("encoding"), tr("Encoding"), - &MainWindow::on_encoding, - shortcuts.keySequence(QKeySequences::Key::ENCODING)); - m_editStateWidgets << addPannelAction(pannel, QStringLiteral("sum"), tr("CheckSum"), &MainWindow::on_checksum); @@ -1873,6 +1902,8 @@ void MainWindow::installPluginEditorWidgets() { m_editorViewWidgets.clear(); } +void MainWindow::showStatus(const QString &status) { _status->setText(status); } + EditorView *MainWindow::newfileGUI() { if (!newOpenFileSafeCheck()) { return nullptr; @@ -2263,6 +2294,7 @@ void MainWindow::on_findfile() { ExecAsync( [this, r]() -> EditorView::FindError { + this->showStatus(tr("Finding...")); return currentEditor()->find(r); }, [this](EditorView::FindError err) { @@ -2287,6 +2319,8 @@ void MainWindow::on_findfile() { m_findEncoding.value(result->encoding())->setChecked(true); } m_find->raise(); + + this->showStatus({}); }); } } @@ -3077,7 +3111,7 @@ bool MainWindow::newOpenFileSafeCheck() { return true; } -void MainWindow::registerEditorView(EditorView *editor) { +void MainWindow::registerEditorView(EditorView *editor, const QString &ws) { for (auto &w : m_editorViewWidgetsBuffer) { editor->registerView(w->id(), w->create(editor)); } @@ -3090,7 +3124,7 @@ void MainWindow::registerEditorView(EditorView *editor) { editor->setFontSize(set.editorfontSize()); connectEditorView(editor); - m_views.insert(editor, {}); + m_views.insert(editor, ws); auto ev = m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS); auto menu = ev->menu(); Q_ASSERT(menu); @@ -3155,7 +3189,7 @@ void MainWindow::connectEditorView(EditorView *editor) { o.foreground = m.foreGroundColor(); o.background = m.backGroundColor(); o.comment = m.comment(); - mi->ModifyMetadata(meta, o); + mi->ModifyMetadata(o, meta); } } else { Toast::toast(this, NAMEICONRES(QStringLiteral("metadata")), @@ -3178,8 +3212,47 @@ void MainWindow::connectEditorView(EditorView *editor) { if (ret == QMessageBox::Cancel) { return; } else if (ret == QMessageBox::Yes) { - if (saveEditor(editor, {}, false) == ErrFile::Success) { + auto ret = saveEditor(editor, {}, false); + switch (ret) { + case WingHex::Success: + // ok, no need to report closeEditor(editor, m_isOnClosing); + break; + case WingHex::Permission: { + auto btn = WingMessageBox::critical( + this, tr("Error"), tr("FilePermissionSure2Quit"), + QMessageBox::Yes | QMessageBox::No); + if (btn == QMessageBox::Yes) { + closeEditor(editor, true); + } + } break; + case WingHex::Error: + case WingHex::UnSaved: + case WingHex::NotExist: + case WingHex::AlreadyOpened: + case WingHex::IsNewFile: + case WingHex::IsDirver: + case WingHex::SourceFileChanged: + case WingHex::ClonedFile: + case WingHex::InvalidFormat: + case WingHex::TooManyOpenedFile: + case WingHex::NotAllowedInNoneGUIThread: { + // unknown error + auto btn = WingMessageBox::critical( + this, tr("Error"), tr("UnknownErrorSure2Quit"), + QMessageBox::Yes | QMessageBox::No); + if (btn == QMessageBox::Yes) { + closeEditor(editor, true); + } + } break; + case WingHex::WorkSpaceUnSaved: { + auto btn = WingMessageBox::critical( + this, tr("Error"), tr("WorkSpaceUnSavedSure2Quit"), + QMessageBox::Yes | QMessageBox::No); + if (btn == QMessageBox::Yes) { + closeEditor(editor, true); + } + } break; } } else { closeEditor(editor, true); @@ -3423,8 +3496,7 @@ ErrFile MainWindow::openWorkSpace(const QString &file, EditorView **editor) { return res; } - m_views.insert(ev, file); - registerEditorView(ev); + registerEditorView(ev, file); if (editor) { *editor = ev; } diff --git a/src/dialog/mainwindow.h b/src/dialog/mainwindow.h index 5524f96..dcdfe04 100644 --- a/src/dialog/mainwindow.h +++ b/src/dialog/mainwindow.h @@ -138,6 +138,8 @@ private: void buildUpSettingDialog(); void installPluginEditorWidgets(); + void showStatus(const QString &status); + private: EditorView *newfileGUI(); @@ -238,7 +240,7 @@ private: EditorView *findEditorView(const QString &filename); bool newOpenFileSafeCheck(); - void registerEditorView(EditorView *editor); + void registerEditorView(EditorView *editor, const QString &ws = {}); void connectEditorView(EditorView *editor); void swapEditor(EditorView *old, EditorView *cur); @@ -497,6 +499,7 @@ private: private: Ribbon *m_ribbon = nullptr; ads::CDockManager *m_dock = nullptr; + QLabel *_status = nullptr; QString m_encoding; diff --git a/src/dialog/metadialog.cpp b/src/dialog/metadialog.cpp index 3cd35a3..6476588 100644 --- a/src/dialog/metadialog.cpp +++ b/src/dialog/metadialog.cpp @@ -122,14 +122,14 @@ QColor MetaDialog::foreGroundColor() { if (cforeground->isChecked()) return _foreground; else - return QColor(qRgba(0, 0, 0, 0)); + return QColor(); } QColor MetaDialog::backGroundColor() { if (cbackground->isChecked()) return _background; else - return QColor::fromRgba(qRgba(0, 0, 0, 0)); + return QColor(); } void MetaDialog::setComment(QString comment) { diff --git a/src/settings/pluginsettingdialog.cpp b/src/settings/pluginsettingdialog.cpp index a3c7e90..a106d4a 100644 --- a/src/settings/pluginsettingdialog.cpp +++ b/src/settings/pluginsettingdialog.cpp @@ -112,14 +112,18 @@ void PluginSettingDialog::on_devlist_currentRowChanged(int currentRow) { auto info = plgsys.getPluginInfo(plg); ui->txtd->clear(); - ui->txtd->append(tr("ID") + " : " + info.id); - ui->txtd->append(tr("Name") + " : " + plg->pluginName()); - ui->txtd->append(tr("License") + " : " + info.license); - ui->txtd->append(tr("Author") + " : " + info.author); - ui->txtd->append(tr("Vendor") + " : " + info.vendor); - ui->txtd->append(tr("Version") + " : " + info.version.toString()); - ui->txtd->append(tr("Comment") + " : " + plg->pluginComment()); - ui->txtd->append(tr("URL") + " : " + info.url); + ui->txtd->append(getWrappedText(tr("ID") + " : " + info.id)); + ui->txtd->append(getWrappedText(tr("Name") + " : " + plg->pluginName())); + ui->txtd->append(getWrappedText(tr("License") + " : " + info.license)); + ui->txtd->append(getWrappedText(tr("Author") + " : " + info.author)); + ui->txtd->append(getWrappedText(tr("Vendor") + " : " + info.vendor)); + ui->txtd->append( + getWrappedText(tr("Version") + " : " + info.version.toString())); + ui->txtd->append( + getWrappedText(tr("Comment") + " : " + plg->pluginComment())); + ui->txtd->append(getWrappedText( + tr("URL") + " : " + QStringLiteral("") + info.url + QStringLiteral(""))); } void PluginSettingDialog::on_plglist_currentRowChanged(int currentRow) { @@ -132,20 +136,30 @@ void PluginSettingDialog::on_plglist_currentRowChanged(int currentRow) { auto info = plgsys.getPluginInfo(plg); ui->txtc->clear(); - ui->txtc->append(tr("ID") + " : " + info.id); - ui->txtc->append(tr("Name") + " : " + plg->pluginName()); - ui->txtc->append(tr("License") + " : " + info.license); - ui->txtc->append(tr("Author") + " : " + info.author); - ui->txtc->append(tr("Vendor") + " : " + info.vendor); - ui->txtc->append(tr("Version") + " : " + info.version.toString()); - ui->txtc->append(tr("Comment") + " : " + plg->pluginComment()); + + ui->txtc->append(getWrappedText(tr("ID") + " : " + info.id)); + ui->txtc->append(getWrappedText(tr("Name") + " : " + plg->pluginName())); + ui->txtc->append(getWrappedText(tr("License") + " : " + info.license)); + ui->txtc->append(getWrappedText(tr("Author") + " : " + info.author)); + ui->txtc->append(getWrappedText(tr("Vendor") + " : " + info.vendor)); + ui->txtc->append( + getWrappedText(tr("Version") + " : " + info.version.toString())); + ui->txtc->append( + getWrappedText(tr("Comment") + " : " + plg->pluginComment())); if (!info.dependencies.isEmpty()) { - ui->txtc->append(tr("pluginDependencies:")); + ui->txtc->append(getWrappedText(tr("pluginDependencies:"))); for (auto &d : info.dependencies) { - ui->txtc->append(QString(4, ' ') + tr("PUID:") + d.puid); - ui->txtc->append(QString(4, ' ') + tr("Version:") + - d.version.toString()); + ui->txtc->append( + getWrappedText(QString(4, ' ') + tr("PUID:") + d.puid)); + ui->txtc->append(getWrappedText(QString(4, ' ') + tr("Version:") + + d.version.toString())); } } - ui->txtc->append(tr("URL") + " : " + info.url); + ui->txtc->append(getWrappedText( + tr("URL") + " : " + QStringLiteral("") + info.url + QStringLiteral(" "))); +} + +QString PluginSettingDialog::getWrappedText(const QString &str) { + return QStringLiteral("") + str + QStringLiteral(""); } diff --git a/src/settings/pluginsettingdialog.h b/src/settings/pluginsettingdialog.h index b25aeeb..59d36d6 100644 --- a/src/settings/pluginsettingdialog.h +++ b/src/settings/pluginsettingdialog.h @@ -51,6 +51,9 @@ public: private slots: void on_devlist_currentRowChanged(int currentRow); void on_plglist_currentRowChanged(int currentRow); + +private: + QString getWrappedText(const QString &str); }; #endif // PLUGINSETTINGDIALOG_H diff --git a/src/settings/pluginsettingdialog.ui b/src/settings/pluginsettingdialog.ui index 1f7eb6b..9f3bbe1 100644 --- a/src/settings/pluginsettingdialog.ui +++ b/src/settings/pluginsettingdialog.ui @@ -118,7 +118,11 @@ - + + + true + + @@ -154,7 +158,11 @@ - + + + true + +