Compare commits

...

65 Commits

Author SHA1 Message Date
WerWolv
54b31b8a55 build: Bumped version to 1.19.3 2022-07-26 16:13:07 +02:00
WerWolv
93aa1247df fix: Switching page when jumping to selection not working 2022-07-26 15:01:21 +02:00
WerWolv
fb4c21b97a build: Fix weird macOS build errors (#591)
* cleanup

* Remove prints
2022-07-26 14:59:08 +02:00
WerWolv
d356993e33 fix: Various search issues 2022-07-26 13:28:21 +02:00
WerWolv
cf017540e2 ui: Fixed rendering of advanced decoding highlighting with multi-byte visualizers 2022-07-25 23:46:32 +02:00
WerWolv
c776bb6c03 ui: Fixed hex editor highlighting with multi-byte visualizers 2022-07-25 15:13:26 +02:00
Polshakov Dmitry
e7399d223d fix: Bitfields not being displayed correctly in Pattern Data view (#580)
Co-authored-by: Dmitry Polshakov <dmitry.polshakov@dsr-corporation.com>
2022-07-25 12:09:28 +02:00
Forrest
8aff20b374 docs: Correct minor typo in windows.md (#582)
should read msys2 instead of mys2
2022-07-25 12:08:41 +02:00
catsout
3b8b95a22f fix: Add Config/DataHomeDir paths before Config/DataDirs paths (#586)
fix not saving to "XDG_DATA_HOME", when "XDG_DATA_DIRS" is available.  
fix "Content Store" persist in flatpak.

XDG specification specifies how to find config and data directories on
linux systems. Specifically, it says this:

- Data should be written to $XDG_DATA_HOME
- Config should be written to $XDG_CONFIG_HOME
- Data should be read from $XDG_DATA_HOME:$XDG_DATA_DIRS
- Config should be read from $XDG_CONFIG_HOME:$XDG_CONFIG_DIRS
2022-07-25 12:08:10 +02:00
xtexChooser
2cb65aac72 lang: Fix typo in Chinese translation (#589) 2022-07-25 12:07:18 +02:00
WerWolv
0c8deecfc5 patterns: Updated pattern language 2022-07-25 11:50:46 +02:00
WerWolv
74f17fd638 ui: Properly hide hidden patterns in hex editor view 2022-07-25 11:33:30 +02:00
WerWolv
f3f13ae4d3 fix: Jumping to selection not working correctly with set base address 2022-07-23 21:31:54 +02:00
WerWolv
daffa4e555 fix: Edit -> Create Bookmark shortcut creating bookmark at wrong address 2022-07-23 21:17:17 +02:00
WerWolv
c618eec843 fix: Hex editor selection not working correctly when setting base address 2022-07-23 20:46:20 +02:00
WerWolv
71a7ae70d0 git: Fixed Arch Linux CI build issue 2022-07-23 20:42:59 +02:00
WerWolv
c1a2697e42 ui: Added filter to bookmarks view 2022-07-23 20:38:38 +02:00
WerWolv
d4dd57c7c8 fix: Setting base address causing hex editor to display zeros 2022-07-23 18:21:37 +02:00
WerWolv
9e3c6898ad fix: Multi-byte hex editor visualizers displaying incorrect bytes 2022-07-23 15:21:24 +02:00
WerWolv
b6d7fd6984 git: Make analysis workflow also pull latest patterns 2022-07-18 20:18:41 +02:00
WerWolv
d8eb027c94 git: Make tests also pull latest patterns 2022-07-18 20:15:14 +02:00
WerWolv
80d47b658e git: Fixed CI, updated all env var names 2022-07-18 20:13:01 +02:00
WerWolv
51f2b24daa git: Create new ImHex-Patterns release on new ImHex release 2022-07-18 20:02:12 +02:00
WerWolv
fe86f69da3 fix: Duplicate pattern data view entries when sorting the list
Fixes #584
2022-07-18 11:40:49 +02:00
WerWolv
2fb51d1a56 patterns: Fixed Bit and Bool operator mixup 2022-07-18 11:39:50 +02:00
WerWolv
ca3b5b72ca ui: Fixed highlighting color and tooltips 2022-07-17 13:12:28 +02:00
WerWolv
3db8e2aec2 build: Bumped version to 1.19.2 2022-07-16 13:41:37 +02:00
WerWolv
499b68b7ad build: Updated nativefiledialog library 2022-07-16 13:26:07 +02:00
WerWolv
2e3bb8e555 patterns: Don't display empty strings in pattern data view 2022-07-16 13:08:08 +02:00
WerWolv
0c9eab70d5 fix: Crash when searching for an empty string 2022-07-16 13:01:40 +02:00
WerWolv
0d3eaa5d86 patterns: Updated pattern language 2022-07-16 12:57:33 +02:00
WerWolv
c20634e093 sys: Fixed crash on exit 2022-07-16 12:14:15 +02:00
WerWolv
5ee3b550bc ui: Fixed advanced decoding cell sizes 2022-07-16 12:14:06 +02:00
WerWolv
831dac9b47 patterns: Updated pattern language 2022-07-15 11:38:46 +02:00
WerWolv
626c34dce8 sys: Upgrade codebase to C++23 2022-07-15 11:37:10 +02:00
Lukas Cone
ed67c20cba fix: User folders didnt load at startup (#578) 2022-07-14 11:38:23 +02:00
Lukas Cone
35c209c791 fix: In/Out variables not working, add recusive pattern scan (#579) 2022-07-14 11:37:02 +02:00
WerWolv
315109aa1f fix: Open File shortcut only working when Hex Editor view is selected
Fixes #576
2022-07-08 14:26:13 +02:00
WerWolv
a57fa34f82 build: Added option for Offline builds 2022-07-08 14:17:22 +02:00
iTrooz_
d1a2f7d6ed build: Cleanup package dependencies (#573)
* removed DEBIAN/imhex.desktop

* added licence to cmake install directory + fixed PKGBUILD to copy desktop file/licence

* removed gtk3 from packaging files

* added xdg-desktop-portal dependency

* adwaita theme should not be needed anymore

* added dbus dependency
2022-07-08 09:23:53 +02:00
WerWolv
8382f68601 fix: Data inspector string row not being editable correctly
Fixes #575
2022-07-08 09:21:49 +02:00
WerWolv
3aa1dd1e06 build: Added usp10 library to maybe provide Windows 7 support 2022-07-07 23:30:09 +02:00
WerWolv
0571fe383c fix: Duplicate file chooser popup entries not being selectable 2022-07-07 23:29:50 +02:00
WerWolv
461c5eac3e fix: Crash when closing the file picker without picking a file 2022-07-07 23:28:40 +02:00
KokaKiwi
e34f94bb79 build: Add xdg-desktop-portal for AUR package (#572)
* Add xdg-desktop-portal for AUR package

* Fix archlinux package build
2022-07-07 22:08:27 +02:00
WerWolv
071bae345e patterns: Fixed passing placed values to functions 2022-07-07 21:32:25 +02:00
WerWolv
9f4625aa00 fix: Editing float and double data inspector rows yielding wrong values
Fixes #571
2022-07-07 18:35:10 +02:00
iTrooz_
9837473810 git: Automatically create PatternLanguage release on new ImHex releases (#570) 2022-07-07 16:10:21 +02:00
WerWolv
9d3759c6cd build: Bumped version to 1.19.1 2022-07-07 08:48:37 +02:00
WerWolv
6aa55eb056 git: Make nightly download options more clear 2022-07-07 08:01:20 +02:00
WerWolv
c8b7f350ad ui: Fix rendering and default view initializing 2022-07-07 07:16:38 +02:00
WerWolv
b6b5045340 build: Downgrade nativefiledialog again 2022-07-06 16:58:36 +02:00
WerWolv
ab4f17a6f4 patterns: Fixed provider operation crash 2022-07-06 16:46:33 +02:00
WerWolv
541f1d5550 ui: Fixed positioning of UI 2022-07-06 16:40:30 +02:00
WerWolv
12942a4e71 build: Updated libromfs 2022-07-06 16:29:26 +02:00
WerWolv
1a378381bd build: Updated pattern language 2022-07-06 11:30:23 +02:00
WerWolv
1354c913a4 fix: UI stuttering when resizing or restoring window 2022-07-06 11:30:06 +02:00
WerWolv
c752fba1c4 ui: Added backdrop image when no views are open 2022-07-06 11:30:06 +02:00
WerWolv
d40a445f33 build: Updated various dependencies 2022-07-06 11:30:06 +02:00
WerWolv
e0cae1dacb patterns: Improved pattern formatting 2022-07-06 11:30:06 +02:00
WerWolv
31a746f3fc fix: Issue opening files that contain special characters on Linux
This is a (hopefully temporary) hack. Fixes #568
2022-07-06 11:29:24 +02:00
WerWolv
b401059678 ux: Automatically restore default layout when no view is open and a file is loaded 2022-07-05 12:10:54 +02:00
iTrooz_
a30f49c75e git: Improve size of Full Sources tar (#569)
* remove .git directories from Full sources

* actually compress Full sources
2022-07-05 10:12:16 +02:00
WerWolv
e981fa53f3 fix: std::u8string usage with nlohmann::json 2022-07-05 09:01:09 +02:00
WerWolv
4cd390ab02 fix: Various more unicode issues 2022-07-05 00:00:00 +02:00
69 changed files with 472 additions and 317 deletions

View File

@@ -56,6 +56,7 @@ jobs:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j 4 install

View File

@@ -96,6 +96,7 @@ jobs:
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DRUST_PATH="$USERPROFILE/.cargo/bin/" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
mingw32-make -j4 install
cpack
@@ -163,6 +164,7 @@ jobs:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j4 package
@@ -227,20 +229,21 @@ jobs:
cd build
CC=gcc-12 CXX=g++-12 cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
-DRUST_PATH="$HOME/.cargo/bin/" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j 4 install DESTDIR=AppDir
- name: 📜 Set version variable
run: |
echo "version=`cat VERSION`" >> $GITHUB_ENV
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
#- name: 📦 Bundle Flatpak
# run: |
@@ -255,14 +258,14 @@ jobs:
run: |
cp -r build/DEBIAN build/AppDir
dpkg-deb --build build/AppDir
mv build/AppDir.deb imhex-${{env.version}}.deb
mv build/AppDir.deb imhex-${{env.IMHEX_VERSION}}.deb
rm -rf build/AppDir/DEBIAN
- name: 📦 Bundle AppImage
run: |
cd build
appimage-builder --recipe ../dist/AppImageBuilder.yml
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.version}}.AppImage
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.IMHEX_VERSION}}.AppImage
cd ..
#- name: ⬆️ Upload Flatpak
@@ -328,25 +331,26 @@ jobs:
run: |
mkdir -p build
cd build
CC=gcc CXX=g++ cmake \
CC=gcc CXX=g++ cmake \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DRUST_PATH="$HOME/.cargo/bin/" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j 4 install DESTDIR=installDir
- name: 📜 Set version variable
run: |
echo "version=`cat VERSION`" >> $GITHUB_ENV
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
- name: ✒️ Prepare PKGBUILD
run: |
cp dist/Arch/PKGBUILD build
sed -i 's/%version%/${{env.version}}/g' build/PKGBUILD
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' build/PKGBUILD
# makepkg doesn't want to run as root, so I had to chmod 777 all over
- name: 📦 Package ArchLinux .pkg.tar.zst
@@ -355,20 +359,20 @@ jobs:
# the name is a small trick to make makepkg recognize it as the source
# else, it would try to download the file from the release
tar -cvf imhex-${{env.version}}-ArchLinux.pkg.tar.zst -C installDir .
tar -cvf imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst -C installDir .
chmod -R 777 .
sudo -u nobody makepkg
# Remplace the old file
rm imhex-${{env.version}}-ArchLinux.pkg.tar.zst
mv *.pkg.tar.zst imhex-${{env.version}}-ArchLinux.pkg.tar.zst
rm imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
uses: actions/upload-artifact@v3
with:
name: ArchLinux .pkg.tar.zst
path: |
build/imhex-${{env.version}}-ArchLinux.pkg.tar.zst
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst

View File

@@ -29,10 +29,10 @@ jobs:
exit 1
fi
echo "version=$project_version" >> $GITHUB_ENV
echo "IMHEX_VERSION=$project_version" >> $GITHUB_ENV
- name: 🗜️ Create tarball from sources with dependencies
run: tar -cvf Full.Sources.tar.gz ImHex
run: tar --exclude-vcs -czvf Full.Sources.tar.gz ImHex
- name: ⬇️ Download artifacts from latest workflow
uses: dawidd6/action-download-artifact@v2
@@ -58,7 +58,7 @@ jobs:
done
- name: 🟩 Rename Windows Portable Zip
run: mv "Windows Portable.zip" imhex-${{env.version}}-Windows-Portable.zip
run: mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
- name: ⬆️ Upload everything to release
uses: softprops/action-gh-release@v1
@@ -69,17 +69,17 @@ jobs:
run: |
cp ImHex/dist/Arch/PKGBUILD .
hash=`md5sum imhex-${{env.version}}-ArchLinux.pkg.tar.zst | cut -d ' ' -f 1`
hash=`md5sum imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst | cut -d ' ' -f 1`
sed -i 's/%version%/${{env.version}}/g' PKGBUILD
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' PKGBUILD
sed -i "s/(SKIP)/($hash)/g" PKGBUILD
- name: ⬆️ Publish AUR package
# I couldn't make the condition in the env directly for some reason
env:
MY_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
if: "${{ env.MY_KEY != '' }}"
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
if: "${{ env.AUR_SSH_PRIVATE_KEY != '' }}"
uses: KSXGitHub/github-actions-deploy-aur@v2
with:
@@ -88,5 +88,25 @@ jobs:
commit_username: iTrooz
commit_email: itrooz@protonmail.com
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: Bump to version ${{env.version}}
commit_message: Bump to version ${{env.IMHEX_VERSION}}
ssh_keyscan_types: rsa,dsa,ecdsa,ed25519
- name: 🎫 Create PatternLanguage release
uses: ncipollo/release-action@v1
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
if: "${{ env.RELEASE_TOKEN != '' }}"
with:
tag: ImHex-v${{env.IMHEX_VERSION}}
repo: PatternLanguage
token: ${{ secrets.RELEASE_TOKEN }}
- name: 🎫 Create ImHex-Patterns release
uses: ncipollo/release-action@v1
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
if: "${{ env.RELEASE_TOKEN != '' }}"
with:
tag: ImHex-v${{env.IMHEX_VERSION}}
repo: ImHex-Patterns
token: ${{ secrets.RELEASE_TOKEN }}

View File

@@ -54,6 +54,7 @@ jobs:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
-DIMHEX_PATTERNS_PULL_MASTER=ON \
..
make -j4 unit_tests install

View File

@@ -5,11 +5,14 @@ file(READ "VERSION" IMHEX_VERSION)
project(imhex VERSION ${IMHEX_VERSION})
message("Project version ${IMHEX_VERSION}")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
set(IMHEX_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_MODULE_PATH "${IMHEX_BASE_FOLDER}/cmake/modules")
include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
# Make sure project is configured correctly
setDefaultBuiltTypeIfUnset()
detectBadClone()

View File

@@ -122,13 +122,14 @@ To develop plugins for ImHex, use one of the following two templates projects to
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
- Windows • __x86_64__
- [MSI](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
- [EXE](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable%20ZIP.zip)
- [Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
- [Portable](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable%20ZIP.zip)
- MacOS • __x86_64__
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
- Linux • __x86_64__
- [DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB.zip)
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
- [Arch Package](https://nightly.link/WerWolv/ImHex/workflows/build/master/ArchLinux%20.pkg.tar.zst.zip)
## Compiling

View File

@@ -1 +1 @@
1.19.0
1.19.3

View File

@@ -222,6 +222,7 @@ macro(createPackage)
configure_file(${CMAKE_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
install(FILES ${CMAKE_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
install(FILES ${CMAKE_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
@@ -289,17 +290,25 @@ endmacro()
function(downloadImHexPatternsFiles dest)
FetchContent_Declare(
imhex_patterns
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
GIT_TAG master
)
if (NOT IMHEX_OFFLINE_BUILD)
if (IMHEX_PATTERNS_PULL_MASTER)
set(PATTERNS_BRANCH master)
else ()
set(PATTERNS_BRANCH ImHex-v${IMHEX_VERSION})
endif ()
FetchContent_Populate(imhex_patterns)
FetchContent_Declare(
imhex_patterns
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
GIT_TAG master
)
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
endforeach()
FetchContent_Populate(imhex_patterns)
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
endforeach ()
endif ()
endfunction()

View File

@@ -26,7 +26,6 @@ AppDir:
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security multiverse
include:
- adwaita-icon-theme-full
- librsvg2-common
- libbz2-1.0:amd64
- libcap2:amd64
@@ -85,7 +84,6 @@ AppDir:
- /lib/x86_64-linux-gnu/libgnutls.so.30
- /lib/x86_64-linux-gnu/libgobject-2.0.so.0
- /lib/x86_64-linux-gnu/libgraphite2.so.3
- /lib/x86_64-linux-gnu/libgtk-3.so.0
- /lib/x86_64-linux-gnu/libharfbuzz.so.0
- /lib/x86_64-linux-gnu/libhogweed.so.6
- /lib/x86_64-linux-gnu/libicudata.so.70

5
dist/Arch/PKGBUILD vendored
View File

@@ -8,7 +8,7 @@ url="https://github.com/WerWolv/ImHex"
repo=$url
license=('GPL 2.0')
groups=()
depends=(glfw mbedtls python freetype2 libglvnd gtk3)
depends=(glfw mbedtls python freetype2 libglvnd dbus xdg-desktop-portal)
makedepends=(git)
checkdepends=()
optdepends=()
@@ -34,5 +34,6 @@ package() {
done
cp -r $srcdir/usr/share/imhex/{constants,encodings,includes,magic,patterns} $pkgdir/usr/share/imhex
install -d $pkgdir/usr/share/imhex
cp -r $srcdir/usr/share/{applications,licenses} $pkgdir/usr/share
install -d $pkgdir/usr/share
}

1
dist/Brewfile vendored
View File

@@ -7,5 +7,4 @@ brew "python3"
brew "freetype2"
brew "libmagic"
brew "pkg-config"
brew "llvm"
brew "gcc@12"

View File

@@ -4,7 +4,7 @@ Section: editors
Priority: optional
Architecture: amd64
License: GNU GPL-2
Depends: libglfw3, libmagic1, libmbedtls14, libpython3.10, libfreetype6, libopengl0, libgtk-3-0
Depends: libglfw3, libmagic1, libmbedtls14, libpython3.10, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
Maintainer: WerWolv <hey@werwolv.net>
Description: ImHex Hex Editor
A Hex Editor for Reverse Engineers, Programmers and

View File

@@ -1,11 +0,0 @@
[Desktop Entry]
Name=ImHex
Comment=ImHex Hex Editor
GenericName=Hex Editor
Exec=/usr/bin/imhex %U
Icon=/usr/share/pixmaps/imhex.png
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Development;
StartupWMClass=imhex

3
dist/Dockerfile vendored
View File

@@ -15,7 +15,8 @@ RUN pacman -S --needed --noconfirm \
mbedtls \
python3 \
freetype2 \
gtk3
dbus \
xdg-desktop-portal
# Clone ImHex
RUN git clone https://github.com/WerWolv/ImHex --recurse-submodules /root/ImHex

View File

@@ -27,6 +27,7 @@ RDEPEND="${DEPEND}
sys-apps/file
dev-libs/mbedtls
dev-cpp/nlohmann_json
x11-libs/gtk+
dbus
xdg-desktop-portal
"
BDEPEND="${DEPEND}"

View File

@@ -1,6 +1,6 @@
### Compiling ImHex on Windows
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a mys2 window and run the PKGCONFIG script in the [dist/msys2](dist/msys2) folder.
On Windows, ImHex is built through msys2 / mingw. To install all dependencies, open a msys2 window and run the PKGCONFIG script in the [dist/msys2](dist/msys2) folder.
After all the dependencies are installed, run the following commands to build ImHex:
```sh
@@ -20,4 +20,4 @@ cmake -G "MinGW Makefiles" \
mingw32-make -j install
```
ImHex will look for any extra resources either in various folders directly next to the executable or in `%localappdata%/imhex`
ImHex will look for any extra resources either in various folders directly next to the executable or in `%localappdata%/imhex`

View File

@@ -9,4 +9,5 @@ pacman -S $@ --needed \
mbedtls \
python3 \
freetype2 \
gtk3
dbus \
xdg-desktop-portal

View File

@@ -21,4 +21,5 @@ apt install -y \
libmbedtls-dev \
python3-dev \
libfreetype-dev \
libgtk-3-dev
libdbus-1-dev \
xdg-desktop-portal

View File

@@ -10,4 +10,5 @@ dnf install \
mbedtls-devel \
python-devel \
freetype-devel \
gtk3-devel
dbus \
xdg-desktop-portal

View File

@@ -32,14 +32,14 @@ add_library(imgui OBJECT
source/implot_items.cpp
source/implot_demo.cpp
fonts/fontawesome_font.c
fonts/codicons_font.c
fonts/unifont_font.c
source/fonts/fontawesome_font.c
source/fonts/codicons_font.c
source/fonts/unifont_font.c
)
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
target_include_directories(imgui PUBLIC include fonts ${CMAKE_CURRENT_SOURCE_DIR} ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS})
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS})

View File

@@ -44,6 +44,7 @@ namespace hex {
std::future<Response<void>> downloadFile(const std::string &url, const std::fs::path &filePath, u32 timeout = DefaultTimeout);
[[nodiscard]] std::string encode(const std::string &input);
[[nodiscard]] std::string decode(const std::string &input);
[[nodiscard]] float getProgress() const { return this->m_progress; }

View File

@@ -110,6 +110,11 @@ namespace hex::prv {
friend bool operator== (const Iterator& left, const Iterator& right) { return left.m_address == right.m_address; };
friend bool operator!= (const Iterator& left, const Iterator& right) { return left.m_address != right.m_address; };
friend bool operator> (const Iterator& left, const Iterator& right) { return left.m_address > right.m_address; };
friend bool operator< (const Iterator& left, const Iterator& right) { return left.m_address < right.m_address; };
friend bool operator>= (const Iterator& left, const Iterator& right) { return left.m_address >= right.m_address; };
friend bool operator<= (const Iterator& left, const Iterator& right) { return left.m_address <= right.m_address; };
private:
BufferedReader *m_reader;
u64 m_address;
@@ -176,10 +181,14 @@ namespace hex::prv {
friend bool operator== (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address == right.m_address; };
friend bool operator!= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address != right.m_address; };
friend bool operator> (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address > right.m_address; };
friend bool operator< (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address < right.m_address; };
friend bool operator>= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address >= right.m_address; };
friend bool operator<= (const ReverseIterator& left, const ReverseIterator& right) { return left.m_address <= right.m_address; };
private:
BufferedReader *m_reader;
u64 m_address;
u64 m_address = 0x00;
};
Iterator begin() {
@@ -187,7 +196,7 @@ namespace hex::prv {
}
Iterator end() {
return { this, this->m_baseAddress + this->m_provider->getActualSize() };
return { this, this->m_provider->getActualSize() };
}
ReverseIterator rbegin() {

View File

@@ -130,7 +130,9 @@ namespace ImGui {
}
bool InputText(const char* label, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputTextMultiline(const char* label, std::string &buffer, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputScalarCallback(const char* label, ImGuiDataType data_type, void* p_data, const char* format, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);

View File

@@ -7,8 +7,8 @@
#include <imgui_internal.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fontawesome_font.h>
#include <codicons_font.h>
#include <fonts/fontawesome_font.h>
#include <fonts/codicons_font.h>
#include <hex/api/imhex_api.hpp>
#include <hex/api/event.hpp>

View File

@@ -24,8 +24,6 @@ namespace hex {
}
#endif
auto pluginName = std::fs::path(path).stem().string();
this->m_initializePluginFunction = getPluginFunction<InitializePluginFunc>("initializePlugin");
this->m_getPluginNameFunction = getPluginFunction<GetPluginNameFunc>("getPluginName");
this->m_getPluginAuthorFunction = getPluginFunction<GetPluginAuthorFunc>("getPluginAuthor");

View File

@@ -38,8 +38,6 @@ namespace hex {
{
auto delimiterPos = line.find('=');
if (delimiterPos == std::string::npos)
continue;
if (delimiterPos >= line.length())
continue;
@@ -47,12 +45,16 @@ namespace hex {
to = line.substr(delimiterPos + 1);
if (from.empty()) continue;
if (to.empty()) to = " ";
}
auto fromBytes = hex::parseByteString(from);
if (fromBytes.empty()) continue;
if (to.length() > 1)
hex::trim(to);
if (to.empty())
to = " ";
if (!this->m_mapping.contains(fromBytes.size()))
this->m_mapping.insert({ fromBytes.size(), {} });
this->m_mapping[fromBytes.size()].insert({ fromBytes, to });

View File

@@ -4,6 +4,7 @@
#include <hex/helpers/fs_macos.hpp>
#include <hex/helpers/file.hpp>
#include <hex/helpers/intrinsics.hpp>
#include <hex/helpers/net.hpp>
#include <xdg.hpp>
@@ -70,7 +71,7 @@ namespace hex::fs {
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath) {
NFD::Init();
nfdchar_t *outPath;
nfdchar_t *outPath = nullptr;
nfdresult_t result;
switch (mode) {
case DialogMode::Open:
@@ -86,8 +87,8 @@ namespace hex::fs {
hex::unreachable();
}
if (result == NFD_OKAY) {
callback(reinterpret_cast<const char8_t *>(outPath));
if (result == NFD_OKAY && outPath != nullptr) {
callback(reinterpret_cast<char8_t*>(outPath));
NFD::FreePath(outPath);
}
@@ -205,39 +206,39 @@ namespace hex::fs {
switch (path) {
case ImHexPath::Patterns:
result.push_back((applicationSupportDirPath / "patterns").string());
result.push_back(applicationSupportDirPath / "patterns");
break;
case ImHexPath::PatternsInclude:
result.push_back((applicationSupportDirPath / "includes").string());
result.push_back(applicationSupportDirPath / "includes");
break;
case ImHexPath::Magic:
result.push_back((applicationSupportDirPath / "magic").string());
result.push_back(applicationSupportDirPath / "magic");
break;
case ImHexPath::Python:
result.push_back((applicationSupportDirPath / "python").string());
result.push_back(applicationSupportDirPath / "python");
break;
case ImHexPath::Plugins:
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) {
return (path / "plugins").string();
return path / "plugins";
});
break;
case ImHexPath::Yara:
result.push_back((applicationSupportDirPath / "yara").string());
result.push_back(applicationSupportDirPath / "yara");
break;
case ImHexPath::Config:
result.push_back((applicationSupportDirPath / "config").string());
result.push_back(applicationSupportDirPath / "config");
break;
case ImHexPath::Resources:
result.push_back((applicationSupportDirPath / "resources").string());
result.push_back(applicationSupportDirPath / "resources");
break;
case ImHexPath::Constants:
result.push_back((applicationSupportDirPath / "constants").string());
result.push_back(applicationSupportDirPath / "constants");
break;
case ImHexPath::Encodings:
result.push_back((applicationSupportDirPath / "encodings").string());
result.push_back(applicationSupportDirPath / "encodings");
break;
case ImHexPath::Logs:
result.push_back((applicationSupportDirPath / "logs").string());
result.push_back(applicationSupportDirPath / "logs");
break;
default:
hex::unreachable();
@@ -246,8 +247,8 @@ namespace hex::fs {
std::vector<std::fs::path> configDirs = xdg::ConfigDirs();
std::vector<std::fs::path> dataDirs = xdg::DataDirs();
configDirs.push_back(xdg::ConfigHomeDir());
dataDirs.push_back(xdg::DataHomeDir());
configDirs.insert(configDirs.begin(), xdg::ConfigHomeDir());
dataDirs.insert(dataDirs.begin(), xdg::DataHomeDir());
for (auto &dir : dataDirs)
dir = dir / "imhex";
@@ -258,43 +259,43 @@ namespace hex::fs {
switch (path) {
case ImHexPath::Patterns:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "patterns").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "patterns"; });
break;
case ImHexPath::PatternsInclude:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "includes").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "includes"; });
break;
case ImHexPath::Magic:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "magic").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "magic"; });
break;
case ImHexPath::Python:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p).string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p; });
break;
case ImHexPath::Plugins:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "plugins").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "plugins"; });
break;
case ImHexPath::Yara:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "yara").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "yara"; });
break;
case ImHexPath::Config:
std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result), [](auto p) { return (p / "imhex").string(); });
std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result), [](auto p) { return p / "imhex"; });
break;
case ImHexPath::Resources:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "resources").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "resources"; });
break;
case ImHexPath::Constants:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "constants").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "constants"; });
break;
case ImHexPath::Encodings:
addUserDirs(dataDirs);
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "encodings").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "encodings"; });
break;
case ImHexPath::Logs:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return (p / "logs").string(); });
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "logs"; });
break;
default:
hex::unreachable();

