mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
Add support for Qt5
This commit is contained in:
104
CMakeLists.txt
104
CMakeLists.txt
@@ -7,9 +7,25 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Widgets PrintSupport Svg Concurrent Network)
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
# Find Qt6 or Qt5 (config mode first, then FindQt5.cmake module for auto-download)
|
||||||
|
set(_QT_COMPONENTS Core Widgets PrintSupport Svg Concurrent Network)
|
||||||
|
find_package(QT NAMES Qt6 Qt5 COMPONENTS ${_QT_COMPONENTS} QUIET)
|
||||||
|
if(NOT QT_FOUND)
|
||||||
|
find_package(Qt5 REQUIRED COMPONENTS ${_QT_COMPONENTS})
|
||||||
|
set(QT_VERSION_MAJOR 5)
|
||||||
|
endif()
|
||||||
|
set(QT Qt${QT_VERSION_MAJOR})
|
||||||
|
message(STATUS "Using ${QT}: ${${QT}_DIR}")
|
||||||
|
|
||||||
|
# Qt5 on Windows needs WinExtras for HICON conversion
|
||||||
|
set(_QT_WINEXTRAS "")
|
||||||
|
if(QT_VERSION_MAJOR EQUAL 5 AND WIN32)
|
||||||
|
find_package(Qt5 REQUIRED COMPONENTS WinExtras)
|
||||||
|
set(_QT_WINEXTRAS Qt5::WinExtras)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(QScintilla REQUIRED)
|
find_package(QScintilla REQUIRED)
|
||||||
|
|
||||||
add_executable(ReclassX
|
add_executable(ReclassX
|
||||||
@@ -49,35 +65,30 @@ add_executable(ReclassX
|
|||||||
target_include_directories(ReclassX PRIVATE src)
|
target_include_directories(ReclassX PRIVATE src)
|
||||||
|
|
||||||
target_link_libraries(ReclassX PRIVATE
|
target_link_libraries(ReclassX PRIVATE
|
||||||
Qt6::Widgets
|
${QT}::Widgets
|
||||||
Qt6::PrintSupport
|
${QT}::PrintSupport
|
||||||
Qt6::Svg
|
${QT}::Svg
|
||||||
Qt6::Concurrent
|
${QT}::Concurrent
|
||||||
Qt6::Network
|
${QT}::Network
|
||||||
QScintilla::QScintilla
|
QScintilla::QScintilla
|
||||||
|
${_QT_WINEXTRAS}
|
||||||
)
|
)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(ReclassX PRIVATE dbghelp psapi)
|
target_link_libraries(ReclassX PRIVATE dbghelp psapi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(rcx-mcp-stdio tools/rcx-mcp-stdio.cpp)
|
add_executable(rcx-mcp-stdio tools/rcx-mcp-stdio.cpp)
|
||||||
target_link_libraries(rcx-mcp-stdio PRIVATE Qt6::Core Qt6::Network)
|
target_link_libraries(rcx-mcp-stdio PRIVATE ${QT}::Core ${QT}::Network)
|
||||||
|
|
||||||
|
include(deploy)
|
||||||
|
|
||||||
add_custom_target(screenshot ALL
|
add_custom_target(screenshot ALL
|
||||||
COMMAND ReclassX --screenshot ${CMAKE_BINARY_DIR}/screenshot.png
|
COMMAND ReclassX --screenshot ${CMAKE_BINARY_DIR}/screenshot.png
|
||||||
DEPENDS ReclassX
|
DEPENDS ReclassX deploy
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
COMMENT "Capturing UI screenshot with class open..."
|
COMMENT "Capturing UI screenshot with class open..."
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(copy_demo ALL
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
|
||||||
${CMAKE_BINARY_DIR}/demo.rcx
|
|
||||||
${CMAKE_SOURCE_DIR}/src/examples/demo.rcx
|
|
||||||
DEPENDS screenshot
|
|
||||||
COMMENT "Copying demo.rcx to src/examples..."
|
|
||||||
)
|
|
||||||
|
|
||||||
set(_combine_script "${CMAKE_BINARY_DIR}/combine_sources.cmake")
|
set(_combine_script "${CMAKE_BINARY_DIR}/combine_sources.cmake")
|
||||||
file(WRITE ${_combine_script} "
|
file(WRITE ${_combine_script} "
|
||||||
set(_out \"${CMAKE_BINARY_DIR}/h_cpp_combined.txt\")
|
set(_out \"${CMAKE_BINARY_DIR}/h_cpp_combined.txt\")
|
||||||
@@ -107,46 +118,47 @@ add_custom_target(combined ALL
|
|||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Test)
|
find_package(${QT} REQUIRED COMPONENTS Test)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
add_executable(test_core tests/test_core.cpp src/format.cpp src/compose.cpp)
|
add_executable(test_core tests/test_core.cpp src/format.cpp src/compose.cpp)
|
||||||
target_include_directories(test_core PRIVATE src)
|
target_include_directories(test_core PRIVATE src)
|
||||||
target_link_libraries(test_core PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_core PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_core COMMAND test_core)
|
add_test(NAME test_core COMMAND test_core)
|
||||||
|
|
||||||
add_executable(test_format tests/test_format.cpp src/format.cpp)
|
add_executable(test_format tests/test_format.cpp src/format.cpp)
|
||||||
target_include_directories(test_format PRIVATE src)
|
target_include_directories(test_format PRIVATE src)
|
||||||
target_link_libraries(test_format PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_format PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_format COMMAND test_format)
|
add_test(NAME test_format COMMAND test_format)
|
||||||
|
|
||||||
add_executable(test_compose tests/test_compose.cpp src/compose.cpp src/format.cpp)
|
add_executable(test_compose tests/test_compose.cpp src/compose.cpp src/format.cpp)
|
||||||
target_include_directories(test_compose PRIVATE src)
|
target_include_directories(test_compose PRIVATE src)
|
||||||
target_link_libraries(test_compose PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_compose PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_compose COMMAND test_compose)
|
add_test(NAME test_compose COMMAND test_compose)
|
||||||
|
|
||||||
add_executable(test_editor tests/test_editor.cpp src/editor.cpp src/compose.cpp src/format.cpp src/providerregistry.cpp
|
add_executable(test_editor tests/test_editor.cpp src/editor.cpp src/compose.cpp src/format.cpp src/providerregistry.cpp
|
||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_editor PRIVATE src)
|
target_include_directories(test_editor PRIVATE src)
|
||||||
target_link_libraries(test_editor PRIVATE
|
target_link_libraries(test_editor PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
add_test(NAME test_editor COMMAND test_editor)
|
add_test(NAME test_editor COMMAND test_editor)
|
||||||
|
|
||||||
add_executable(test_provider tests/test_provider.cpp)
|
add_executable(test_provider tests/test_provider.cpp)
|
||||||
target_include_directories(test_provider PRIVATE src)
|
target_include_directories(test_provider PRIVATE src)
|
||||||
target_link_libraries(test_provider PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_provider PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_provider COMMAND test_provider)
|
add_test(NAME test_provider COMMAND test_provider)
|
||||||
|
|
||||||
add_executable(test_command_row tests/test_command_row.cpp)
|
add_executable(test_command_row tests/test_command_row.cpp)
|
||||||
target_include_directories(test_command_row PRIVATE src)
|
target_include_directories(test_command_row PRIVATE src)
|
||||||
target_link_libraries(test_command_row PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_command_row PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_command_row COMMAND test_command_row)
|
add_test(NAME test_command_row COMMAND test_command_row)
|
||||||
|
|
||||||
add_executable(test_provider_getSymbol tests/test_provider_getSymbol.cpp)
|
add_executable(test_provider_getSymbol tests/test_provider_getSymbol.cpp)
|
||||||
target_include_directories(test_provider_getSymbol PRIVATE src)
|
target_include_directories(test_provider_getSymbol PRIVATE src)
|
||||||
target_link_libraries(test_provider_getSymbol PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_provider_getSymbol PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
target_compile_definitions(test_provider_getSymbol PRIVATE _WIN32)
|
||||||
target_link_libraries(test_provider_getSymbol PRIVATE psapi)
|
target_link_libraries(test_provider_getSymbol PRIVATE psapi)
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME test_provider_getSymbol COMMAND test_provider_getSymbol)
|
add_test(NAME test_provider_getSymbol COMMAND test_provider_getSymbol)
|
||||||
@@ -158,10 +170,10 @@ if(BUILD_TESTING)
|
|||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_controller PRIVATE src)
|
target_include_directories(test_controller PRIVATE src)
|
||||||
target_link_libraries(test_controller PRIVATE
|
target_link_libraries(test_controller PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Concurrent Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Concurrent ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(test_controller PRIVATE dbghelp psapi)
|
target_link_libraries(test_controller PRIVATE dbghelp psapi ${_QT_WINEXTRAS})
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME test_controller COMMAND test_controller)
|
add_test(NAME test_controller COMMAND test_controller)
|
||||||
|
|
||||||
@@ -172,17 +184,17 @@ if(BUILD_TESTING)
|
|||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_validation PRIVATE src)
|
target_include_directories(test_validation PRIVATE src)
|
||||||
target_link_libraries(test_validation PRIVATE
|
target_link_libraries(test_validation PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Concurrent Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Concurrent ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(test_validation PRIVATE dbghelp psapi)
|
target_link_libraries(test_validation PRIVATE dbghelp psapi ${_QT_WINEXTRAS})
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME test_validation COMMAND test_validation)
|
add_test(NAME test_validation COMMAND test_validation)
|
||||||
|
|
||||||
add_executable(test_generator tests/test_generator.cpp
|
add_executable(test_generator tests/test_generator.cpp
|
||||||
src/generator.cpp src/compose.cpp src/format.cpp)
|
src/generator.cpp src/compose.cpp src/format.cpp)
|
||||||
target_include_directories(test_generator PRIVATE src)
|
target_include_directories(test_generator PRIVATE src)
|
||||||
target_link_libraries(test_generator PRIVATE Qt6::Core Qt6::Test)
|
target_link_libraries(test_generator PRIVATE ${QT}::Core ${QT}::Test)
|
||||||
add_test(NAME test_generator COMMAND test_generator)
|
add_test(NAME test_generator COMMAND test_generator)
|
||||||
|
|
||||||
add_executable(test_context_menu tests/test_context_menu.cpp
|
add_executable(test_context_menu tests/test_context_menu.cpp
|
||||||
@@ -192,10 +204,10 @@ if(BUILD_TESTING)
|
|||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_context_menu PRIVATE src)
|
target_include_directories(test_context_menu PRIVATE src)
|
||||||
target_link_libraries(test_context_menu PRIVATE
|
target_link_libraries(test_context_menu PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Concurrent Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Concurrent ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(test_context_menu PRIVATE dbghelp psapi)
|
target_link_libraries(test_context_menu PRIVATE dbghelp psapi ${_QT_WINEXTRAS})
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME test_context_menu COMMAND test_context_menu)
|
add_test(NAME test_context_menu COMMAND test_context_menu)
|
||||||
|
|
||||||
@@ -203,7 +215,7 @@ if(BUILD_TESTING)
|
|||||||
src/generator.cpp src/compose.cpp src/format.cpp)
|
src/generator.cpp src/compose.cpp src/format.cpp)
|
||||||
target_include_directories(test_rendered_view PRIVATE src)
|
target_include_directories(test_rendered_view PRIVATE src)
|
||||||
target_link_libraries(test_rendered_view PRIVATE
|
target_link_libraries(test_rendered_view PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
add_test(NAME test_rendered_view COMMAND test_rendered_view)
|
add_test(NAME test_rendered_view COMMAND test_rendered_view)
|
||||||
|
|
||||||
@@ -214,10 +226,10 @@ if(BUILD_TESTING)
|
|||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_new_features PRIVATE src)
|
target_include_directories(test_new_features PRIVATE src)
|
||||||
target_link_libraries(test_new_features PRIVATE
|
target_link_libraries(test_new_features PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Concurrent Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Concurrent ${QT}::Test
|
||||||
QScintilla::QScintilla)
|
QScintilla::QScintilla)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(test_new_features PRIVATE dbghelp psapi)
|
target_link_libraries(test_new_features PRIVATE dbghelp psapi ${_QT_WINEXTRAS})
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME test_new_features COMMAND test_new_features)
|
add_test(NAME test_new_features COMMAND test_new_features)
|
||||||
|
|
||||||
@@ -228,14 +240,30 @@ if(BUILD_TESTING)
|
|||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_type_selector PRIVATE src)
|
target_include_directories(test_type_selector PRIVATE src)
|
||||||
target_link_libraries(test_type_selector PRIVATE
|
target_link_libraries(test_type_selector PRIVATE
|
||||||
Qt6::Widgets Qt6::PrintSupport Qt6::Concurrent Qt6::Test
|
${QT}::Widgets ${QT}::PrintSupport ${QT}::Concurrent ${QT}::Test
|
||||||
QScintilla::QScintilla dbghelp psapi)
|
QScintilla::QScintilla)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(test_type_selector PRIVATE dbghelp psapi ${_QT_WINEXTRAS})
|
||||||
|
endif()
|
||||||
add_test(NAME test_type_selector COMMAND test_type_selector)
|
add_test(NAME test_type_selector COMMAND test_type_selector)
|
||||||
|
|
||||||
add_executable(test_theme tests/test_theme.cpp
|
add_executable(test_theme tests/test_theme.cpp
|
||||||
src/themes/theme.cpp src/themes/thememanager.cpp)
|
src/themes/theme.cpp src/themes/thememanager.cpp)
|
||||||
target_include_directories(test_theme PRIVATE src)
|
target_include_directories(test_theme PRIVATE src)
|
||||||
target_link_libraries(test_theme PRIVATE Qt6::Widgets Qt6::Test)
|
target_link_libraries(test_theme PRIVATE ${QT}::Widgets ${QT}::Test)
|
||||||
add_test(NAME test_theme COMMAND test_theme)
|
add_test(NAME test_theme COMMAND test_theme)
|
||||||
|
|
||||||
|
# Deploy Qt runtime DLLs for tests (run windeployqt on a representative test exe
|
||||||
|
# that links the broadest set of Qt modules; all test exes share the same output dir)
|
||||||
|
if(TARGET ${QT}::windeployqt)
|
||||||
|
add_custom_target(deploy_tests ALL
|
||||||
|
COMMAND $<TARGET_FILE:${QT}::windeployqt>
|
||||||
|
--no-compiler-runtime --no-translations
|
||||||
|
--no-opengl-sw --no-system-d3d-compiler
|
||||||
|
$<TARGET_FILE:test_controller>
|
||||||
|
DEPENDS test_controller
|
||||||
|
COMMENT "Deploying Qt runtime DLLs for tests..."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(plugins/ProcessMemory)
|
add_subdirectory(plugins/ProcessMemory)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
set(_QSCI_ROOT "${CMAKE_SOURCE_DIR}/third_party/qscintilla")
|
set(_QSCI_ROOT "${CMAKE_SOURCE_DIR}/third_party/qscintilla")
|
||||||
|
|
||||||
|
# Try to find a pre-built library first
|
||||||
find_path(QScintilla_INCLUDE_DIR
|
find_path(QScintilla_INCLUDE_DIR
|
||||||
NAMES Qsci/qsciscintilla.h
|
NAMES Qsci/qsciscintilla.h
|
||||||
PATHS "${_QSCI_ROOT}/src" "${_QSCI_ROOT}/include"
|
PATHS "${_QSCI_ROOT}/src" "${_QSCI_ROOT}/include"
|
||||||
@@ -7,7 +8,10 @@ find_path(QScintilla_INCLUDE_DIR
|
|||||||
)
|
)
|
||||||
|
|
||||||
find_library(QScintilla_LIBRARY
|
find_library(QScintilla_LIBRARY
|
||||||
NAMES qscintilla2_qt6 libqscintilla2_qt6
|
NAMES
|
||||||
|
qscintilla2_qt${QT_VERSION_MAJOR} libqscintilla2_qt${QT_VERSION_MAJOR}
|
||||||
|
qscintilla2_qt6 libqscintilla2_qt6
|
||||||
|
qscintilla2_qt5 libqscintilla2_qt5
|
||||||
PATHS
|
PATHS
|
||||||
"${_QSCI_ROOT}/src/release"
|
"${_QSCI_ROOT}/src/release"
|
||||||
"${_QSCI_ROOT}/src"
|
"${_QSCI_ROOT}/src"
|
||||||
@@ -15,13 +19,11 @@ find_library(QScintilla_LIBRARY
|
|||||||
NO_DEFAULT_PATH
|
NO_DEFAULT_PATH
|
||||||
)
|
)
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
if(QScintilla_LIBRARY AND QScintilla_INCLUDE_DIR)
|
||||||
find_package_handle_standard_args(QScintilla DEFAULT_MSG
|
# Use pre-built library
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(QScintilla DEFAULT_MSG
|
||||||
QScintilla_LIBRARY QScintilla_INCLUDE_DIR)
|
QScintilla_LIBRARY QScintilla_INCLUDE_DIR)
|
||||||
|
|
||||||
if(QScintilla_FOUND)
|
|
||||||
set(QScintilla_INCLUDE_DIRS ${QScintilla_INCLUDE_DIR})
|
|
||||||
set(QScintilla_LIBRARIES ${QScintilla_LIBRARY})
|
|
||||||
if(NOT TARGET QScintilla::QScintilla)
|
if(NOT TARGET QScintilla::QScintilla)
|
||||||
add_library(QScintilla::QScintilla STATIC IMPORTED)
|
add_library(QScintilla::QScintilla STATIC IMPORTED)
|
||||||
set_target_properties(QScintilla::QScintilla PROPERTIES
|
set_target_properties(QScintilla::QScintilla PROPERTIES
|
||||||
@@ -29,4 +31,118 @@ if(QScintilla_FOUND)
|
|||||||
INTERFACE_INCLUDE_DIRECTORIES "${QScintilla_INCLUDE_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${QScintilla_INCLUDE_DIR}"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
elseif(EXISTS "${_QSCI_ROOT}/src/qsciscintilla.cpp")
|
||||||
|
# Build from source
|
||||||
|
message(STATUS "Building QScintilla from source")
|
||||||
|
|
||||||
|
file(GLOB _QSCI_LEXER_SOURCES "${_QSCI_ROOT}/scintilla/lexers/*.cpp")
|
||||||
|
file(GLOB _QSCI_LEXLIB_SOURCES "${_QSCI_ROOT}/scintilla/lexlib/*.cpp")
|
||||||
|
file(GLOB _QSCI_SCI_SOURCES "${_QSCI_ROOT}/scintilla/src/*.cpp")
|
||||||
|
file(GLOB _QSCI_HEADERS "${_QSCI_ROOT}/src/Qsci/*.h")
|
||||||
|
|
||||||
|
set(_QSCI_QT_SOURCES
|
||||||
|
"${_QSCI_ROOT}/src/qsciscintilla.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qsciscintillabase.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qsciabstractapis.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qsciapis.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscicommand.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscicommandset.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscidocument.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexer.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerasm.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexeravs.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerbash.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerbatch.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercmake.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercoffeescript.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercpp.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercsharp.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercss.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexercustom.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerd.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerdiff.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexeredifact.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerfortran.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerfortran77.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerhex.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerhtml.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexeridl.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerintelhex.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerjava.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerjavascript.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerjson.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerlua.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexermakefile.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexermarkdown.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexermasm.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexermatlab.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexernasm.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexeroctave.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerpascal.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerperl.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerpostscript.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerpo.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerpov.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerproperties.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerpython.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerruby.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerspice.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexersql.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexersrec.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexertcl.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexertekhex.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexertex.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerverilog.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexervhdl.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexerxml.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscilexeryaml.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscimacro.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qsciprinter.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscistyle.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/qscistyledtext.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/InputMethod.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/ListBoxQt.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/PlatQt.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/SciAccessibility.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/SciClasses.cpp"
|
||||||
|
"${_QSCI_ROOT}/src/ScintillaQt.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(qscintilla2 STATIC
|
||||||
|
${_QSCI_QT_SOURCES}
|
||||||
|
${_QSCI_HEADERS}
|
||||||
|
${_QSCI_LEXER_SOURCES}
|
||||||
|
${_QSCI_LEXLIB_SOURCES}
|
||||||
|
${_QSCI_SCI_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(qscintilla2 PUBLIC
|
||||||
|
"${_QSCI_ROOT}/src"
|
||||||
|
)
|
||||||
|
target_include_directories(qscintilla2 PRIVATE
|
||||||
|
"${_QSCI_ROOT}/scintilla/include"
|
||||||
|
"${_QSCI_ROOT}/scintilla/lexlib"
|
||||||
|
"${_QSCI_ROOT}/scintilla/src"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(qscintilla2 PRIVATE
|
||||||
|
SCINTILLA_QT
|
||||||
|
SCI_LEXER
|
||||||
|
INCLUDE_DEPRECATED_FEATURES
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(qscintilla2 PUBLIC
|
||||||
|
${QT}::Widgets
|
||||||
|
${QT}::PrintSupport
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(qscintilla2 PROPERTIES AUTOMOC ON)
|
||||||
|
|
||||||
|
add_library(QScintilla::QScintilla ALIAS qscintilla2)
|
||||||
|
set(QScintilla_FOUND TRUE)
|
||||||
|
else()
|
||||||
|
set(QScintilla_FOUND FALSE)
|
||||||
|
if(QScintilla_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could NOT find QScintilla (missing source and pre-built library)")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
36
cmake/FindQt5.cmake
Normal file
36
cmake/FindQt5.cmake
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Documentation: https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#find-modules
|
||||||
|
|
||||||
|
# Always try config mode for the requested components (handles repeated calls)
|
||||||
|
find_package(Qt5 COMPONENTS ${Qt5_FIND_COMPONENTS} QUIET CONFIG)
|
||||||
|
|
||||||
|
if(Qt5_FOUND)
|
||||||
|
if(NOT Qt5_FIND_QUIETLY)
|
||||||
|
message(STATUS "Qt5 found: ${Qt5_DIR}")
|
||||||
|
endif()
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(Qt5_FIND_REQUIRED AND WIN32)
|
||||||
|
message(STATUS "Downloading Qt5...")
|
||||||
|
# Fix warnings about DOWNLOAD_EXTRACT_TIMESTAMP
|
||||||
|
if(POLICY CMP0135)
|
||||||
|
cmake_policy(SET CMP0135 NEW)
|
||||||
|
endif()
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_QUIET OFF)
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
FetchContent_Declare(Qt5
|
||||||
|
URL "https://github.com/x64dbg/deps/releases/download/2025.07.02/qt5.12.12-msvc2017_64.7z"
|
||||||
|
URL_HASH SHA256=770490bf09514982c8192ebde9a1fac8821108ba42b021f167bac54e85ada48a
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
FetchContent_Declare(Qt5
|
||||||
|
URL "https://github.com/x64dbg/deps/releases/download/2025.07.02/qt5.12.12-msvc2017.7z"
|
||||||
|
URL_HASH SHA256=3ff2a58e5ed772be475643cd7bb2df3e5499d7169d794ddf1ed5df5c5e862cb6
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
FetchContent_MakeAvailable(Qt5)
|
||||||
|
unset(FETCHCONTENT_QUIET)
|
||||||
|
set(Qt5_ROOT ${qt5_SOURCE_DIR})
|
||||||
|
find_package(Qt5 COMPONENTS ${Qt5_FIND_COMPONENTS} CONFIG REQUIRED)
|
||||||
|
endif()
|
||||||
82
cmake/deploy.cmake
Normal file
82
cmake/deploy.cmake
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# cmake/deploy.cmake - Dual-mode script for deploying Qt runtime DLLs
|
||||||
|
#
|
||||||
|
# Script mode: cmake -P deploy.cmake <target_exe> <windeployqt>
|
||||||
|
# Include mode: include(deploy) from CMakeLists.txt (creates "deploy" target)
|
||||||
|
|
||||||
|
if(CMAKE_SCRIPT_MODE_FILE)
|
||||||
|
set(TARGET_EXE ${CMAKE_ARGV3})
|
||||||
|
set(WINDEPLOYQT ${CMAKE_ARGV4})
|
||||||
|
get_filename_component(TARGET_DIR ${TARGET_EXE} DIRECTORY)
|
||||||
|
|
||||||
|
# Skip if already deployed for this build
|
||||||
|
if(EXISTS "${TARGET_DIR}/.qt_deployed")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Running windeployqt on ${TARGET_EXE}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${WINDEPLOYQT}
|
||||||
|
--pdb
|
||||||
|
--no-compiler-runtime
|
||||||
|
--no-translations
|
||||||
|
--no-opengl-sw
|
||||||
|
--no-system-d3d-compiler
|
||||||
|
--force
|
||||||
|
${TARGET_EXE}
|
||||||
|
RESULT_VARIABLE _result
|
||||||
|
)
|
||||||
|
|
||||||
|
if(_result EQUAL 0)
|
||||||
|
file(WRITE "${TARGET_DIR}/.qt_deployed" "")
|
||||||
|
message(STATUS "windeployqt completed successfully")
|
||||||
|
else()
|
||||||
|
message(WARNING "windeployqt failed with exit code ${_result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ── Include mode: configure the deploy target ──
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Discover windeployqt from qmake
|
||||||
|
if(NOT TARGET ${QT}::windeployqt AND TARGET ${QT}::qmake)
|
||||||
|
get_target_property(_qt_qmake_location ${QT}::qmake IMPORTED_LOCATION)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${_qt_qmake_location}" -query QT_INSTALL_PREFIX
|
||||||
|
RESULT_VARIABLE _return_code
|
||||||
|
OUTPUT_VARIABLE _qt_install_prefix
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_windeployqt "${_qt_install_prefix}/bin/windeployqt.exe")
|
||||||
|
if(EXISTS ${_windeployqt})
|
||||||
|
add_executable(${QT}::windeployqt IMPORTED)
|
||||||
|
set_target_properties(${QT}::windeployqt PROPERTIES
|
||||||
|
IMPORTED_LOCATION ${_windeployqt}
|
||||||
|
)
|
||||||
|
message(STATUS "Found windeployqt: ${_windeployqt}")
|
||||||
|
else()
|
||||||
|
message(WARNING "windeployqt not found at ${_windeployqt}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TARGET ${QT}::windeployqt)
|
||||||
|
add_custom_target(deploy
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/deploy.cmake
|
||||||
|
$<TARGET_FILE:ReclassX>
|
||||||
|
$<TARGET_FILE:${QT}::windeployqt>
|
||||||
|
DEPENDS ReclassX
|
||||||
|
COMMENT "Deploying Qt runtime DLLs..."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Force re-deploy on rebuild
|
||||||
|
set_target_properties(deploy PROPERTIES
|
||||||
|
ADDITIONAL_CLEAN_FILES $<TARGET_FILE_DIR:ReclassX>/.qt_deployed
|
||||||
|
)
|
||||||
|
endif()
|
||||||
@@ -4,8 +4,7 @@ project(ProcessMemoryPlugin LANGUAGES CXX)
|
|||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Find Qt
|
# Qt is found by the parent project; QT variable (Qt5 or Qt6) is inherited
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Widgets)
|
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
@@ -24,7 +23,7 @@ set(PLUGIN_SOURCES
|
|||||||
add_library(ProcessMemoryPlugin SHARED ${PLUGIN_SOURCES})
|
add_library(ProcessMemoryPlugin SHARED ${PLUGIN_SOURCES})
|
||||||
|
|
||||||
# Link Qt
|
# Link Qt
|
||||||
target_link_libraries(ProcessMemoryPlugin PRIVATE Qt6::Widgets)
|
target_link_libraries(ProcessMemoryPlugin PRIVATE ${QT}::Widgets ${_QT_WINEXTRAS})
|
||||||
|
|
||||||
# Platform-specific linking
|
# Platform-specific linking
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(_WIN32)
|
||||||
|
#include <QtWin>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -469,7 +472,11 @@ QVector<PluginProcessInfo> ProcessMemoryPlugin::enumerateProcesses()
|
|||||||
SHFILEINFOW sfi = {};
|
SHFILEINFOW sfi = {};
|
||||||
if (SHGetFileInfoW(path, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON)) {
|
if (SHGetFileInfoW(path, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON)) {
|
||||||
if (sfi.hIcon) {
|
if (sfi.hIcon) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QPixmap pixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon));
|
QPixmap pixmap = QPixmap::fromImage(QImage::fromHICON(sfi.hIcon));
|
||||||
|
#else
|
||||||
|
QPixmap pixmap = QtWin::fromHICON(sfi.hIcon);
|
||||||
|
#endif
|
||||||
info.icon = QIcon(pixmap);
|
info.icon = QIcon(pixmap);
|
||||||
DestroyIcon(sfi.hIcon);
|
DestroyIcon(sfi.hIcon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ static QString crumbFor(const rcx::NodeTree& t, uint64_t nodeId) {
|
|||||||
}
|
}
|
||||||
std::reverse(parts.begin(), parts.end());
|
std::reverse(parts.begin(), parts.end());
|
||||||
if (parts.size() > 4)
|
if (parts.size() > 4)
|
||||||
parts = {parts.front(), QStringLiteral("\u2026"), parts[parts.size() - 2], parts.back()};
|
parts = QStringList{parts.front(), QStringLiteral("\u2026"), parts[parts.size() - 2], parts.back()};
|
||||||
return parts.join(QStringLiteral(" \u00B7 "));
|
return parts.join(QStringLiteral(" \u00B7 "));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,7 +863,7 @@ void RcxController::applyCommand(const Command& command, bool isUndo) {
|
|||||||
} else if constexpr (std::is_same_v<T, cmd::WriteBytes>) {
|
} else if constexpr (std::is_same_v<T, cmd::WriteBytes>) {
|
||||||
const QByteArray& bytes = isUndo ? c.oldBytes : c.newBytes;
|
const QByteArray& bytes = isUndo ? c.oldBytes : c.newBytes;
|
||||||
if (!m_doc->provider->writeBytes(c.addr, bytes))
|
if (!m_doc->provider->writeBytes(c.addr, bytes))
|
||||||
qWarning() << "WriteBytes failed at address" << Qt::hex << c.addr;
|
qWarning() << "WriteBytes failed at address" << QString::number(c.addr, 16);
|
||||||
// Patch snapshot so compose sees the new value immediately
|
// Patch snapshot so compose sees the new value immediately
|
||||||
if (m_snapshotProv)
|
if (m_snapshotProv)
|
||||||
m_snapshotProv->patchSnapshot(c.addr, bytes.constData(), bytes.size());
|
m_snapshotProv->patchSnapshot(c.addr, bytes.constData(), bytes.size());
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ enum class NodeKind : uint8_t {
|
|||||||
Struct, Array
|
Struct, Array
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace rcx (temporarily close for qHash)
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
inline uint qHash(rcx::NodeKind key, uint seed = 0) { return ::qHash(static_cast<uint8_t>(key), seed); }
|
||||||
|
#endif
|
||||||
|
namespace rcx { // reopen
|
||||||
|
|
||||||
// ── Kind flags (replaces repeated Hex/Padding switches) ──
|
// ── Kind flags (replaces repeated Hex/Padding switches) ──
|
||||||
|
|
||||||
enum KindFlags : uint32_t {
|
enum KindFlags : uint32_t {
|
||||||
|
|||||||
28
src/main.cpp
28
src/main.cpp
@@ -239,23 +239,23 @@ QIcon MainWindow::makeIcon(const QString& svgPath) {
|
|||||||
void MainWindow::createMenus() {
|
void MainWindow::createMenus() {
|
||||||
// File
|
// File
|
||||||
auto* file = menuBar()->addMenu("&File");
|
auto* file = menuBar()->addMenu("&File");
|
||||||
file->addAction("&New", QKeySequence::New, this, &MainWindow::newDocument);
|
file->addAction("&New", this, &MainWindow::newDocument, QKeySequence::New);
|
||||||
file->addAction("New &Tab", QKeySequence(Qt::CTRL | Qt::Key_T), this, &MainWindow::newFile);
|
file->addAction("New &Tab", this, &MainWindow::newFile, QKeySequence(Qt::CTRL | Qt::Key_T));
|
||||||
file->addAction(makeIcon(":/vsicons/folder-opened.svg"), "&Open...", QKeySequence::Open, this, &MainWindow::openFile);
|
file->addAction(makeIcon(":/vsicons/folder-opened.svg"), "&Open...", this, &MainWindow::openFile, QKeySequence::Open);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
file->addAction(makeIcon(":/vsicons/save.svg"), "&Save", QKeySequence::Save, this, &MainWindow::saveFile);
|
file->addAction(makeIcon(":/vsicons/save.svg"), "&Save", this, &MainWindow::saveFile, QKeySequence::Save);
|
||||||
file->addAction(makeIcon(":/vsicons/save-as.svg"), "Save &As...", QKeySequence::SaveAs, this, &MainWindow::saveFileAs);
|
file->addAction(makeIcon(":/vsicons/save-as.svg"), "Save &As...", this, &MainWindow::saveFileAs, QKeySequence::SaveAs);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
file->addAction(makeIcon(":/vsicons/export.svg"), "Export &C++ Header...", this, &MainWindow::exportCpp);
|
file->addAction(makeIcon(":/vsicons/export.svg"), "Export &C++ Header...", this, &MainWindow::exportCpp);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
m_mcpAction = file->addAction("Start &MCP Server", this, &MainWindow::toggleMcp);
|
m_mcpAction = file->addAction("Start &MCP Server", this, &MainWindow::toggleMcp);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
file->addAction(makeIcon(":/vsicons/close.svg"), "E&xit", QKeySequence(Qt::Key_Close), this, &QMainWindow::close);
|
file->addAction(makeIcon(":/vsicons/close.svg"), "E&xit", this, &QMainWindow::close, QKeySequence(Qt::Key_Close));
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
auto* edit = menuBar()->addMenu("&Edit");
|
auto* edit = menuBar()->addMenu("&Edit");
|
||||||
edit->addAction(makeIcon(":/vsicons/arrow-left.svg"), "&Undo", QKeySequence::Undo, this, &MainWindow::undo);
|
edit->addAction(makeIcon(":/vsicons/arrow-left.svg"), "&Undo", this, &MainWindow::undo, QKeySequence::Undo);
|
||||||
edit->addAction(makeIcon(":/vsicons/arrow-right.svg"), "&Redo", QKeySequence::Redo, this, &MainWindow::redo);
|
edit->addAction(makeIcon(":/vsicons/arrow-right.svg"), "&Redo", this, &MainWindow::redo, QKeySequence::Redo);
|
||||||
edit->addSeparator();
|
edit->addSeparator();
|
||||||
edit->addAction("&Type Aliases...", this, &MainWindow::showTypeAliasesDialog);
|
edit->addAction("&Type Aliases...", this, &MainWindow::showTypeAliasesDialog);
|
||||||
|
|
||||||
@@ -304,10 +304,10 @@ void MainWindow::createMenus() {
|
|||||||
|
|
||||||
// Node
|
// Node
|
||||||
auto* node = menuBar()->addMenu("&Node");
|
auto* node = menuBar()->addMenu("&Node");
|
||||||
node->addAction(makeIcon(":/vsicons/add.svg"), "&Add Field", QKeySequence(Qt::Key_Insert), this, &MainWindow::addNode);
|
node->addAction(makeIcon(":/vsicons/add.svg"), "&Add Field", this, &MainWindow::addNode, QKeySequence(Qt::Key_Insert));
|
||||||
node->addAction(makeIcon(":/vsicons/remove.svg"), "&Remove Field", QKeySequence::Delete, this, &MainWindow::removeNode);
|
node->addAction(makeIcon(":/vsicons/remove.svg"), "&Remove Field", this, &MainWindow::removeNode, QKeySequence::Delete);
|
||||||
node->addAction(makeIcon(":/vsicons/symbol-structure.svg"), "Change &Type", QKeySequence(Qt::Key_T), this, &MainWindow::changeNodeType);
|
node->addAction(makeIcon(":/vsicons/symbol-structure.svg"), "Change &Type", this, &MainWindow::changeNodeType, QKeySequence(Qt::Key_T));
|
||||||
node->addAction(makeIcon(":/vsicons/edit.svg"), "Re&name", QKeySequence(Qt::Key_F2), this, &MainWindow::renameNodeAction);
|
node->addAction(makeIcon(":/vsicons/edit.svg"), "Re&name", this, &MainWindow::renameNodeAction, QKeySequence(Qt::Key_F2));
|
||||||
node->addAction(makeIcon(":/vsicons/files.svg"), "D&uplicate", this, &MainWindow::duplicateNodeAction)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
|
node->addAction(makeIcon(":/vsicons/files.svg"), "D&uplicate", this, &MainWindow::duplicateNodeAction)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
@@ -659,7 +659,11 @@ void MainWindow::removeNode() {
|
|||||||
if (!primary || primary->isEditing()) return;
|
if (!primary || primary->isEditing()) return;
|
||||||
QSet<int> indices = primary->selectedNodeIndices();
|
QSet<int> indices = primary->selectedNodeIndices();
|
||||||
if (indices.size() > 1) {
|
if (indices.size() > 1) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
ctrl->batchRemoveNodes(indices.values());
|
ctrl->batchRemoveNodes(indices.values());
|
||||||
|
#else
|
||||||
|
ctrl->batchRemoveNodes(indices.values().toVector());
|
||||||
|
#endif
|
||||||
} else if (indices.size() == 1) {
|
} else if (indices.size() == 1) {
|
||||||
ctrl->removeNode(*indices.begin());
|
ctrl->removeNode(*indices.begin());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -791,7 +791,7 @@ QJsonObject McpBridge::toolHexRead(const QJsonObject& args) {
|
|||||||
auto* prov = tab->doc->provider.get();
|
auto* prov = tab->doc->provider.get();
|
||||||
if (!prov) return makeTextResult("No provider", true);
|
if (!prov) return makeTextResult("No provider", true);
|
||||||
|
|
||||||
int64_t offset = args.value("offset").toInteger();
|
int64_t offset = static_cast<int64_t>(args.value("offset").toDouble());
|
||||||
int length = qMin(args.value("length").toInt(64), 4096);
|
int length = qMin(args.value("length").toInt(64), 4096);
|
||||||
|
|
||||||
if (args.value("baseRelative").toBool())
|
if (args.value("baseRelative").toBool())
|
||||||
@@ -873,7 +873,7 @@ QJsonObject McpBridge::toolHexWrite(const QJsonObject& args) {
|
|||||||
auto* doc = tab->doc;
|
auto* doc = tab->doc;
|
||||||
auto* prov = doc->provider.get();
|
auto* prov = doc->provider.get();
|
||||||
|
|
||||||
int64_t offset = args.value("offset").toInteger();
|
int64_t offset = static_cast<int64_t>(args.value("offset").toDouble());
|
||||||
QString hexStr = args.value("hexBytes").toString().remove(' ');
|
QString hexStr = args.value("hexBytes").toString().remove(' ');
|
||||||
|
|
||||||
if (args.value("baseRelative").toBool())
|
if (args.value("baseRelative").toBool())
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ bool PluginManager::LoadPlugin(const QString& path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "PluginManager: Loaded plugin:" << plugin->Name() << plugin->Version() << "by" << plugin->Author();
|
qDebug() << "PluginManager: Loaded plugin:" << plugin->Name().c_str() << plugin->Version().c_str() << "by" << plugin->Author().c_str();
|
||||||
|
|
||||||
// Store plugin entry
|
// Store plugin entry
|
||||||
m_entries.append({library, plugin});
|
m_entries.append({library, plugin});
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
#include <tlhelp32.h>
|
#include <tlhelp32.h>
|
||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
#include <QtWin>
|
||||||
|
#endif
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
@@ -142,7 +145,11 @@ void ProcessPicker::enumerateProcesses()
|
|||||||
SHFILEINFOW sfi = {};
|
SHFILEINFOW sfi = {};
|
||||||
if (SHGetFileInfoW(path, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON)) {
|
if (SHGetFileInfoW(path, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON)) {
|
||||||
if (sfi.hIcon) {
|
if (sfi.hIcon) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
info.icon = QIcon(QPixmap::fromImage(QImage::fromHICON(sfi.hIcon)));
|
info.icon = QIcon(QPixmap::fromImage(QImage::fromHICON(sfi.hIcon)));
|
||||||
|
#else
|
||||||
|
info.icon = QIcon(QtWin::fromHICON(sfi.hIcon));
|
||||||
|
#endif
|
||||||
DestroyIcon(sfi.hIcon);
|
DestroyIcon(sfi.hIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void ProviderRegistry::unregisterProvider(const QString& identifier) {
|
|||||||
for (int i = 0; i < m_providers.size(); ++i) {
|
for (int i = 0; i < m_providers.size(); ++i) {
|
||||||
if (m_providers[i].identifier == identifier) {
|
if (m_providers[i].identifier == identifier) {
|
||||||
qDebug() << "ProviderRegistry: Unregistered provider:" << identifier;
|
qDebug() << "ProviderRegistry: Unregistered provider:" << identifier;
|
||||||
m_providers.remove(i);
|
m_providers.removeAt(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "iplugin.h"
|
#include "iplugin.h"
|
||||||
#include <QVector>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
void unregisterProvider(const QString& identifier);
|
void unregisterProvider(const QString& identifier);
|
||||||
|
|
||||||
// Get all registered providers
|
// Get all registered providers
|
||||||
const QVector<ProviderInfo>& providers() const { return m_providers; }
|
const QList<ProviderInfo>& providers() const { return m_providers; }
|
||||||
|
|
||||||
// Find provider by identifier
|
// Find provider by identifier
|
||||||
const ProviderInfo* findProvider(const QString& identifier) const;
|
const ProviderInfo* findProvider(const QString& identifier) const;
|
||||||
@@ -55,5 +55,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ProviderRegistry() = default;
|
ProviderRegistry() = default;
|
||||||
QVector<ProviderInfo> m_providers;
|
QList<ProviderInfo> m_providers;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#include <QTest>
|
#include <QTest>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "providers/process_provider.h"
|
#include "providers/process_provider.h"
|
||||||
|
|
||||||
using namespace rcx;
|
using namespace rcx;
|
||||||
|
#endif
|
||||||
|
|
||||||
class TestProcessProviderSymbol : public QObject {
|
class TestProcessProviderSymbol : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
void getSymbol_selfProcess() {
|
void getSymbol_selfProcess() {
|
||||||
// Attach to our own process for testing
|
// Attach to our own process for testing
|
||||||
HANDLE self = GetCurrentProcess();
|
HANDLE self = GetCurrentProcess();
|
||||||
@@ -87,19 +88,10 @@ private slots:
|
|||||||
QString sym = prov.getSymbol(ntdllBase);
|
QString sym = prov.getSymbol(ntdllBase);
|
||||||
QVERIFY(sym.toLower().startsWith("ntdll.dll+0x"));
|
QVERIFY(sym.toLower().startsWith("ntdll.dll+0x"));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
QTEST_MAIN(TestProcessProviderSymbol)
|
|
||||||
#include "test_provider_getSymbol.moc"
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// Non-Windows: empty test that passes
|
|
||||||
#include <QTest>
|
|
||||||
class TestProcessProviderSymbol : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
private slots:
|
|
||||||
void skip() { QSKIP("ProcessProvider tests are Windows-only"); }
|
void skip() { QSKIP("ProcessProvider tests are Windows-only"); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_MAIN(TestProcessProviderSymbol)
|
QTEST_MAIN(TestProcessProviderSymbol)
|
||||||
#include "test_provider_getSymbol.moc"
|
#include "test_provider_getSymbol.moc"
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -47,7 +47,11 @@ int main(int argc, char* argv[]) {
|
|||||||
app.quit();
|
app.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
QObject::connect(socket, &QLocalSocket::errorOccurred, [&](QLocalSocket::LocalSocketError err) {
|
QObject::connect(socket, &QLocalSocket::errorOccurred, [&](QLocalSocket::LocalSocketError err) {
|
||||||
|
#else
|
||||||
|
QObject::connect(socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), [&](QLocalSocket::LocalSocketError err) {
|
||||||
|
#endif
|
||||||
fprintf(stderr, "[rcx-mcp-stdio] Socket error %d: %s\n",
|
fprintf(stderr, "[rcx-mcp-stdio] Socket error %d: %s\n",
|
||||||
(int)err, socket->errorString().toUtf8().constData());
|
(int)err, socket->errorString().toUtf8().constData());
|
||||||
app.quit();
|
app.quit();
|
||||||
|
|||||||
Reference in New Issue
Block a user