View File

@@ -122,7 +122,7 @@ namespace hex {
std::optional<i32> Net::execute() {
CURLcode result = curl_easy_perform(this->m_ctx);
if (result != CURLE_OK)
log::error("Net request failed with error {0}: '{1}'", result, curl_easy_strerror(result));
log::error("Net request failed with error {0}: '{1}'", u32(result), curl_easy_strerror(result));
i32 responseCode = 0;
curl_easy_getinfo(this->m_ctx, CURLINFO_RESPONSE_CODE, &responseCode);
@@ -180,7 +180,7 @@ namespace hex {
ON_SCOPE_EXIT { this->m_transmissionActive.unlock(); };
fs::File file(filePath.string(), fs::File::Mode::Read);
fs::File file(filePath, fs::File::Mode::Read);
if (!file.isValid())
return Response<std::string> { 400, {} };
@@ -218,7 +218,7 @@ namespace hex {
ON_SCOPE_EXIT { this->m_transmissionActive.unlock(); };
fs::File file(filePath.string(), fs::File::Mode::Create);
fs::File file(filePath, fs::File::Mode::Create);
if (!file.isValid())
return Response<void> { 400 };
@@ -245,6 +245,19 @@ namespace hex {
return {};
}
std::string Net::decode(const std::string &input) {
auto unescapedString = curl_easy_unescape(this->m_ctx, input.c_str(), std::strlen(input.c_str()), nullptr);
if (unescapedString != nullptr) {
std::string output = unescapedString;
curl_free(unescapedString);
return output;
}
return {};
}
std::string Net::s_proxyUrl;
void Net::setProxy(const std::string &url) {

View File

@@ -52,10 +52,10 @@ namespace hex {
json projectFileData;
try {
std::ifstream projectFile(filePath.c_str());
std::ifstream projectFile(filePath);
projectFile >> projectFileData;
ProjectFile::s_filePath = std::fs::path(projectFileData["filePath"].get<std::string>());
ProjectFile::s_filePath = std::fs::path(projectFileData["filePath"].get<std::u8string>());
ProjectFile::s_pattern = projectFileData["pattern"];
ProjectFile::s_patches = projectFileData["patches"].get<Patches>();
ProjectFile::s_dataProcessorContent = projectFileData["dataProcessor"];
@@ -89,7 +89,7 @@ namespace hex {
filePath = ProjectFile::s_currProjectFilePath;
try {
projectFileData["filePath"] = ProjectFile::s_filePath.string();
projectFileData["filePath"] = ProjectFile::s_filePath.u8string();
projectFileData["pattern"] = ProjectFile::s_pattern;
projectFileData["patches"] = ProjectFile::s_patches;
projectFileData["dataProcessor"] = ProjectFile::s_dataProcessorContent;

View File

@@ -334,8 +334,8 @@ namespace ImGui {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#if defined(GL_UNPACK_ROW_LENGTH)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -553,6 +553,14 @@ namespace ImGui {
return ImGui::InputText(label, buffer.data(), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
}
bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags) {
return ImGui::InputTextWithHint(label, hint, buffer.data(), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
}
bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags) {
return ImGui::InputText(label, reinterpret_cast<char *>(buffer.data()), buffer.size() + 1, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
}
bool InputTextMultiline(const char *label, std::string &buffer, const ImVec2 &size, ImGuiInputTextFlags flags) {
return ImGui::InputTextMultiline(label, buffer.data(), buffer.size() + 1, size, ImGuiInputTextFlags_CallbackResize | flags, ImGui::UpdateStringSizeCallback, &buffer);
}

View File

@@ -26,7 +26,7 @@ set_target_properties(main PROPERTIES
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
if (WIN32)
target_link_libraries(main PUBLIC libimhex wsock32 ws2_32 Dwmapi.lib)
target_link_libraries(main PUBLIC usp10 libimhex wsock32 ws2_32 Dwmapi.lib)
else ()
target_link_libraries(main PUBLIC libimhex pthread)
endif ()

View File

@@ -13,7 +13,7 @@
#include <hex/ui/imgui_imhex_extensions.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <fontawesome_font.h>
#include <fonts/fontawesome_font.h>
#include <GLFW/glfw3.h>
#include <unistd.h>

View File

@@ -9,9 +9,9 @@
#include <hex/helpers/fs.hpp>
#include <hex/helpers/logger.hpp>
#include <fontawesome_font.h>
#include <codicons_font.h>
#include <unifont_font.h>
#include <fonts/fontawesome_font.h>
#include <fonts/codicons_font.h>
#include <fonts/unifont_font.h>
#include <hex/api/plugin_manager.hpp>

View File

@@ -9,7 +9,7 @@
#include <imgui.h>
#include <imgui_internal.h>
#include <codicons_font.h>
#include <fonts/codicons_font.h>
#include <nlohmann/json.hpp>

View File

@@ -30,7 +30,7 @@
#include <imnodes.h>
#include <imnodes_internal.h>
#include <codicons_font.h>
#include <fonts/codicons_font.h>
#include <hex/helpers/project_file_handler.hpp>
@@ -118,7 +118,7 @@ namespace hex {
return;
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
if (ProjectFile::store((std::fs::path(path) / CrashBackupFileName).string()))
if (ProjectFile::store(std::fs::path(path) / CrashBackupFileName))
break;
}
});
@@ -198,7 +198,7 @@ namespace hex {
ImGuiViewport *viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::SetNextWindowSize(ImHexApi::System::getMainWindowSize() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing()));
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
@@ -558,7 +558,8 @@ namespace hex {
});
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
ImHexApi::System::impl::setMainWindowSize(width, height);
if (!glfwGetWindowAttrib(window, GLFW_ICONIFIED))
ImHexApi::System::impl::setMainWindowSize(width, height);
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;

View File

@@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
private:
std::list<ImHexApi::Bookmarks::Entry> m_bookmarks;
std::string m_currFilter;
};
}

View File

@@ -41,7 +41,9 @@ namespace hex::plugin::builtin {
if (end == InvalidSelection)
end = start;
const size_t maxAddress = ImHexApi::Provider::get()->getActualSize() - 1;
auto provider = ImHexApi::Provider::get();
const size_t maxAddress = provider->getActualSize() + provider->getBaseAddress() - 1;
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;

View File

@@ -21,7 +21,7 @@ namespace hex::plugin::builtin {
void drawContent() override;
private:
std::map<prv::Provider *, std::vector<std::shared_ptr<pl::Pattern>>> m_sortedPatterns;
std::map<prv::Provider *, std::vector<pl::Pattern*>> m_sortedPatterns;
hex::PatternDrawer m_patternDrawer;
};

View File

@@ -56,7 +56,6 @@ namespace hex::plugin::builtin {
};
std::map<std::string, PatternVariable> m_patternVariables;
std::vector<std::string> m_patternTypes;
enum class EnvVarType
{
@@ -102,4 +101,4 @@ namespace hex::plugin::builtin {
void evaluatePattern(const std::string &code);
};
}
}

View File

@@ -54,7 +54,7 @@ namespace hex::plugin::builtin {
template<std::floating_point T>
static std::vector<u8> stringToFloat(const std::string &value, std::endian endian) requires(sizeof(T) <= sizeof(long double)) {
auto result = std::strtold(value.c_str(), nullptr);
T result = std::strtold(value.c_str(), nullptr);
std::vector<u8> bytes(sizeof(T), 0x00);
std::memcpy(bytes.data(), &result, bytes.size());
@@ -349,7 +349,7 @@ namespace hex::plugin::builtin {
ContentRegistry::DataInspector::add("hex.builtin.inspector.string", 1,
[](auto buffer, auto endian, auto style) {
hex::unused(endian, style);
hex::unused(buffer, endian, style);
auto currSelection = ImHexApi::HexEditor::getSelection();
@@ -358,14 +358,15 @@ namespace hex::plugin::builtin {
std::string value, copyValue;
if (currSelection.has_value()) {
std::vector<u8> stringBuffer(std::min<size_t>(MaxStringLength, currSelection->size), 0x00);
std::vector<u8> stringBuffer(std::min<size_t>(currSelection->size, 0x1000), 0x00);
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
value = hex::encodeByteString(stringBuffer);
copyValue = hex::encodeByteString(buffer);
value = copyValue = hex::encodeByteString(stringBuffer);
if (currSelection->size > MaxStringLength)
if (currSelection->size > MaxStringLength) {
value.resize(MaxStringLength);
value += "...";
}
} else {
value = "";
copyValue = "";

View File

@@ -91,7 +91,7 @@ namespace hex::plugin::builtin {
}
void load(nlohmann::json &j) override {
this->m_value = j["data"];
this->m_value = j["data"].get<std::string>();
}
private:
@@ -213,7 +213,7 @@ namespace hex::plugin::builtin {
}
void load(nlohmann::json &j) override {
this->m_comment = j["comment"];
this->m_comment = j["comment"].get<std::string>();
}
private:

View File

@@ -250,14 +250,11 @@ namespace hex::plugin::builtin {
});
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.edit", 1050, [&] {
auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid();
auto selection = ImHexApi::HexEditor::getSelection();
if (ImGui::MenuItem("hex.builtin.menu.edit.bookmark"_lang, nullptr, false, selection.has_value() && providerValid)) {
auto base = provider->getBaseAddress();
ImHexApi::Bookmarks::add(base + selection->getStartAddress(), selection->size, {}, {});
ImHexApi::Bookmarks::add(selection->getStartAddress(), selection->getSize(), {}, {});
}
});

View File

@@ -13,6 +13,19 @@
#include <nlohmann/json.hpp>
namespace {
static std::vector<std::fs::path> userFolders;
static void loadUserFoldersFromSetting(nlohmann::json &setting) {
userFolders.clear();
std::vector<std::string> paths = setting;
for (const auto &path : paths) {
// JSON reads char8_t as array, char8_t is not supported as of now
std::u8string_view uString(reinterpret_cast<const char8_t *>(&path.front()), reinterpret_cast<const char8_t *>(std::next(&path.back())));
userFolders.emplace_back(uString);
}
}
};
namespace hex::plugin::builtin {
void registerSettings() {
@@ -247,7 +260,7 @@ namespace hex::plugin::builtin {
for (const auto &[unlocalizedName, visualizer] : visualizers) {
if (ImGui::Selectable(LangEntry(unlocalizedName))) {
setting = unlocalizedName;
result = true;
result = true;
}
}
@@ -314,34 +327,27 @@ namespace hex::plugin::builtin {
ContentRegistry::Settings::add(dirsSetting, dirsSetting, std::vector<std::string> {}, [](auto name, nlohmann::json &setting) {
hex::unused(name);
static size_t currentItemIndex = 0;
static std::vector<std::fs::path> folders = [&setting]{
std::vector<std::fs::path> result;
static size_t currentItemIndex = [&setting] {loadUserFoldersFromSetting(setting); return 0; }();
std::vector<std::u8string> paths = setting;
for (const auto &path : paths)
result.emplace_back(path);
return result;
}();
auto saveToSetting = [&setting] {
std::vector<std::string> folderStrings;
for (const auto &folder : userFolders) {
auto utfString = folder.u8string();
// JSON stores char8_t as array, char8_t is not supported as of now
folderStrings.emplace_back(reinterpret_cast<const char *>(&utfString.front()), reinterpret_cast<const char *>(std::next(&utfString.back())));
}
setting = folderStrings;
ImHexApi::System::setAdditionalFolderPaths(userFolders);
};
bool result = false;
auto writeSetting = [&setting]{
std::vector<std::u8string> folderStrings;
for (const auto &folder : folders)
folderStrings.push_back(folder.u8string());
setting = folderStrings;
ImHexApi::System::setAdditionalFolderPaths(folders);
};
if (!ImGui::BeginListBox("", ImVec2(-38, -FLT_MIN))) {
return false;
} else {
for (size_t n = 0; n < folders.size(); n++) {
for (size_t n = 0; n < userFolders.size(); n++) {
const bool isSelected = (currentItemIndex == n);
if (ImGui::Selectable(folders.at(n).string().c_str(), isSelected)) { currentItemIndex = n; }
if (ImGui::Selectable(userFolders.at(n).string().c_str(), isSelected)) { currentItemIndex = n; }
if (isSelected) { ImGui::SetItemDefaultFocus(); }
}
ImGui::EndListBox();
@@ -351,12 +357,9 @@ namespace hex::plugin::builtin {
if (ImGui::IconButton(ICON_VS_NEW_FOLDER, ImGui::GetCustomColorVec4(ImGuiCustomCol_DescButton), ImVec2(30, 30))) {
fs::openFileBrowser(fs::DialogMode::Folder, {}, [&](const std::fs::path &path) {
if (std::find(folders.begin(), folders.end(), path) == folders.end()) {
folders.emplace_back(path);
writeSetting();
if (std::find(userFolders.begin(), userFolders.end(), path) == userFolders.end()) {
userFolders.emplace_back(path);
saveToSetting();
result = true;
}
});
@@ -364,10 +367,9 @@ namespace hex::plugin::builtin {
ImGui::InfoTooltip("hex.builtin.setting.folders.add_folder"_lang);
if (ImGui::IconButton(ICON_VS_REMOVE_CLOSE, ImGui::GetCustomColorVec4(ImGuiCustomCol_DescButton), ImVec2(30, 30))) {
if (!folders.empty()) {
folders.erase(std::next(folders.begin(), currentItemIndex));
writeSetting();
if (!userFolders.empty()) {
userFolders.erase(std::next(userFolders.begin(), currentItemIndex));
saveToSetting();
result = true;
}
@@ -480,10 +482,18 @@ namespace hex::plugin::builtin {
ImHexApi::System::setTheme(static_cast<ImHexApi::System::Theme>(theme));
}
static void loadFoldersSettings() {
static const std::string dirsSetting { "hex.builtin.setting.folders" };
auto dirs = ContentRegistry::Settings::getSetting(dirsSetting, dirsSetting);
loadUserFoldersFromSetting(dirs);
ImHexApi::System::setAdditionalFolderPaths(userFolders);
}
void loadSettings() {
loadInterfaceScalingSetting();
loadFontSettings();
loadThemeSettings();
loadFoldersSettings();
}
}

View File

@@ -712,8 +712,8 @@ namespace hex::plugin::builtin {
auto json = nlohmann::json::parse(response.body);
resultTitle = json["query"]["pages"][0]["title"];
resultExtract = json["query"]["pages"][0]["extract"];
resultTitle = json["query"]["pages"][0]["title"].get<std::string>();
resultExtract = json["query"]["pages"][0]["extract"].get<std::string>();
if (!extendedSearch && resultExtract.ends_with(':')) {
extendedSearch = true;
@@ -739,7 +739,7 @@ namespace hex::plugin::builtin {
void drawFileToolShredder() {
static bool shredding = false;
static auto selectedFile = [] { std::string s; s.reserve(0x1000); return s; }();
static std::u8string selectedFile;
static bool fastMode = false;
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.warning"_lang);
@@ -754,7 +754,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.string();
selectedFile = path.u8string();
});
}
@@ -883,11 +883,11 @@ namespace hex::plugin::builtin {
1
};
static bool splitting = false;
static auto selectedFile = [] { std::string s; s.reserve(0x1000); return s; }();
static auto baseOutputPath = [] { std::string s; s.reserve(0x1000); return s; }();
static u64 splitSize = sizes[0];
static int selectedItem = 0;
static bool splitting = false;
static std::u8string selectedFile;
static std::u8string baseOutputPath;
static u64 splitSize = sizes[0];
static int selectedItem = 0;
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
ImGui::BeginDisabled(splitting);
@@ -896,7 +896,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
if (ImGui::Button("...##input")) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
selectedFile = path.string();
selectedFile = path.u8string();
});
}
ImGui::SameLine();
@@ -906,7 +906,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
if (ImGui::Button("...##output")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
baseOutputPath = path.string();
baseOutputPath = path.u8string();
});
}
ImGui::SameLine();
@@ -960,7 +960,10 @@ namespace hex::plugin::builtin {
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
task.update(offset);
fs::File partFile(baseOutputPath + hex::format(".{:05}", index), fs::File::Mode::Create);
std::fs::path path = baseOutputPath;
path += hex::format(".{:05}", index);
fs::File partFile(path, fs::File::Mode::Create);
if (!partFile.isValid()) {
View::showErrorPopup(hex::format("hex.builtin.tools.file_tools.splitter.error.create"_lang, index));
@@ -986,8 +989,8 @@ namespace hex::plugin::builtin {
void drawFileToolCombiner() {
static bool combining = false;
static std::vector<std::string> files;
static auto outputPath = [] { std::string s; s.reserve(0x1000); return s; }();
static std::vector<std::fs::path> files;
static std::u8string outputPath;
static u32 selectedIndex;
if (ImGui::BeginTable("files_table", 2, ImGuiTableFlags_SizingStretchProp)) {
@@ -1035,7 +1038,7 @@ namespace hex::plugin::builtin {
{
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.add"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
files.push_back(path.string());
files.push_back(path);
});
}
ImGui::SameLine();
@@ -1059,7 +1062,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
if (ImGui::Button("...")) {
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
outputPath = path.string();
outputPath = path.u8string();
});
}
ImGui::SameLine();

View File

@@ -6,7 +6,7 @@
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/logger.hpp>
#include <codicons_font.h>
#include <fonts/codicons_font.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <hex/ui/imgui_imhex_extensions.h>
@@ -107,8 +107,11 @@ namespace hex::plugin::builtin {
u32 index = 0;
for (auto &path : s_selectableFiles) {
ImGui::PushID(index);
if (ImGui::Selectable(path.filename().string().c_str(), index == s_selectableFileIndex))
s_selectableFileIndex = index;
ImGui::PopID();
index++;
}
@@ -283,7 +286,7 @@ namespace hex::plugin::builtin {
auto region = ImHexApi::HexEditor::getSelection();
if (region.has_value())
ImHexApi::Bookmarks::add(region->address, region->size, {}, {});
ImHexApi::Bookmarks::add(region->getStartAddress(), region->getSize(), {}, {});
}
}
ImGui::EndDisabled();

View File

@@ -61,11 +61,11 @@ namespace hex::plugin::builtin {
ImGui::BeginTooltip();
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
ImGui::PushID(&bookmark);
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(&bookmark);
{
ImGui::ColorButton("##color", ImColor(bookmark.color));
ImGui::SameLine(0, 10);
@@ -73,7 +73,7 @@ namespace hex::plugin::builtin {
if (ImGui::GetIO().KeyShift) {
ImGui::Indent();
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoClip)) {
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
@@ -98,13 +98,13 @@ namespace hex::plugin::builtin {
}
}
ImGui::PopID();
ImGui::PushStyleColor(ImGuiCol_TableRowBg, bookmark.color);
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, bookmark.color);
ImGui::EndTable();
ImGui::PopStyleColor(2);
}
ImGui::PopID();
ImGui::EndTooltip();
}
@@ -122,17 +122,29 @@ namespace hex::plugin::builtin {
void ViewBookmarks::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.bookmarks.name").c_str(), &this->getWindowOpenState())) {
if (ImGui::BeginChild("##scrolling")) {
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth());
ImGui::InputTextWithHint("##filter", "Filter", this->m_currFilter);
ImGui::PopItemWidth();
ImGui::NewLine();
if (ImGui::BeginChild("##bookmarks")) {
if (this->m_bookmarks.empty()) {
ImGui::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang);
}
u32 id = 1;
u32 id = 1;
auto bookmarkToRemove = this->m_bookmarks.end();
for (auto iter = this->m_bookmarks.begin(); iter != this->m_bookmarks.end(); iter++) {
auto &[region, name, comment, color, locked] = *iter;
if (!this->m_currFilter.empty()) {
if (!name.contains(this->m_currFilter) && !comment.contains(this->m_currFilter))
continue;
}
auto headerColor = ImColor(color);
auto hoverColor = ImColor(color);
hoverColor.Value.w *= 1.3F;

View File

@@ -34,11 +34,11 @@ namespace hex::plugin::builtin {
for (auto value : content["values"]) {
Constant constant;
constant.category = content["name"];
constant.name = value["name"];
constant.category = content["name"].get<std::string>();
constant.name = value["name"].get<std::string>();
if (value.contains("desc"))
constant.description = value["desc"];
constant.value = value["value"];
constant.description = value["desc"].get<std::string>();
constant.value = value["value"].get<std::string>();
auto type = value["type"];
if (type == "int10")

View File

@@ -104,8 +104,10 @@ namespace hex::plugin::builtin {
if (ImGui::BeginTabBar("##find_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.hex"_lang)) {
if (ImGui::InputText("##input", this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsHexadecimal)) {
this->m_shouldSearch = true;
this->m_backwards = false;
if (!this->m_input.empty()) {
this->m_shouldSearch = true;
this->m_backwards = false;
}
}
this->drawButtons();
@@ -119,8 +121,10 @@ namespace hex::plugin::builtin {
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.string"_lang)) {
if (ImGui::InputText("##input", this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
this->m_shouldSearch = true;
this->m_backwards = false;
if (!this->m_input.empty()) {
this->m_shouldSearch = true;
this->m_backwards = false;
}
}
this->drawButtons();
@@ -129,8 +133,8 @@ namespace hex::plugin::builtin {
searchSequence.clear();
std::copy(this->m_input.begin(), this->m_input.end(), std::back_inserter(searchSequence));
// Remove null termination
searchSequence.pop_back();
if (searchSequence.back() == 0x00)
searchSequence.pop_back();
}
ImGui::EndTabItem();
@@ -140,9 +144,9 @@ namespace hex::plugin::builtin {
}
if (!this->m_searchRunning && !searchSequence.empty() && this->m_shouldSearch) {
this->m_searchRunning = true;
std::thread([this, searchSequence, editor]{
this->m_searchTask = ImHexApi::Tasks::createTask("Searching", ImHexApi::Provider::get()->getSize());
this->m_searchRunning = true;
auto task = ImHexApi::Tasks::createTask("Searching", ImHexApi::Provider::get()->getSize());
if (auto region = this->findSequence(editor, searchSequence, this->m_backwards); region.has_value()) {
ImHexApi::Tasks::doLater([editor, region]{
@@ -177,15 +181,20 @@ namespace hex::plugin::builtin {
this->m_searchPosition.reset();
}
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = true;
}
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
ImGui::BeginDisabled(!this->m_searchPosition.has_value());
{
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = true;
}
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
}
}
ImGui::EndDisabled();
}
ImGui::EndDisabled();
}
@@ -196,7 +205,7 @@ namespace hex::plugin::builtin {
if (!editor->isSelectionValid())
reader.seek(this->m_searchPosition.value_or(0x00));
else
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getEndAddress()));
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getStartAddress()));
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
@@ -205,13 +214,17 @@ namespace hex::plugin::builtin {
if (!backwards) {
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
if (occurrence != reader.end()) {
this->m_searchPosition = occurrence.getAddress() + 1;
this->m_searchPosition = occurrence.getAddress() + sequence.size();
return Region { occurrence.getAddress(), sequence.size() };
}
} else {
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.begin(), sequence.end());
if (occurrence != reader.rend()) {
this->m_searchPosition = occurrence.getAddress() - 1;
if (occurrence.getAddress() < sequence.size())
this->m_searchPosition = 0x00;
else
this->m_searchPosition = occurrence.getAddress() - sequence.size();
return Region { occurrence.getAddress(), sequence.size() };
}
}
@@ -226,7 +239,6 @@ namespace hex::plugin::builtin {
std::atomic<bool> m_shouldSearch = false;
std::atomic<bool> m_backwards = false;
std::optional<Task> m_searchTask;
std::atomic<bool> m_searchRunning = false;
};
@@ -239,7 +251,8 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_base"_lang);
if (ImGui::InputHexadecimal("##base_address", &this->m_baseAddress, ImGuiInputTextFlags_EnterReturnsTrue)) {
ImGui::InputHexadecimal("##base_address", &this->m_baseAddress);
if (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
setBaseAddress(this->m_baseAddress);
editor->closePopup();
}
@@ -272,6 +285,10 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.resize"_lang);
ImGui::InputHexadecimal("##resize", &this->m_size);
if (ImGui::IsItemFocused() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
resize(static_cast<size_t>(this->m_size));
editor->closePopup();
}
View::confirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
@@ -434,15 +451,15 @@ namespace hex::plugin::builtin {
const auto [decoded, advance] = encodingFile.getEncodingFor(buffer);
const ImColor color = [&decoded = decoded, &advance = advance]{
if (decoded.length() == 1 && std::isalnum(decoded[0]))
return 0xFFFF8000;
return ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarBlue);
else if (decoded.length() == 1 && advance == 1)
return 0xFF0000FF;
return ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarRed);
else if (decoded.length() > 1 && advance == 1)
return 0xFF00FFFF;
return ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarYellow);
else if (advance > 1)
return 0xFFFFFFFF;
return ImGui::GetColorU32(ImGuiCol_Text);
else
return 0xFFFF8000;
return ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarBlue);
}();
return { std::string(decoded), advance, color };
@@ -556,7 +573,7 @@ namespace hex::plugin::builtin {
drawList->AddLine(cellPos, cellPos + ImVec2(0, cellSize.y), ImColor(SelectionFrameColor), 1.0F);
// Draw vertical line at the right of the last byte and the end of the line
if (x == u16((this->m_bytesPerRow / bytesPerCell) - 1) || (byteAddress + this->m_currDataVisualizer->getBytesPerCell()) > selection.getEndAddress())
if (x == u16((this->m_bytesPerRow / bytesPerCell) - 1) || (byteAddress + bytesPerCell) > selection.getEndAddress())
drawList->AddLine(cellPos + ImVec2(cellSize.x, -1), cellPos + cellSize, ImColor(SelectionFrameColor), 1.0F);
// Draw horizontal line at the top of the bytes
@@ -677,7 +694,7 @@ namespace hex::plugin::builtin {
const u8 validBytes = std::min<u64>(this->m_bytesPerRow, provider->getSize() - y * this->m_bytesPerRow);
std::vector<u8> bytes(validBytes);
provider->read(y * this->m_bytesPerRow + provider->getCurrentPageAddress(), bytes.data(), validBytes);
provider->read(y * this->m_bytesPerRow + provider->getBaseAddress() + provider->getCurrentPageAddress(), bytes.data(), validBytes);
std::vector<std::tuple<std::optional<color_t>, std::optional<color_t>>> cellColors;
{
@@ -688,9 +705,9 @@ namespace hex::plugin::builtin {
// Query cell colors
if (x < validBytes) {
const auto foregroundColor = queryForegroundColor(byteAddress, &bytes[x], cellBytes);
const auto foregroundColor = queryForegroundColor(byteAddress, &bytes[x * cellBytes], cellBytes);
const auto backgroundColor = [&]{
auto color = queryBackgroundColor(byteAddress, &bytes[x], cellBytes);
auto color = queryBackgroundColor(byteAddress, &bytes[x * cellBytes], cellBytes);
if ((byteAddress >= selectionMin && byteAddress <= selectionMax)) {
if (color.has_value())
@@ -748,7 +765,7 @@ namespace hex::plugin::builtin {
const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true);
this->handleSelection(byteAddress, bytesPerCell, &bytes[x], cellHovered);
this->handleSelection(byteAddress, bytesPerCell, &bytes[x * bytesPerCell], cellHovered);
// Get byte foreground color
if (foregroundColor.has_value())
@@ -757,7 +774,7 @@ namespace hex::plugin::builtin {
// Draw cell content
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth((CharacterSize * this->m_currDataVisualizer->getMaxCharsPerCell()).x);
this->drawCell(byteAddress, &bytes[x], bytesPerCell, cellHovered);
this->drawCell(byteAddress, &bytes[x * bytesPerCell], bytesPerCell, cellHovered);
ImGui::PopItemWidth();
ImGui::PopStyleVar();
@@ -830,19 +847,21 @@ namespace hex::plugin::builtin {
} while (offset < this->m_bytesPerRow);
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
if (ImGui::BeginTable("##encoding_cell", encodingData.size(), ImGuiTableFlags_SizingFixedFit)) {
ImGui::PushID(y);
if (ImGui::BeginTable("##encoding_cell", encodingData.size(), ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoKeepColumnsVisible)) {
ImGui::TableNextRow();
for (const auto &[address, data] : encodingData) {
ImGui::TableNextColumn();
const auto cellStartPos = getCellPosition();
const auto cellSize = CharacterSize * data.advance;
const auto cellSize = ImGui::CalcTextSize(data.displayValue.c_str()) * ImVec2(1, 0) + ImVec2(0, CharacterSize.y);
const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true);
const auto x = address % this->m_bytesPerRow;
if (x < validBytes) {
auto [foregroundColor, backgroundColor] = cellColors[x];
auto [foregroundColor, backgroundColor] = cellColors[x / bytesPerCell];
// Draw highlights and selection
if (backgroundColor.has_value()) {
@@ -854,7 +873,9 @@ namespace hex::plugin::builtin {
this->drawSelectionFrame(x, y, address, 1, cellStartPos, cellSize);
}
ImGui::PushItemWidth(cellSize.x);
ImGui::TextFormattedColored(data.color, "{}", data.displayValue);
ImGui::PopItemWidth();
this->handleSelection(address, data.advance, &bytes[address % this->m_bytesPerRow], cellHovered);
}
@@ -863,6 +884,7 @@ namespace hex::plugin::builtin {
ImGui::EndTable();
}
ImGui::PopStyleVar();
ImGui::PopID();
}
@@ -908,11 +930,11 @@ namespace hex::plugin::builtin {
if (this->m_shouldJumpToSelection) {
this->m_shouldJumpToSelection = false;
const auto pageAddress = provider->getCurrentPageAddress() + provider->getBaseAddress();
auto newSelection = this->getSelection();
newSelection.address -= pageAddress;
provider->setCurrentPage(provider->getPageOfAddress(newSelection.address).value_or(0));
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (static_cast<long double>(newSelection.getStartAddress()) / this->m_bytesPerRow) * CharacterSize.y, 0.5);
const auto pageAddress = provider->getCurrentPageAddress() + provider->getBaseAddress();
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (static_cast<long double>(newSelection.getStartAddress() - pageAddress) / this->m_bytesPerRow) * CharacterSize.y, 0.5);
}
} else {
@@ -1222,7 +1244,7 @@ namespace hex::plugin::builtin {
});
// Open file
ShortcutManager::addShortcut(this, CTRL + Keys::O, [] {
ShortcutManager::addGlobalShortcut(CTRL + Keys::O, [] {
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
EventManager::post<RequestOpenFile>(path);
});
@@ -1253,7 +1275,6 @@ namespace hex::plugin::builtin {
if (region.size != 0) {
provider->setCurrentPage(page.value());
region.address -= provider->getBaseAddress() + provider->getCurrentPageAddress();
this->setSelection(region);
this->jumpToSelection();
}

View File

@@ -67,7 +67,7 @@ namespace hex::plugin::builtin {
return false;
}
static bool beginPatternTable(prv::Provider *&provider, const std::vector<std::shared_ptr<pl::Pattern>> &patterns, std::vector<std::shared_ptr<pl::Pattern>> &sortedPatterns) {
static bool beginPatternTable(prv::Provider *&provider, const std::vector<std::shared_ptr<pl::Pattern>> &patterns, std::vector<pl::Pattern*> &sortedPatterns) {
if (ImGui::BeginTable("##Patterntable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, 0, 0, ImGui::GetID("name"));
@@ -80,10 +80,13 @@ namespace hex::plugin::builtin {
auto sortSpecs = ImGui::TableGetSortSpecs();
if (sortSpecs->SpecsDirty || sortedPatterns.empty()) {
sortedPatterns = patterns;
sortedPatterns.clear();
std::transform(patterns.begin(), patterns.end(), std::back_inserter(sortedPatterns), [](const std::shared_ptr<pl::Pattern> &pattern) {
return pattern.get();
});
std::sort(sortedPatterns.begin(), sortedPatterns.end(), [&sortSpecs, &provider](const std::shared_ptr<pl::Pattern> &left, const std::shared_ptr<pl::Pattern> &right) -> bool {
return sortPatterns(provider, sortSpecs, left.get(), right.get());
std::sort(sortedPatterns.begin(), sortedPatterns.end(), [&sortSpecs, &provider](pl::Pattern *left, pl::Pattern *right) -> bool {
return sortPatterns(provider, sortSpecs, left, right);
});
for (auto &pattern : sortedPatterns)

View File

@@ -28,7 +28,7 @@ namespace hex::plugin::builtin {
langDef.mKeywords.insert(k);
static constexpr std::array builtInTypes = {
"u8", "u16", "u32", "u64", "u128", "s8", "s16", "s32", "s64", "s128", "float", "double", "char", "char16", "bool", "padding", "str", "auto"
"u8", "u16", "u24", "u32", "u48", "u64", "u96", "u128", "s8", "s16", "s24", "s32", "s48", "s64", "s96", "s128", "float", "double", "char", "char16", "bool", "padding", "str", "auto"
};
for (const auto name : builtInTypes) {
TextEditor::Identifier id;
@@ -93,9 +93,7 @@ namespace hex::plugin::builtin {
});
EventManager::subscribe<RequestSetPatternLanguageCode>(this, [this](const std::string &code) {
this->m_textEditor.SelectAll();
this->m_textEditor.Delete();
this->m_textEditor.InsertText(code);
this->m_textEditor.SetText(code);
});
EventManager::subscribe<EventFileLoaded>(this, [this](const std::fs::path &path) {
@@ -127,7 +125,7 @@ namespace hex::plugin::builtin {
std::error_code errorCode;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Patterns)) {
for (auto &entry : std::fs::directory_iterator(dir, errorCode)) {
for (auto &entry : std::fs::recursive_directory_iterator(dir, errorCode)) {
foundCorrectType = false;
if (!entry.is_regular_file())
continue;
@@ -185,7 +183,7 @@ namespace hex::plugin::builtin {
}
ContentRegistry::FileHandler::add({ ".hexpat", ".pat" }, [](const std::fs::path &path) -> bool {
fs::File file(path.string(), fs::File::Mode::Read);
fs::File file(path, fs::File::Mode::Read);
if (file.isValid()) {
EventManager::post<RequestSetPatternLanguageCode>(file.readString());
@@ -236,31 +234,44 @@ namespace hex::plugin::builtin {
if (this->m_runningEvaluators != 0)
return std::nullopt;
const auto pattern = ImHexApi::Provider::get()->getPatternLanguageRuntime().getPattern(address);
if (pattern != nullptr)
return pattern->getColor();
else
return std::nullopt;
std::optional<ImColor> color;
for (const auto &pattern : ImHexApi::Provider::get()->getPatternLanguageRuntime().getPatterns(address)) {
if (pattern->isHidden())
continue;
if (color.has_value())
color = ImAlphaBlendColors(*color, pattern->getColor());
else
color = pattern->getColor();
}
return color;
});
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
hex::unused(data, size);
auto pattern = ImHexApi::Provider::get()->getPatternLanguageRuntime().getPattern(address);
if (pattern != nullptr) {
auto patterns = ImHexApi::Provider::get()->getPatternLanguageRuntime().getPatterns(address);
if (!patterns.empty() && !std::all_of(patterns.begin(), patterns.end(), [](const auto &pattern) { return pattern->isHidden(); })) {
ImGui::BeginTooltip();
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
this->drawPatternTooltip(pattern);
for (const auto &pattern : patterns) {
if (pattern->isHidden())
continue;
auto tooltipColor = (pattern->getColor() & 0x00FF'FFFF) | 0x7000'0000;
ImGui::PushStyleColor(ImGuiCol_TableRowBg, tooltipColor);
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, tooltipColor);
ImGui::EndTable();
ImGui::PopStyleColor(2);
ImGui::PushID(pattern);
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
this->drawPatternTooltip(pattern);
ImGui::PushStyleColor(ImGuiCol_TableRowBg, tooltipColor);
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, tooltipColor);
ImGui::EndTable();
ImGui::PopStyleColor(2);
}
ImGui::PopID();
}
ImGui::EndTooltip();
}
@@ -558,25 +569,27 @@ namespace hex::plugin::builtin {
if (variable.outVariable) {
ImGui::TextUnformatted(pl::Token::literalToString(variable.value, true).c_str());
} else if (variable.inVariable) {
const std::string label { "##" + name };
if (pl::Token::isSigned(variable.type)) {
i64 value = hex::get_or<i128>(variable.value, 0);
ImGui::InputScalar("", ImGuiDataType_S64, &value);
ImGui::InputScalar(label.c_str(), ImGuiDataType_S64, &value);
variable.value = i128(value);
} else if (pl::Token::isUnsigned(variable.type)) {
u64 value = hex::get_or<u128>(variable.value, 0);
ImGui::InputScalar("", ImGuiDataType_U64, &value);
ImGui::InputScalar(label.c_str(), ImGuiDataType_U64, &value);
variable.value = u128(value);
} else if (pl::Token::isFloatingPoint(variable.type)) {
double value = hex::get_or<double>(variable.value, 0.0);
ImGui::InputScalar("", ImGuiDataType_Double, &value);
ImGui::InputScalar(label.c_str(), ImGuiDataType_Double, &value);
variable.value = value;
} else if (variable.type == pl::Token::ValueType::Boolean) {
bool value = hex::get_or<bool>(variable.value, false);
ImGui::Checkbox("", &value);
ImGui::Checkbox(label.c_str(), &value);
variable.value = value;
} else if (variable.type == pl::Token::ValueType::Character) {
char buffer[2];
ImGui::InputText("", buffer, 2);
ImGui::InputText(label.c_str(), buffer, 2);
variable.value = buffer[0];
}
}
@@ -619,7 +632,7 @@ namespace hex::plugin::builtin {
confirmButtons(
"hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [this] {
this->loadPatternFile(this->m_possiblePatternFiles[this->m_selectedPatternFile].string());
this->loadPatternFile(this->m_possiblePatternFiles[this->m_selectedPatternFile]);
ImGui::CloseCurrentPopup(); }, [] { ImGui::CloseCurrentPopup(); });
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
@@ -674,7 +687,7 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGui::TextFormatted("{}", pattern->getEndian() == std::endian::little ? "Little" : "Big");
if (auto comment = pattern->getComment(); comment.has_value()) {
if (const auto &comment = pattern->getComment(); comment.has_value()) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextFormatted("Comment: ");
@@ -717,7 +730,6 @@ namespace hex::plugin::builtin {
auto ast = this->m_parserRuntime->parseString(code);
this->m_patternVariables.clear();
this->m_patternTypes.clear();
if (ast) {
for (auto &node : *ast) {
@@ -752,7 +764,7 @@ namespace hex::plugin::builtin {
this->m_textEditor.SetErrorMarkers({});
this->m_console.clear();
this->clearPatterns();
ImHexApi::Provider::get()->getPatternLanguageRuntime().reset();
EventManager::post<EventHighlightingChanged>();

View File

@@ -191,7 +191,7 @@ namespace hex::plugin::builtin {
[](const char *includeName, const char *, const char *, void *userData) -> const char * {
auto currFilePath = static_cast<const char *>(userData);
fs::File file((std::fs::path(currFilePath).parent_path() / includeName).string(), fs::File::Mode::Read);
fs::File file(std::fs::path(currFilePath).parent_path() / includeName, fs::File::Mode::Read);
if (!file.isValid())
return nullptr;

View File

@@ -18,26 +18,23 @@
#include <nlohmann/json.hpp>
#include <romfs/romfs.hpp>
#include <fontawesome_font.h>
#include <codicons_font.h>
#include <fonts/fontawesome_font.h>
#include <fonts/codicons_font.h>
#include <list>
namespace hex::plugin::builtin {
static bool s_layoutConfigured = false;
static ImGui::Texture s_bannerTexture;
static std::string s_bannerTextureName;
static ImGui::Texture s_bannerTexture, s_backdropTexture;
static std::list<std::fs::path> s_recentFilePaths;
static std::fs::path s_safetyBackupPath;
static std::string s_tipOfTheDay;
static void initDefaultLayout() {
static void loadDefaultLayout() {
auto layouts = ContentRegistry::Interface::getLayouts();
if (!layouts.empty()) {
s_layoutConfigured = true;
for (auto &[viewName, view] : ContentRegistry::Views::getEntries()) {
view->getWindowOpenState() = false;
@@ -52,6 +49,14 @@ namespace hex::plugin::builtin {
}
}
static bool isAnyViewOpen() {
const auto &views = ContentRegistry::Views::getEntries();
return std::any_of(views.begin(), views.end(),
[](const std::pair<std::string, View*> &entry) {
return entry.second->getWindowOpenState();
});
}
static void drawPopups() {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size / 3, ImGuiCond_Appearing);
@@ -84,7 +89,7 @@ namespace hex::plugin::builtin {
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.builtin.welcome.safety_backup.restore"_lang, ImVec2(width / 3, 0))) {
ProjectFile::load(s_safetyBackupPath.string());
ProjectFile::load(s_safetyBackupPath);
ProjectFile::markDirty();
ProjectFile::clearProjectFilePath();
@@ -282,8 +287,32 @@ namespace hex::plugin::builtin {
drawPopups();
}
static void drawNoViewsBackground() {
if (isAnyViewOpen() && ImHexApi::Provider::isValid()) return;
if (ImGui::Begin("ImHexDockSpace")) {
static char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("ImHexMainDock"));
if (ImGui::Begin(title)) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10_scaled, 10_scaled));
if (ImGui::BeginChild("NoViewsBackground", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoScrollWithMouse)) {
auto imageSize = scaled(ImVec2(350, 350));
auto pos = (ImGui::GetContentRegionAvail() - imageSize) / 2;
ImGui::SetCursorPos(pos);
ImGui::Image(s_backdropTexture, imageSize);
}
ImGui::EndChild();
ImGui::PopStyleVar();
}
ImGui::End();
}
ImGui::End();
}
void createWelcomeScreen() {
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
(void)EventManager::subscribe<EventFrameBegin>(drawNoViewsBackground);
(void)EventManager::subscribe<EventSettingsChanged>([]() {
{
@@ -316,27 +345,17 @@ namespace hex::plugin::builtin {
if (targetFps.is_number())
ImHexApi::System::setTargetFPS(targetFps);
}
{
if (ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 0) == 1)
s_layoutConfigured = true;
else
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.launched", 1);
}
});
(void)EventManager::subscribe<RequestChangeTheme>([](u32 theme) {
auto changeBannerTexture = [&](const char newTexture[]) {
if (s_bannerTextureName == newTexture) {
return;
}
auto changeTexture = [&](const std::string &path, const ImGui::Texture &texture) {
auto textureData = romfs::get(path);
auto oldTexture = texture;
auto newTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(textureData.data()), textureData.size());
s_bannerTextureName = newTexture;
auto banner = romfs::get(newTexture);
auto oldBannerTexture = s_bannerTexture;
s_bannerTexture = ImGui::LoadImageFromMemory(reinterpret_cast<const ImU8 *>(banner.data()), banner.size());
if (oldTexture.valid()) { ImGui::UnloadImage(oldTexture); }
if (oldBannerTexture.valid()) { ImGui::UnloadImage(oldBannerTexture); }
return newTexture;
};
switch (theme) {
@@ -346,7 +365,8 @@ namespace hex::plugin::builtin {
ImGui::StyleColorsDark();
ImGui::StyleCustomColorsDark();
ImPlot::StyleColorsDark();
changeBannerTexture("banner_dark.png");
s_bannerTexture = changeTexture("banner_dark.png", s_bannerTexture);
s_backdropTexture = changeTexture("backdrop_dark.png", s_backdropTexture);
break;
}
@@ -355,7 +375,8 @@ namespace hex::plugin::builtin {
ImGui::StyleColorsLight();
ImGui::StyleCustomColorsLight();
ImPlot::StyleColorsLight();
changeBannerTexture("banner_light.png");
s_bannerTexture = changeTexture("banner_light.png", s_bannerTexture);
s_backdropTexture = changeTexture("backdrop_light.png", s_backdropTexture);
break;
}
@@ -364,7 +385,8 @@ namespace hex::plugin::builtin {
ImGui::StyleColorsClassic();
ImGui::StyleCustomColorsClassic();
ImPlot::StyleColorsClassic();
changeBannerTexture("banner_dark.png");
s_bannerTexture = changeTexture("banner_dark.png", s_bannerTexture);
s_backdropTexture = changeTexture("backdrop_dark.png", s_backdropTexture);
break;
}
@@ -409,12 +431,11 @@ namespace hex::plugin::builtin {
ContentRegistry::Settings::write("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files", recentFilesVector);
}
});
{
if (!s_layoutConfigured) {
initDefaultLayout();
}
}
EventManager::subscribe<EventProviderCreated>([](auto) {
if (!isAnyViewOpen())
loadDefaultLayout();
});
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1075, [&] {

View File

@@ -224,7 +224,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.view.hashes.type", "类型" },
{ "hex.builtin.view.hashes.result", "结果" },
{ "hex.builtin.view.hashes.remove", "移除哈希" },
{ "hex.builtin.view.hashes.hover_info", "将鼠标放在 Hex 编辑器的选区上,按住 SHIFT来查看其哈希。" },
{ "hex.builtin.view.hashes.hover_info", "将鼠标放在 Hex 编辑器的选区上,按住 SHIFT 来查看其哈希。" },
{ "hex.builtin.view.help.name", "帮助" },

View File

@@ -44,9 +44,13 @@ namespace hex {
void PatternDrawer::visit(pl::PatternBitfieldField& pattern) {
ImGui::TableNextRow();
createLeafNode(pattern);
ImGui::TableNextColumn();
drawNameColumn(pattern);
makeSelectable(pattern);
drawCommentTooltip(pattern);
ImGui::SameLine();
drawNameColumn(pattern);
drawColorColumn(pattern);
auto byteAddr = pattern.getOffset() + pattern.getBitOffset() / 8;
@@ -167,8 +171,9 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternString& pattern) {
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
}
if (pattern.getSize() > 0)
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
}
void PatternDrawer::visit(pl::PatternStruct& pattern) {
bool open = true;
@@ -237,9 +242,8 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternWideString& pattern) {
std::string utf8String = pattern.getValue();
this->createDefaultEntry(pattern, pattern.getFormattedValue(), utf8String);
if (pattern.getSize() > 0)
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
}
void PatternDrawer::createDefaultEntry(const pl::Pattern &pattern, const std::string &value, pl::Token::Literal &&literal) const {

View File

@@ -8,8 +8,8 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fontawesome_font.h>
#include <codicons_font.h>
#include <fonts/fontawesome_font.h>
#include <fonts/codicons_font.h>
namespace hex::plugin::windows {

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB