mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
Initial commit: ReclassX structured binary editor
This commit is contained in:
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
build/
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.obj
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
*.pdb
|
||||||
|
*.ilk
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
.vs/
|
||||||
|
CMakeUserPresets.json
|
||||||
93
CMakeLists.txt
Normal file
93
CMakeLists.txt
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
project(ReclassX VERSION 0.1 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Widgets PrintSupport)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
find_package(QScintilla REQUIRED)
|
||||||
|
|
||||||
|
add_executable(ReclassX
|
||||||
|
src/main.cpp
|
||||||
|
src/editor.h
|
||||||
|
src/editor.cpp
|
||||||
|
src/controller.h
|
||||||
|
src/controller.cpp
|
||||||
|
src/compose.cpp
|
||||||
|
src/format.cpp
|
||||||
|
src/icons.qrc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(ReclassX PRIVATE src)
|
||||||
|
|
||||||
|
target_link_libraries(ReclassX PRIVATE
|
||||||
|
Qt6::Widgets
|
||||||
|
Qt6::PrintSupport
|
||||||
|
QScintilla::QScintilla
|
||||||
|
dbghelp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(screenshot
|
||||||
|
COMMAND ReclassX --screenshot ${CMAKE_BINARY_DIR}/screenshot.png
|
||||||
|
DEPENDS ReclassX
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
|
COMMENT "Capturing UI screenshot with class open..."
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_combine_script "${CMAKE_BINARY_DIR}/combine_sources.cmake")
|
||||||
|
file(WRITE ${_combine_script} "
|
||||||
|
set(_out \"${CMAKE_BINARY_DIR}/h_cpp_combined.txt\")
|
||||||
|
file(WRITE \${_out} \"\")
|
||||||
|
foreach(_f
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/core.h\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/editor.h\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/editor.cpp\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/controller.h\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/controller.cpp\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/compose.cpp\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/format.cpp\"
|
||||||
|
\"${CMAKE_SOURCE_DIR}/src/main.cpp\")
|
||||||
|
file(READ \${_f} _content)
|
||||||
|
file(APPEND \${_out} \${_content})
|
||||||
|
file(APPEND \${_out} \"\\n\")
|
||||||
|
endforeach()
|
||||||
|
message(STATUS \"Combined sources -> \${_out}\")
|
||||||
|
")
|
||||||
|
|
||||||
|
add_custom_target(combined ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P ${_combine_script}
|
||||||
|
DEPENDS ReclassX
|
||||||
|
COMMENT "Combining all source files into h_cpp_combined.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Test)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_executable(test_core tests/test_core.cpp src/format.cpp src/compose.cpp)
|
||||||
|
target_include_directories(test_core PRIVATE src)
|
||||||
|
target_link_libraries(test_core PRIVATE Qt6::Core Qt6::Test)
|
||||||
|
add_test(NAME test_core COMMAND test_core)
|
||||||
|
|
||||||
|
add_executable(test_format tests/test_format.cpp src/format.cpp)
|
||||||
|
target_include_directories(test_format PRIVATE src)
|
||||||
|
target_link_libraries(test_format PRIVATE Qt6::Core Qt6::Test)
|
||||||
|
add_test(NAME test_format COMMAND test_format)
|
||||||
|
|
||||||
|
add_executable(test_compose tests/test_compose.cpp src/compose.cpp src/format.cpp)
|
||||||
|
target_include_directories(test_compose PRIVATE src)
|
||||||
|
target_link_libraries(test_compose PRIVATE Qt6::Core Qt6::Test)
|
||||||
|
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)
|
||||||
|
target_include_directories(test_editor PRIVATE src)
|
||||||
|
target_link_libraries(test_editor PRIVATE
|
||||||
|
Qt6::Widgets Qt6::PrintSupport Qt6::Test
|
||||||
|
QScintilla::QScintilla)
|
||||||
|
add_test(NAME test_editor COMMAND test_editor)
|
||||||
|
endif()
|
||||||
32
cmake/FindQScintilla.cmake
Normal file
32
cmake/FindQScintilla.cmake
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
set(_QSCI_ROOT "${CMAKE_SOURCE_DIR}/third_party/qscintilla")
|
||||||
|
|
||||||
|
find_path(QScintilla_INCLUDE_DIR
|
||||||
|
NAMES Qsci/qsciscintilla.h
|
||||||
|
PATHS "${_QSCI_ROOT}/src" "${_QSCI_ROOT}/include"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(QScintilla_LIBRARY
|
||||||
|
NAMES qscintilla2_qt6 libqscintilla2_qt6
|
||||||
|
PATHS
|
||||||
|
"${_QSCI_ROOT}/src/release"
|
||||||
|
"${_QSCI_ROOT}/src"
|
||||||
|
"${_QSCI_ROOT}/lib"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(QScintilla DEFAULT_MSG
|
||||||
|
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)
|
||||||
|
add_library(QScintilla::QScintilla STATIC IMPORTED)
|
||||||
|
set_target_properties(QScintilla::QScintilla PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${QScintilla_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${QScintilla_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
13
scripts/build_qscintilla.bat
Normal file
13
scripts/build_qscintilla.bat
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
@echo off
|
||||||
|
set "PATH=C:\Qt\Tools\mingw1120_64\bin;C:\Qt\6.5.2\mingw_64\bin;%PATH%"
|
||||||
|
cd /d "E:\game_dev\util\reclass2027-main\third_party\qscintilla\src"
|
||||||
|
echo Current dir: %cd%
|
||||||
|
echo Running qmake...
|
||||||
|
"C:\Qt\6.5.2\mingw_64\bin\qmake.exe" qscintilla.pro "CONFIG+=staticlib"
|
||||||
|
echo qmake exit code: %errorlevel%
|
||||||
|
echo Running mingw32-make...
|
||||||
|
"C:\Qt\Tools\mingw1120_64\bin\mingw32-make.exe" -j8
|
||||||
|
echo make exit code: %errorlevel%
|
||||||
|
echo Done. Checking for .a files:
|
||||||
|
dir /b *.a 2>nul
|
||||||
|
dir /b release\*.a 2>nul
|
||||||
323
src/compose.cpp
Normal file
323
src/compose.cpp
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
#include "core.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Scintilla fold constants (avoid including Scintilla headers in core)
|
||||||
|
constexpr int SC_FOLDLEVELBASE = 0x400;
|
||||||
|
constexpr int SC_FOLDLEVELHEADERFLAG = 0x2000;
|
||||||
|
constexpr uint64_t kGoldenRatio = 0x9E3779B97F4A7C15ULL;
|
||||||
|
|
||||||
|
struct ComposeState {
|
||||||
|
QString text;
|
||||||
|
QVector<LineMeta> meta;
|
||||||
|
QSet<uint64_t> visiting; // cycle detection for struct recursion
|
||||||
|
QSet<qulonglong> ptrVisiting; // cycle guard for pointer expansions
|
||||||
|
int currentLine = 0;
|
||||||
|
|
||||||
|
// Precomputed for O(1) lookups
|
||||||
|
QHash<uint64_t, QVector<int>> childMap;
|
||||||
|
QVector<int64_t> absOffsets; // indexed by node index
|
||||||
|
|
||||||
|
void emitLine(const QString& lineText, LineMeta lm) {
|
||||||
|
if (currentLine > 0) text += '\n';
|
||||||
|
// 3-char fold indicator column: " - " expanded, " + " collapsed, " " other
|
||||||
|
if (lm.foldHead)
|
||||||
|
text += lm.foldCollapsed ? QStringLiteral(" + ") : QStringLiteral(" - ");
|
||||||
|
else
|
||||||
|
text += QStringLiteral(" ");
|
||||||
|
text += lineText;
|
||||||
|
meta.append(lm);
|
||||||
|
currentLine++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int computeFoldLevel(int depth, bool isHead) {
|
||||||
|
int level = SC_FOLDLEVELBASE + depth;
|
||||||
|
if (isHead) level |= SC_FOLDLEVELHEADERFLAG;
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t computeMarkers(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, bool isCont, int depth) {
|
||||||
|
uint32_t mask = 0;
|
||||||
|
if (isCont) mask |= (1u << M_CONT);
|
||||||
|
if (node.kind == NodeKind::Padding) mask |= (1u << M_PAD);
|
||||||
|
|
||||||
|
if (prov.isValid()) {
|
||||||
|
int sz = node.byteSize();
|
||||||
|
if (sz > 0 && !prov.isReadable(addr, sz)) {
|
||||||
|
mask |= (1u << M_ERR);
|
||||||
|
} else if (sz > 0) {
|
||||||
|
if (node.kind == NodeKind::Pointer32 && prov.readU32(addr) == 0)
|
||||||
|
mask |= (1u << M_PTR0);
|
||||||
|
if (node.kind == NodeKind::Pointer64 && prov.readU64(addr) == 0)
|
||||||
|
mask |= (1u << M_PTR0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ptrToProviderAddr(const NodeTree& tree, uint64_t ptr) {
|
||||||
|
if (tree.baseAddress && ptr >= tree.baseAddress) return ptr - tree.baseAddress;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t relOffsetFromRoot(const NodeTree& tree, int idx, uint64_t rootId) {
|
||||||
|
int64_t total = 0;
|
||||||
|
QSet<int> visited;
|
||||||
|
int cur = idx;
|
||||||
|
while (cur >= 0 && cur < tree.nodes.size()) {
|
||||||
|
if (visited.contains(cur)) break;
|
||||||
|
visited.insert(cur);
|
||||||
|
const Node& n = tree.nodes[cur];
|
||||||
|
if (n.id == rootId) break;
|
||||||
|
total += n.offset;
|
||||||
|
if (n.parentId == 0) break;
|
||||||
|
cur = tree.indexOfId(n.parentId);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t resolveAddr(const ComposeState& state,
|
||||||
|
const NodeTree& tree,
|
||||||
|
int nodeIdx,
|
||||||
|
uint64_t base, uint64_t rootId) {
|
||||||
|
if (rootId != 0)
|
||||||
|
return base + relOffsetFromRoot(tree, nodeIdx, rootId);
|
||||||
|
return state.absOffsets[nodeIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void composeLeaf(ComposeState& state, const NodeTree& tree,
|
||||||
|
const Provider& prov, int nodeIdx,
|
||||||
|
int depth, uint64_t absAddr) {
|
||||||
|
const Node& node = tree.nodes[nodeIdx];
|
||||||
|
|
||||||
|
// Line count: padding wraps at 8 bytes per line
|
||||||
|
int numLines;
|
||||||
|
if (node.kind == NodeKind::Padding) {
|
||||||
|
int totalBytes = qMax(1, node.arrayLen);
|
||||||
|
numLines = (totalBytes + 7) / 8;
|
||||||
|
} else {
|
||||||
|
numLines = linesForKind(node.kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int sub = 0; sub < numLines; sub++) {
|
||||||
|
bool isCont = (sub > 0);
|
||||||
|
|
||||||
|
LineMeta lm;
|
||||||
|
lm.nodeIdx = nodeIdx;
|
||||||
|
lm.nodeId = node.id;
|
||||||
|
lm.subLine = sub;
|
||||||
|
lm.depth = depth;
|
||||||
|
lm.isContinuation = isCont;
|
||||||
|
lm.lineKind = isCont ? LineKind::Continuation : LineKind::Field;
|
||||||
|
lm.nodeKind = node.kind;
|
||||||
|
lm.offsetText = fmt::fmtOffsetMargin(absAddr, isCont);
|
||||||
|
lm.markerMask = computeMarkers(node, prov, absAddr, isCont, depth);
|
||||||
|
lm.foldLevel = computeFoldLevel(depth, false);
|
||||||
|
|
||||||
|
QString lineText = fmt::fmtNodeLine(node, prov, absAddr, depth, sub);
|
||||||
|
state.emitLine(lineText, lm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward declarations (base/rootId default to 0 = use precomputed offsets)
|
||||||
|
void composeNode(ComposeState& state, const NodeTree& tree,
|
||||||
|
const Provider& prov, int nodeIdx, int depth,
|
||||||
|
uint64_t base = 0, uint64_t rootId = 0);
|
||||||
|
void composeParent(ComposeState& state, const NodeTree& tree,
|
||||||
|
const Provider& prov, int nodeIdx, int depth,
|
||||||
|
uint64_t base = 0, uint64_t rootId = 0);
|
||||||
|
|
||||||
|
void composeParent(ComposeState& state, const NodeTree& tree,
|
||||||
|
const Provider& prov, int nodeIdx, int depth,
|
||||||
|
uint64_t base, uint64_t rootId) {
|
||||||
|
const Node& node = tree.nodes[nodeIdx];
|
||||||
|
uint64_t absAddr = resolveAddr(state, tree, nodeIdx, base, rootId);
|
||||||
|
|
||||||
|
// Cycle detection
|
||||||
|
if (state.visiting.contains(node.id)) {
|
||||||
|
LineMeta lm;
|
||||||
|
lm.nodeIdx = nodeIdx;
|
||||||
|
lm.nodeId = node.id;
|
||||||
|
lm.depth = depth;
|
||||||
|
lm.lineKind = LineKind::Field;
|
||||||
|
lm.offsetText = fmt::fmtOffsetMargin(absAddr, false);
|
||||||
|
lm.nodeKind = node.kind;
|
||||||
|
lm.markerMask = (1u << M_CYCLE) | (1u << M_ERR);
|
||||||
|
lm.foldLevel = computeFoldLevel(depth, false);
|
||||||
|
state.emitLine(fmt::indent(depth) + QStringLiteral("/* CYCLE: ") +
|
||||||
|
node.name + QStringLiteral(" */"), lm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.visiting.insert(node.id);
|
||||||
|
|
||||||
|
// Header line
|
||||||
|
{
|
||||||
|
LineMeta lm;
|
||||||
|
lm.nodeIdx = nodeIdx;
|
||||||
|
lm.nodeId = node.id;
|
||||||
|
lm.depth = depth;
|
||||||
|
lm.lineKind = LineKind::Header;
|
||||||
|
lm.offsetText = fmt::fmtOffsetMargin(absAddr, false);
|
||||||
|
lm.nodeKind = node.kind;
|
||||||
|
lm.foldHead = true;
|
||||||
|
lm.foldCollapsed = node.collapsed;
|
||||||
|
lm.foldLevel = computeFoldLevel(depth, true);
|
||||||
|
lm.markerMask = (1u << M_STRUCT_BG);
|
||||||
|
state.emitLine(fmt::fmtStructHeader(node, depth), lm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.collapsed) {
|
||||||
|
QVector<int> children = state.childMap.value(node.id);
|
||||||
|
std::sort(children.begin(), children.end(), [&](int a, int b) {
|
||||||
|
return tree.nodes[a].offset < tree.nodes[b].offset;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int childIdx : children) {
|
||||||
|
composeNode(state, tree, prov, childIdx, depth + 1, base, rootId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Footer line
|
||||||
|
{
|
||||||
|
LineMeta lm;
|
||||||
|
lm.nodeIdx = nodeIdx;
|
||||||
|
lm.nodeId = node.id;
|
||||||
|
lm.depth = depth;
|
||||||
|
lm.lineKind = LineKind::Footer;
|
||||||
|
lm.nodeKind = node.kind;
|
||||||
|
lm.offsetText = QStringLiteral(" ---");
|
||||||
|
lm.foldLevel = computeFoldLevel(depth, false);
|
||||||
|
lm.markerMask = (1u << M_STRUCT_BG);
|
||||||
|
int sz = tree.structSpan(node.id, &state.childMap);
|
||||||
|
state.emitLine(fmt::fmtStructFooter(node, depth, sz), lm);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.visiting.remove(node.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void composeNode(ComposeState& state, const NodeTree& tree,
|
||||||
|
const Provider& prov, int nodeIdx, int depth,
|
||||||
|
uint64_t base, uint64_t rootId) {
|
||||||
|
const Node& node = tree.nodes[nodeIdx];
|
||||||
|
uint64_t absAddr = resolveAddr(state, tree, nodeIdx, base, rootId);
|
||||||
|
|
||||||
|
// Pointer deref expansion
|
||||||
|
if ((node.kind == NodeKind::Pointer32 || node.kind == NodeKind::Pointer64)
|
||||||
|
&& node.refId != 0) {
|
||||||
|
{
|
||||||
|
LineMeta lm;
|
||||||
|
lm.nodeIdx = nodeIdx;
|
||||||
|
lm.nodeId = node.id;
|
||||||
|
lm.depth = depth;
|
||||||
|
lm.lineKind = LineKind::Field;
|
||||||
|
lm.offsetText = fmt::fmtOffsetMargin(absAddr, false);
|
||||||
|
lm.nodeKind = node.kind;
|
||||||
|
lm.foldHead = true;
|
||||||
|
lm.foldCollapsed = node.collapsed;
|
||||||
|
lm.foldLevel = computeFoldLevel(depth, true);
|
||||||
|
lm.markerMask = computeMarkers(node, prov, absAddr, false, depth);
|
||||||
|
state.emitLine(fmt::fmtNodeLine(node, prov, absAddr, depth, 0), lm);
|
||||||
|
}
|
||||||
|
if (!node.collapsed) {
|
||||||
|
int sz = node.byteSize();
|
||||||
|
if (prov.isValid() && sz > 0 && prov.isReadable(absAddr, sz)) {
|
||||||
|
uint64_t ptrVal = (node.kind == NodeKind::Pointer32)
|
||||||
|
? (uint64_t)prov.readU32(absAddr) : prov.readU64(absAddr);
|
||||||
|
if (ptrVal != 0) {
|
||||||
|
uint64_t pBase = ptrToProviderAddr(tree, ptrVal);
|
||||||
|
qulonglong key = pBase ^ (node.refId * kGoldenRatio);
|
||||||
|
if (!state.ptrVisiting.contains(key)) {
|
||||||
|
state.ptrVisiting.insert(key);
|
||||||
|
int refIdx = tree.indexOfId(node.refId);
|
||||||
|
if (refIdx >= 0) {
|
||||||
|
const Node& ref = tree.nodes[refIdx];
|
||||||
|
if (ref.kind == NodeKind::Struct || ref.kind == NodeKind::Array)
|
||||||
|
composeParent(state, tree, prov, refIdx,
|
||||||
|
depth + 1, pBase, ref.id);
|
||||||
|
}
|
||||||
|
state.ptrVisiting.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.kind == NodeKind::Struct || node.kind == NodeKind::Array) {
|
||||||
|
composeParent(state, tree, prov, nodeIdx, depth, base, rootId);
|
||||||
|
} else {
|
||||||
|
composeLeaf(state, tree, prov, nodeIdx, depth, absAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
ComposeResult compose(const NodeTree& tree, const Provider& prov) {
|
||||||
|
ComposeState state;
|
||||||
|
|
||||||
|
// Precompute parent→children map
|
||||||
|
for (int i = 0; i < tree.nodes.size(); i++)
|
||||||
|
state.childMap[tree.nodes[i].parentId].append(i);
|
||||||
|
|
||||||
|
// Precompute absolute offsets
|
||||||
|
state.absOffsets.resize(tree.nodes.size());
|
||||||
|
for (int i = 0; i < tree.nodes.size(); i++)
|
||||||
|
state.absOffsets[i] = tree.computeOffset(i);
|
||||||
|
|
||||||
|
QVector<int> roots = state.childMap.value(0);
|
||||||
|
std::sort(roots.begin(), roots.end(), [&](int a, int b) {
|
||||||
|
return tree.nodes[a].offset < tree.nodes[b].offset;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int idx : roots) {
|
||||||
|
composeNode(state, tree, prov, idx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { state.text, state.meta };
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<uint64_t> NodeTree::normalizePreferAncestors(const QSet<uint64_t>& ids) const {
|
||||||
|
QSet<uint64_t> result;
|
||||||
|
for (uint64_t id : ids) {
|
||||||
|
int idx = indexOfId(id);
|
||||||
|
if (idx < 0) continue;
|
||||||
|
bool ancestorSelected = false;
|
||||||
|
uint64_t cur = nodes[idx].parentId;
|
||||||
|
QSet<uint64_t> visited;
|
||||||
|
while (cur != 0 && !visited.contains(cur)) {
|
||||||
|
visited.insert(cur);
|
||||||
|
if (ids.contains(cur)) { ancestorSelected = true; break; }
|
||||||
|
int pi = indexOfId(cur);
|
||||||
|
if (pi < 0) break;
|
||||||
|
cur = nodes[pi].parentId;
|
||||||
|
}
|
||||||
|
if (!ancestorSelected)
|
||||||
|
result.insert(id);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<uint64_t> NodeTree::normalizePreferDescendants(const QSet<uint64_t>& ids) const {
|
||||||
|
QSet<uint64_t> result;
|
||||||
|
for (uint64_t id : ids) {
|
||||||
|
QVector<int> sub = subtreeIndices(id);
|
||||||
|
bool hasSelectedDescendant = false;
|
||||||
|
for (int si : sub) {
|
||||||
|
uint64_t sid = nodes[si].id;
|
||||||
|
if (sid != id && ids.contains(sid)) {
|
||||||
|
hasSelectedDescendant = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasSelectedDescendant)
|
||||||
|
result.insert(id);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
565
src/controller.cpp
Normal file
565
src/controller.cpp
Normal file
@@ -0,0 +1,565 @@
|
|||||||
|
#include "controller.h"
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
// ── RcxDocument ──
|
||||||
|
|
||||||
|
RcxDocument::RcxDocument(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, provider(std::make_unique<NullProvider>())
|
||||||
|
{
|
||||||
|
connect(&undoStack, &QUndoStack::cleanChanged, this, [this](bool clean) {
|
||||||
|
modified = !clean;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ComposeResult RcxDocument::compose() const {
|
||||||
|
return rcx::compose(tree, *provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RcxDocument::save(const QString& path) {
|
||||||
|
QJsonObject json = tree.toJson();
|
||||||
|
QJsonDocument jdoc(json);
|
||||||
|
QFile file(path);
|
||||||
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
|
return false;
|
||||||
|
file.write(jdoc.toJson(QJsonDocument::Indented));
|
||||||
|
filePath = path;
|
||||||
|
undoStack.setClean();
|
||||||
|
modified = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RcxDocument::load(const QString& path) {
|
||||||
|
QFile file(path);
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
undoStack.clear();
|
||||||
|
QJsonDocument jdoc = QJsonDocument::fromJson(file.readAll());
|
||||||
|
tree = NodeTree::fromJson(jdoc.object());
|
||||||
|
filePath = path;
|
||||||
|
modified = false;
|
||||||
|
emit documentChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxDocument::loadData(const QString& binaryPath) {
|
||||||
|
QFile file(binaryPath);
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
return;
|
||||||
|
undoStack.clear();
|
||||||
|
provider = std::make_unique<FileProvider>(file.readAll());
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
emit documentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxDocument::loadData(const QByteArray& data) {
|
||||||
|
undoStack.clear();
|
||||||
|
provider = std::make_unique<FileProvider>(data);
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
emit documentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── RcxCommand ──
|
||||||
|
|
||||||
|
RcxCommand::RcxCommand(RcxController* ctrl, Command cmd)
|
||||||
|
: m_ctrl(ctrl), m_cmd(cmd) {}
|
||||||
|
|
||||||
|
void RcxCommand::undo() { m_ctrl->applyCommand(m_cmd, true); }
|
||||||
|
void RcxCommand::redo() { m_ctrl->applyCommand(m_cmd, false); }
|
||||||
|
|
||||||
|
// ── RcxController ──
|
||||||
|
|
||||||
|
RcxController::RcxController(RcxDocument* doc, QWidget* parent)
|
||||||
|
: QObject(parent), m_doc(doc)
|
||||||
|
{
|
||||||
|
connect(m_doc, &RcxDocument::documentChanged, this, &RcxController::refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
RcxEditor* RcxController::primaryEditor() const {
|
||||||
|
return m_editors.isEmpty() ? nullptr : m_editors.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
RcxEditor* RcxController::addSplitEditor(QSplitter* splitter) {
|
||||||
|
auto* editor = new RcxEditor(splitter);
|
||||||
|
splitter->addWidget(editor);
|
||||||
|
m_editors.append(editor);
|
||||||
|
connectEditor(editor);
|
||||||
|
|
||||||
|
if (!m_lastResult.text.isEmpty()) {
|
||||||
|
editor->applyDocument(m_lastResult);
|
||||||
|
}
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::removeSplitEditor(RcxEditor* editor) {
|
||||||
|
m_editors.removeOne(editor);
|
||||||
|
editor->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::connectEditor(RcxEditor* editor) {
|
||||||
|
connect(editor, &RcxEditor::marginClicked,
|
||||||
|
this, [this, editor](int margin, int line, Qt::KeyboardModifiers mods) {
|
||||||
|
handleMarginClick(editor, margin, line, mods);
|
||||||
|
});
|
||||||
|
connect(editor, &RcxEditor::contextMenuRequested,
|
||||||
|
this, [this, editor](int line, int nodeIdx, int subLine, QPoint globalPos) {
|
||||||
|
showContextMenu(editor, line, nodeIdx, subLine, globalPos);
|
||||||
|
});
|
||||||
|
connect(editor, &RcxEditor::nodeClicked,
|
||||||
|
this, [this, editor](int line, uint64_t nodeId, Qt::KeyboardModifiers mods) {
|
||||||
|
handleNodeClick(editor, line, nodeId, mods);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inline editing signals
|
||||||
|
connect(editor, &RcxEditor::inlineEditCommitted,
|
||||||
|
this, [this](int nodeIdx, int subLine, EditTarget target, const QString& text) {
|
||||||
|
if (nodeIdx < 0) { refresh(); return; }
|
||||||
|
switch (target) {
|
||||||
|
case EditTarget::Name:
|
||||||
|
if (!text.isEmpty()) renameNode(nodeIdx, text);
|
||||||
|
break;
|
||||||
|
case EditTarget::Type: {
|
||||||
|
bool ok;
|
||||||
|
NodeKind k = kindFromTypeName(text, &ok);
|
||||||
|
if (ok) changeNodeKind(nodeIdx, k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EditTarget::Value:
|
||||||
|
setNodeValue(nodeIdx, subLine, text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Always refresh to restore canonical text (handles parse failures, no-ops, etc.)
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
connect(editor, &RcxEditor::inlineEditCancelled,
|
||||||
|
this, [this]() { refresh(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::refresh() {
|
||||||
|
m_lastResult = m_doc->compose();
|
||||||
|
|
||||||
|
// Prune stale selections (nodes removed by undo/redo/delete)
|
||||||
|
QSet<uint64_t> valid;
|
||||||
|
for (uint64_t id : m_selIds) {
|
||||||
|
if (m_doc->tree.indexOfId(id) >= 0)
|
||||||
|
valid.insert(id);
|
||||||
|
}
|
||||||
|
m_selIds = valid;
|
||||||
|
|
||||||
|
for (auto* editor : m_editors) {
|
||||||
|
ViewState vs = editor->saveViewState();
|
||||||
|
editor->applyDocument(m_lastResult);
|
||||||
|
editor->restoreViewState(vs);
|
||||||
|
}
|
||||||
|
applySelectionOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::changeNodeKind(int nodeIdx, NodeKind newKind) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
auto& node = m_doc->tree.nodes[nodeIdx];
|
||||||
|
|
||||||
|
int oldSize = node.byteSize();
|
||||||
|
// Compute what byteSize() would be with the new kind
|
||||||
|
Node tmp = node;
|
||||||
|
tmp.kind = newKind;
|
||||||
|
int newSize = tmp.byteSize();
|
||||||
|
int delta = newSize - oldSize;
|
||||||
|
|
||||||
|
QVector<cmd::OffsetAdj> adjs;
|
||||||
|
if (delta != 0 && oldSize > 0 && newSize > 0) {
|
||||||
|
int oldEnd = node.offset + oldSize;
|
||||||
|
auto siblings = m_doc->tree.childrenOf(node.parentId);
|
||||||
|
for (int si : siblings) {
|
||||||
|
if (si == nodeIdx) continue;
|
||||||
|
auto& sib = m_doc->tree.nodes[si];
|
||||||
|
if (sib.offset >= oldEnd)
|
||||||
|
adjs.append({sib.id, sib.offset, sib.offset + delta});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this,
|
||||||
|
cmd::ChangeKind{node.id, node.kind, newKind, adjs}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::renameNode(int nodeIdx, const QString& newName) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
auto& node = m_doc->tree.nodes[nodeIdx];
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this,
|
||||||
|
cmd::Rename{node.id, node.name, newName}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::insertNode(uint64_t parentId, int offset, NodeKind kind, const QString& name) {
|
||||||
|
Node n;
|
||||||
|
n.kind = kind;
|
||||||
|
n.name = name;
|
||||||
|
n.parentId = parentId;
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
// Auto-place after last sibling with alignment
|
||||||
|
int maxEnd = 0;
|
||||||
|
auto siblings = m_doc->tree.childrenOf(parentId);
|
||||||
|
for (int si : siblings) {
|
||||||
|
auto& sn = m_doc->tree.nodes[si];
|
||||||
|
int sz = (sn.kind == NodeKind::Struct || sn.kind == NodeKind::Array)
|
||||||
|
? m_doc->tree.structSpan(sn.id) : sn.byteSize();
|
||||||
|
int end = sn.offset + sz;
|
||||||
|
if (end > maxEnd) maxEnd = end;
|
||||||
|
}
|
||||||
|
int align = alignmentFor(kind);
|
||||||
|
n.offset = (maxEnd + align - 1) / align * align;
|
||||||
|
} else {
|
||||||
|
n.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign ID before storing
|
||||||
|
n.id = m_doc->tree.m_nextId;
|
||||||
|
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this, cmd::Insert{n}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::removeNode(int nodeIdx) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
uint64_t nodeId = m_doc->tree.nodes[nodeIdx].id;
|
||||||
|
|
||||||
|
QVector<int> indices = m_doc->tree.subtreeIndices(nodeId);
|
||||||
|
QVector<Node> subtree;
|
||||||
|
for (int i : indices)
|
||||||
|
subtree.append(m_doc->tree.nodes[i]);
|
||||||
|
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this,
|
||||||
|
cmd::Remove{nodeId, subtree}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::toggleCollapse(int nodeIdx) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
auto& node = m_doc->tree.nodes[nodeIdx];
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this,
|
||||||
|
cmd::Collapse{node.id, node.collapsed, !node.collapsed}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::applyCommand(const Command& command, bool isUndo) {
|
||||||
|
auto& tree = m_doc->tree;
|
||||||
|
|
||||||
|
std::visit([&](auto&& c) {
|
||||||
|
using T = std::decay_t<decltype(c)>;
|
||||||
|
if constexpr (std::is_same_v<T, cmd::ChangeKind>) {
|
||||||
|
int idx = tree.indexOfId(c.nodeId);
|
||||||
|
if (idx >= 0)
|
||||||
|
tree.nodes[idx].kind = isUndo ? c.oldKind : c.newKind;
|
||||||
|
for (const auto& adj : c.offAdjs) {
|
||||||
|
int ai = tree.indexOfId(adj.nodeId);
|
||||||
|
if (ai >= 0)
|
||||||
|
tree.nodes[ai].offset = isUndo ? adj.oldOffset : adj.newOffset;
|
||||||
|
}
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::Rename>) {
|
||||||
|
int idx = tree.indexOfId(c.nodeId);
|
||||||
|
if (idx >= 0)
|
||||||
|
tree.nodes[idx].name = isUndo ? c.oldName : c.newName;
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::Collapse>) {
|
||||||
|
int idx = tree.indexOfId(c.nodeId);
|
||||||
|
if (idx >= 0)
|
||||||
|
tree.nodes[idx].collapsed = isUndo ? c.oldState : c.newState;
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::Insert>) {
|
||||||
|
if (isUndo) {
|
||||||
|
int idx = tree.indexOfId(c.node.id);
|
||||||
|
if (idx >= 0) {
|
||||||
|
tree.nodes.remove(idx);
|
||||||
|
tree.invalidateIdCache();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tree.addNode(c.node);
|
||||||
|
}
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::Remove>) {
|
||||||
|
if (isUndo) {
|
||||||
|
for (const Node& n : c.subtree)
|
||||||
|
tree.addNode(n);
|
||||||
|
} else {
|
||||||
|
QVector<int> indices = tree.subtreeIndices(c.nodeId);
|
||||||
|
std::sort(indices.begin(), indices.end(), std::greater<int>());
|
||||||
|
for (int idx : indices)
|
||||||
|
tree.nodes.remove(idx);
|
||||||
|
tree.invalidateIdCache();
|
||||||
|
}
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::ChangeBase>) {
|
||||||
|
tree.baseAddress = isUndo ? c.oldBase : c.newBase;
|
||||||
|
} else if constexpr (std::is_same_v<T, cmd::WriteBytes>) {
|
||||||
|
const QByteArray& bytes = isUndo ? c.oldBytes : c.newBytes;
|
||||||
|
m_doc->provider->writeBytes(c.addr, bytes);
|
||||||
|
}
|
||||||
|
}, command);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::setNodeValue(int nodeIdx, int subLine, const QString& text) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
if (!m_doc->provider->isWritable()) return;
|
||||||
|
|
||||||
|
const Node& node = m_doc->tree.nodes[nodeIdx];
|
||||||
|
uint64_t addr = m_doc->tree.computeOffset(nodeIdx);
|
||||||
|
|
||||||
|
// For vector sub-components, redirect to float parsing at sub-offset
|
||||||
|
NodeKind editKind = node.kind;
|
||||||
|
if ((node.kind == NodeKind::Vec2 || node.kind == NodeKind::Vec3 ||
|
||||||
|
node.kind == NodeKind::Vec4) && subLine >= 0) {
|
||||||
|
addr += subLine * 4;
|
||||||
|
editKind = NodeKind::Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
QByteArray newBytes = fmt::parseValue(editKind, text, &ok);
|
||||||
|
if (!ok) return;
|
||||||
|
|
||||||
|
// For strings, pad/truncate to full buffer size
|
||||||
|
if (node.kind == NodeKind::UTF8 || node.kind == NodeKind::UTF16) {
|
||||||
|
int fullSize = node.byteSize();
|
||||||
|
newBytes = newBytes.left(fullSize);
|
||||||
|
if (newBytes.size() < fullSize)
|
||||||
|
newBytes.append(QByteArray(fullSize - newBytes.size(), '\0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newBytes.isEmpty()) return;
|
||||||
|
|
||||||
|
int writeSize = newBytes.size();
|
||||||
|
|
||||||
|
// Validate write range before pushing command
|
||||||
|
if (!m_doc->provider->isReadable(addr, writeSize)) return;
|
||||||
|
|
||||||
|
QByteArray oldBytes = m_doc->provider->readBytes(addr, writeSize);
|
||||||
|
|
||||||
|
m_doc->undoStack.push(new RcxCommand(this,
|
||||||
|
cmd::WriteBytes{addr, oldBytes, newBytes}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::duplicateNode(int nodeIdx) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
const Node& src = m_doc->tree.nodes[nodeIdx];
|
||||||
|
if (src.kind == NodeKind::Struct || src.kind == NodeKind::Array) return;
|
||||||
|
insertNode(src.parentId, src.offset + src.byteSize(), src.kind, src.name + "_copy");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx,
|
||||||
|
int subLine, const QPoint& globalPos) {
|
||||||
|
if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return;
|
||||||
|
uint64_t clickedId = m_doc->tree.nodes[nodeIdx].id;
|
||||||
|
|
||||||
|
// Right-click selection policy: if not in selection, select only this node
|
||||||
|
if (!m_selIds.contains(clickedId)) {
|
||||||
|
m_selIds.clear();
|
||||||
|
m_selIds.insert(clickedId);
|
||||||
|
m_anchorLine = line;
|
||||||
|
applySelectionOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multi-select batch menu
|
||||||
|
if (m_selIds.size() > 1) {
|
||||||
|
QMenu menu;
|
||||||
|
int count = m_selIds.size();
|
||||||
|
QSet<uint64_t> ids = m_selIds;
|
||||||
|
menu.addAction(QString("Delete %1 nodes").arg(count), [this, ids]() {
|
||||||
|
QVector<int> indices;
|
||||||
|
for (uint64_t id : ids) {
|
||||||
|
int idx = m_doc->tree.indexOfId(id);
|
||||||
|
if (idx >= 0) indices.append(idx);
|
||||||
|
}
|
||||||
|
batchRemoveNodes(indices);
|
||||||
|
});
|
||||||
|
menu.addAction(QString("Change type of %1 nodes...").arg(count),
|
||||||
|
[this, ids]() {
|
||||||
|
QStringList types;
|
||||||
|
for (const auto& e : kKindMeta) types << e.name;
|
||||||
|
bool ok;
|
||||||
|
QString sel = QInputDialog::getItem(nullptr, "Change Type", "Type:",
|
||||||
|
types, 0, false, &ok);
|
||||||
|
if (ok) {
|
||||||
|
QVector<int> indices;
|
||||||
|
for (uint64_t id : ids) {
|
||||||
|
int idx = m_doc->tree.indexOfId(id);
|
||||||
|
if (idx >= 0) indices.append(idx);
|
||||||
|
}
|
||||||
|
batchChangeKind(indices, kindFromString(sel));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.exec(globalPos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Node& node = m_doc->tree.nodes[nodeIdx];
|
||||||
|
uint64_t nodeId = node.id;
|
||||||
|
uint64_t parentId = node.parentId;
|
||||||
|
|
||||||
|
QMenu menu;
|
||||||
|
|
||||||
|
// Inline edit actions — position cursor on the right-clicked line
|
||||||
|
bool isEditable = node.kind != NodeKind::Struct && node.kind != NodeKind::Array
|
||||||
|
&& node.kind != NodeKind::Padding && node.kind != NodeKind::Mat4x4
|
||||||
|
&& m_doc->provider->isWritable();
|
||||||
|
if (isEditable) {
|
||||||
|
menu.addAction("Edit &Value", [editor, line]() {
|
||||||
|
editor->beginInlineEdit(EditTarget::Value, line);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.addAction("Re&name", [editor, line]() {
|
||||||
|
editor->beginInlineEdit(EditTarget::Name, line);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addAction("Change &Type", [editor, line]() {
|
||||||
|
editor->beginInlineEdit(EditTarget::Type, line);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
menu.addAction("&Add Field Below", [this, parentId]() {
|
||||||
|
insertNode(parentId, -1, NodeKind::Hex64, "newField");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (node.kind == NodeKind::Struct || node.kind == NodeKind::Array) {
|
||||||
|
menu.addAction("Add &Child", [this, nodeId]() {
|
||||||
|
insertNode(nodeId, 0, NodeKind::Hex64, "newField");
|
||||||
|
});
|
||||||
|
QString colText = node.collapsed ? "&Expand" : "&Collapse";
|
||||||
|
menu.addAction(colText, [this, nodeId]() {
|
||||||
|
int ni = m_doc->tree.indexOfId(nodeId);
|
||||||
|
if (ni >= 0) toggleCollapse(ni);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.addAction("D&uplicate", [this, nodeId]() {
|
||||||
|
int ni = m_doc->tree.indexOfId(nodeId);
|
||||||
|
if (ni >= 0) duplicateNode(ni);
|
||||||
|
});
|
||||||
|
menu.addAction("&Delete", [this, nodeId]() {
|
||||||
|
int ni = m_doc->tree.indexOfId(nodeId);
|
||||||
|
if (ni >= 0) removeNode(ni);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
menu.addAction("Copy &Address", [this, nodeId]() {
|
||||||
|
int ni = m_doc->tree.indexOfId(nodeId);
|
||||||
|
if (ni < 0) return;
|
||||||
|
uint64_t addr = m_doc->tree.baseAddress + m_doc->tree.computeOffset(ni);
|
||||||
|
QApplication::clipboard()->setText(
|
||||||
|
QStringLiteral("0x") + QString::number(addr, 16).toUpper());
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addAction("Copy &Offset", [this, nodeId]() {
|
||||||
|
int ni = m_doc->tree.indexOfId(nodeId);
|
||||||
|
if (ni < 0) return;
|
||||||
|
int off = m_doc->tree.nodes[ni].offset;
|
||||||
|
QApplication::clipboard()->setText(
|
||||||
|
QStringLiteral("+0x") + QString::number(off, 16).toUpper().rightJustified(4, '0'));
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::batchRemoveNodes(const QVector<int>& nodeIndices) {
|
||||||
|
QSet<uint64_t> idSet;
|
||||||
|
for (int idx : nodeIndices) {
|
||||||
|
if (idx >= 0 && idx < m_doc->tree.nodes.size())
|
||||||
|
idSet.insert(m_doc->tree.nodes[idx].id);
|
||||||
|
}
|
||||||
|
idSet = m_doc->tree.normalizePreferAncestors(idSet);
|
||||||
|
if (idSet.isEmpty()) return;
|
||||||
|
m_doc->undoStack.beginMacro(QString("Delete %1 nodes").arg(idSet.size()));
|
||||||
|
for (uint64_t id : idSet) {
|
||||||
|
int idx = m_doc->tree.indexOfId(id);
|
||||||
|
if (idx >= 0) removeNode(idx);
|
||||||
|
}
|
||||||
|
m_doc->undoStack.endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::batchChangeKind(const QVector<int>& nodeIndices, NodeKind newKind) {
|
||||||
|
QSet<uint64_t> idSet;
|
||||||
|
for (int idx : nodeIndices) {
|
||||||
|
if (idx >= 0 && idx < m_doc->tree.nodes.size())
|
||||||
|
idSet.insert(m_doc->tree.nodes[idx].id);
|
||||||
|
}
|
||||||
|
idSet = m_doc->tree.normalizePreferDescendants(idSet);
|
||||||
|
if (idSet.isEmpty()) return;
|
||||||
|
m_doc->undoStack.beginMacro(QString("Change type of %1 nodes").arg(idSet.size()));
|
||||||
|
for (uint64_t id : idSet) {
|
||||||
|
int idx = m_doc->tree.indexOfId(id);
|
||||||
|
if (idx >= 0) changeNodeKind(idx, newKind);
|
||||||
|
}
|
||||||
|
m_doc->undoStack.endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::handleNodeClick(RcxEditor* source, int line,
|
||||||
|
uint64_t nodeId,
|
||||||
|
Qt::KeyboardModifiers mods) {
|
||||||
|
bool ctrl = mods & Qt::ControlModifier;
|
||||||
|
bool shift = mods & Qt::ShiftModifier;
|
||||||
|
|
||||||
|
if (!ctrl && !shift) {
|
||||||
|
m_selIds.clear();
|
||||||
|
m_selIds.insert(nodeId);
|
||||||
|
m_anchorLine = line;
|
||||||
|
} else if (ctrl && !shift) {
|
||||||
|
if (m_selIds.contains(nodeId))
|
||||||
|
m_selIds.remove(nodeId);
|
||||||
|
else
|
||||||
|
m_selIds.insert(nodeId);
|
||||||
|
m_anchorLine = line;
|
||||||
|
} else if (shift && !ctrl) {
|
||||||
|
m_selIds.clear();
|
||||||
|
int from = qMin(m_anchorLine, line);
|
||||||
|
int to = qMax(m_anchorLine, line);
|
||||||
|
for (int i = from; i <= to && i < m_lastResult.meta.size(); i++) {
|
||||||
|
uint64_t nid = m_lastResult.meta[i].nodeId;
|
||||||
|
if (nid != 0) m_selIds.insert(nid);
|
||||||
|
}
|
||||||
|
} else { // Ctrl+Shift
|
||||||
|
int from = qMin(m_anchorLine, line);
|
||||||
|
int to = qMax(m_anchorLine, line);
|
||||||
|
for (int i = from; i <= to && i < m_lastResult.meta.size(); i++) {
|
||||||
|
uint64_t nid = m_lastResult.meta[i].nodeId;
|
||||||
|
if (nid != 0) m_selIds.insert(nid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applySelectionOverlays();
|
||||||
|
|
||||||
|
if (m_selIds.size() == 1) {
|
||||||
|
uint64_t sid = *m_selIds.begin();
|
||||||
|
int idx = m_doc->tree.indexOfId(sid);
|
||||||
|
if (idx >= 0) emit nodeSelected(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::clearSelection() {
|
||||||
|
m_selIds.clear();
|
||||||
|
m_anchorLine = -1;
|
||||||
|
applySelectionOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::applySelectionOverlays() {
|
||||||
|
for (auto* editor : m_editors)
|
||||||
|
editor->applySelectionOverlay(m_selIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxController::handleMarginClick(RcxEditor* editor, int margin,
|
||||||
|
int line, Qt::KeyboardModifiers) {
|
||||||
|
const LineMeta* lm = editor->metaForLine(line);
|
||||||
|
if (!lm) return;
|
||||||
|
|
||||||
|
if (lm->foldHead && (margin == 0 || margin == 1)) {
|
||||||
|
toggleCollapse(lm->nodeIdx);
|
||||||
|
} else if (margin == 0 || margin == 1) {
|
||||||
|
emit nodeSelected(lm->nodeIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
99
src/controller.h
Normal file
99
src/controller.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUndoStack>
|
||||||
|
#include <QUndoCommand>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class QSplitter;
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
class RcxController;
|
||||||
|
|
||||||
|
// ── Document ──
|
||||||
|
|
||||||
|
class RcxDocument : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RcxDocument(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
NodeTree tree;
|
||||||
|
std::unique_ptr<Provider> provider;
|
||||||
|
QUndoStack undoStack;
|
||||||
|
QString filePath;
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
ComposeResult compose() const;
|
||||||
|
bool save(const QString& path);
|
||||||
|
bool load(const QString& path);
|
||||||
|
void loadData(const QString& binaryPath);
|
||||||
|
void loadData(const QByteArray& data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void documentChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Undo command ──
|
||||||
|
|
||||||
|
class RcxCommand : public QUndoCommand {
|
||||||
|
public:
|
||||||
|
RcxCommand(RcxController* ctrl, Command cmd);
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
private:
|
||||||
|
RcxController* m_ctrl;
|
||||||
|
Command m_cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Controller ──
|
||||||
|
|
||||||
|
class RcxController : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RcxController(RcxDocument* doc, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
RcxEditor* primaryEditor() const;
|
||||||
|
RcxEditor* addSplitEditor(QSplitter* splitter);
|
||||||
|
void removeSplitEditor(RcxEditor* editor);
|
||||||
|
QList<RcxEditor*> editors() const { return m_editors; }
|
||||||
|
|
||||||
|
void changeNodeKind(int nodeIdx, NodeKind newKind);
|
||||||
|
void renameNode(int nodeIdx, const QString& newName);
|
||||||
|
void insertNode(uint64_t parentId, int offset, NodeKind kind, const QString& name);
|
||||||
|
void removeNode(int nodeIdx);
|
||||||
|
void toggleCollapse(int nodeIdx);
|
||||||
|
void setNodeValue(int nodeIdx, int subLine, const QString& text);
|
||||||
|
void duplicateNode(int nodeIdx);
|
||||||
|
void showContextMenu(RcxEditor* editor, int line, int nodeIdx, int subLine, const QPoint& globalPos);
|
||||||
|
void batchRemoveNodes(const QVector<int>& nodeIndices);
|
||||||
|
void batchChangeKind(const QVector<int>& nodeIndices, NodeKind newKind);
|
||||||
|
|
||||||
|
void applyCommand(const Command& cmd, bool isUndo);
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
// Selection
|
||||||
|
void handleNodeClick(RcxEditor* source, int line, uint64_t nodeId,
|
||||||
|
Qt::KeyboardModifiers mods);
|
||||||
|
void clearSelection();
|
||||||
|
void applySelectionOverlays();
|
||||||
|
QSet<uint64_t> selectedIds() const { return m_selIds; }
|
||||||
|
|
||||||
|
RcxDocument* document() const { return m_doc; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void nodeSelected(int nodeIdx);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RcxDocument* m_doc;
|
||||||
|
QList<RcxEditor*> m_editors;
|
||||||
|
ComposeResult m_lastResult;
|
||||||
|
QSet<uint64_t> m_selIds;
|
||||||
|
int m_anchorLine = -1;
|
||||||
|
|
||||||
|
void connectEditor(RcxEditor* editor);
|
||||||
|
void handleMarginClick(RcxEditor* editor, int margin, int line, Qt::KeyboardModifiers mods);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
521
src/core.h
Normal file
521
src/core.h
Normal file
@@ -0,0 +1,521 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QSet>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
// ── Node kind enum ──
|
||||||
|
|
||||||
|
enum class NodeKind : uint8_t {
|
||||||
|
Hex8, Hex16, Hex32, Hex64,
|
||||||
|
Int8, Int16, Int32, Int64,
|
||||||
|
UInt8, UInt16, UInt32, UInt64,
|
||||||
|
Float, Double, Bool,
|
||||||
|
Pointer32, Pointer64,
|
||||||
|
Vec2, Vec3, Vec4, Mat4x4,
|
||||||
|
UTF8, UTF16,
|
||||||
|
Padding,
|
||||||
|
Struct, Array
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Unified kind metadata table (single source of truth) ──
|
||||||
|
|
||||||
|
struct KindMeta {
|
||||||
|
NodeKind kind;
|
||||||
|
const char* name; // UI/JSON name: "Hex64", "UInt16"
|
||||||
|
const char* typeName; // display name: "Hex64", "uint16_t"
|
||||||
|
int size; // byte size (0 = dynamic: Struct/Array)
|
||||||
|
int lines; // display line count
|
||||||
|
int align; // natural alignment
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr KindMeta kKindMeta[] = {
|
||||||
|
// kind name typeName sz ln al
|
||||||
|
{NodeKind::Hex8, "Hex8", "Hex8", 1, 1, 1},
|
||||||
|
{NodeKind::Hex16, "Hex16", "Hex16", 2, 1, 2},
|
||||||
|
{NodeKind::Hex32, "Hex32", "Hex32", 4, 1, 4},
|
||||||
|
{NodeKind::Hex64, "Hex64", "Hex64", 8, 1, 8},
|
||||||
|
{NodeKind::Int8, "Int8", "int8_t", 1, 1, 1},
|
||||||
|
{NodeKind::Int16, "Int16", "int16_t", 2, 1, 2},
|
||||||
|
{NodeKind::Int32, "Int32", "int32_t", 4, 1, 4},
|
||||||
|
{NodeKind::Int64, "Int64", "int64_t", 8, 1, 8},
|
||||||
|
{NodeKind::UInt8, "UInt8", "uint8_t", 1, 1, 1},
|
||||||
|
{NodeKind::UInt16, "UInt16", "uint16_t", 2, 1, 2},
|
||||||
|
{NodeKind::UInt32, "UInt32", "uint32_t", 4, 1, 4},
|
||||||
|
{NodeKind::UInt64, "UInt64", "uint64_t", 8, 1, 8},
|
||||||
|
{NodeKind::Float, "Float", "float", 4, 1, 4},
|
||||||
|
{NodeKind::Double, "Double", "double", 8, 1, 8},
|
||||||
|
{NodeKind::Bool, "Bool", "bool", 1, 1, 1},
|
||||||
|
{NodeKind::Pointer32, "Pointer32", "ptr32", 4, 1, 4},
|
||||||
|
{NodeKind::Pointer64, "Pointer64", "ptr64", 8, 1, 8},
|
||||||
|
{NodeKind::Vec2, "Vec2", "Vec2", 8, 2, 4},
|
||||||
|
{NodeKind::Vec3, "Vec3", "Vec3", 12, 3, 4},
|
||||||
|
{NodeKind::Vec4, "Vec4", "Vec4", 16, 4, 4},
|
||||||
|
{NodeKind::Mat4x4, "Mat4x4", "Mat4x4", 64, 4, 4},
|
||||||
|
{NodeKind::UTF8, "UTF8", "char[]", 1, 1, 1},
|
||||||
|
{NodeKind::UTF16, "UTF16", "wchar_t[]", 2, 1, 2},
|
||||||
|
{NodeKind::Padding, "Padding", "pad", 1, 1, 1},
|
||||||
|
{NodeKind::Struct, "Struct", "struct", 0, 1, 1},
|
||||||
|
{NodeKind::Array, "Array", "array", 0, 1, 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr const KindMeta* kindMeta(NodeKind k) {
|
||||||
|
for (const auto& m : kKindMeta)
|
||||||
|
if (m.kind == k) return &m;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr int sizeForKind(NodeKind k) { auto* m = kindMeta(k); return m ? m->size : 0; }
|
||||||
|
inline constexpr int linesForKind(NodeKind k) { auto* m = kindMeta(k); return m ? m->lines : 1; }
|
||||||
|
inline constexpr int alignmentFor(NodeKind k) { auto* m = kindMeta(k); return m ? m->align : 1; }
|
||||||
|
|
||||||
|
inline const char* kindToString(NodeKind k) {
|
||||||
|
auto* m = kindMeta(k);
|
||||||
|
return m ? m->name : "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NodeKind kindFromString(const QString& s) {
|
||||||
|
for (const auto& m : kKindMeta)
|
||||||
|
if (s == m.name) return m.kind;
|
||||||
|
return NodeKind::Hex8;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NodeKind kindFromTypeName(const QString& s, bool* ok = nullptr) {
|
||||||
|
for (const auto& m : kKindMeta) {
|
||||||
|
if (s == m.typeName) {
|
||||||
|
if (ok) *ok = true;
|
||||||
|
return m.kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) *ok = false;
|
||||||
|
return NodeKind::Hex8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Marker vocabulary ──
|
||||||
|
|
||||||
|
enum Marker : int {
|
||||||
|
M_CONT = 0,
|
||||||
|
M_PAD = 1,
|
||||||
|
M_PTR0 = 2,
|
||||||
|
M_CYCLE = 3,
|
||||||
|
M_ERR = 4,
|
||||||
|
M_STRUCT_BG = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Provider interface ──
|
||||||
|
|
||||||
|
class Provider {
|
||||||
|
public:
|
||||||
|
virtual ~Provider() = default;
|
||||||
|
virtual uint8_t readU8 (uint64_t addr) const = 0;
|
||||||
|
virtual uint16_t readU16(uint64_t addr) const = 0;
|
||||||
|
virtual uint32_t readU32(uint64_t addr) const = 0;
|
||||||
|
virtual uint64_t readU64(uint64_t addr) const = 0;
|
||||||
|
virtual float readF32(uint64_t addr) const = 0;
|
||||||
|
virtual double readF64(uint64_t addr) const = 0;
|
||||||
|
virtual QByteArray readBytes(uint64_t addr, int len) const = 0;
|
||||||
|
virtual bool isValid() const = 0;
|
||||||
|
virtual bool isReadable(uint64_t addr, int len) const = 0;
|
||||||
|
virtual int size() const = 0;
|
||||||
|
virtual bool isWritable() const { return false; }
|
||||||
|
virtual bool writeBytes(uint64_t addr, const QByteArray& data) {
|
||||||
|
Q_UNUSED(addr); Q_UNUSED(data); return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileProvider : public Provider {
|
||||||
|
QByteArray m_data;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T readT(uint64_t a) const {
|
||||||
|
if (a + sizeof(T) > (uint64_t)m_data.size()) return T{};
|
||||||
|
T v; memcpy(&v, m_data.data() + a, sizeof(T)); return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileProvider(const QByteArray& data) : m_data(data) {}
|
||||||
|
static FileProvider fromFile(const QString& path) {
|
||||||
|
QFile f(path);
|
||||||
|
if (f.open(QIODevice::ReadOnly)) return FileProvider(f.readAll());
|
||||||
|
return FileProvider({});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const override { return !m_data.isEmpty(); }
|
||||||
|
bool isReadable(uint64_t addr, int len) const override {
|
||||||
|
if (len <= 0) return len == 0;
|
||||||
|
if (addr > (uint64_t)m_data.size()) return false;
|
||||||
|
return (uint64_t)len <= (uint64_t)m_data.size() - addr;
|
||||||
|
}
|
||||||
|
int size() const override { return m_data.size(); }
|
||||||
|
|
||||||
|
uint8_t readU8 (uint64_t a) const override { return readT<uint8_t>(a); }
|
||||||
|
uint16_t readU16(uint64_t a) const override { return readT<uint16_t>(a); }
|
||||||
|
uint32_t readU32(uint64_t a) const override { return readT<uint32_t>(a); }
|
||||||
|
uint64_t readU64(uint64_t a) const override { return readT<uint64_t>(a); }
|
||||||
|
float readF32(uint64_t a) const override { return readT<float>(a); }
|
||||||
|
double readF64(uint64_t a) const override { return readT<double>(a); }
|
||||||
|
|
||||||
|
QByteArray readBytes(uint64_t a, int len) const override {
|
||||||
|
if (a >= (uint64_t)m_data.size()) return {};
|
||||||
|
int avail = qMin(len, (int)((uint64_t)m_data.size() - a));
|
||||||
|
return m_data.mid((int)a, avail);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWritable() const override { return true; }
|
||||||
|
bool writeBytes(uint64_t addr, const QByteArray& data) override {
|
||||||
|
if (addr + data.size() > (uint64_t)m_data.size()) return false;
|
||||||
|
memcpy(m_data.data() + addr, data.data(), data.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NullProvider : public Provider {
|
||||||
|
public:
|
||||||
|
uint8_t readU8 (uint64_t) const override { return 0; }
|
||||||
|
uint16_t readU16(uint64_t) const override { return 0; }
|
||||||
|
uint32_t readU32(uint64_t) const override { return 0; }
|
||||||
|
uint64_t readU64(uint64_t) const override { return 0; }
|
||||||
|
float readF32(uint64_t) const override { return 0.0f; }
|
||||||
|
double readF64(uint64_t) const override { return 0.0; }
|
||||||
|
QByteArray readBytes(uint64_t, int) const override { return {}; }
|
||||||
|
bool isValid() const override { return false; }
|
||||||
|
bool isReadable(uint64_t, int) const override { return false; }
|
||||||
|
int size() const override { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Node ──
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
uint64_t id = 0;
|
||||||
|
NodeKind kind = NodeKind::Hex8;
|
||||||
|
QString name;
|
||||||
|
uint64_t parentId = 0; // 0 = root (no parent)
|
||||||
|
int offset = 0;
|
||||||
|
int arrayLen = 0;
|
||||||
|
int strLen = 64;
|
||||||
|
bool collapsed = false;
|
||||||
|
uint64_t refId = 0; // Pointer32/64: id of Struct to expand at *ptr
|
||||||
|
|
||||||
|
int byteSize() const {
|
||||||
|
switch (kind) {
|
||||||
|
case NodeKind::UTF8: return strLen;
|
||||||
|
case NodeKind::UTF16: return strLen * 2;
|
||||||
|
case NodeKind::Padding: return qMax(1, arrayLen);
|
||||||
|
default: return sizeForKind(kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject toJson() const {
|
||||||
|
QJsonObject o;
|
||||||
|
o["id"] = QString::number(id);
|
||||||
|
o["kind"] = kindToString(kind);
|
||||||
|
o["name"] = name;
|
||||||
|
o["parentId"] = QString::number(parentId);
|
||||||
|
o["offset"] = offset;
|
||||||
|
o["arrayLen"] = arrayLen;
|
||||||
|
o["strLen"] = strLen;
|
||||||
|
o["collapsed"] = collapsed;
|
||||||
|
o["refId"] = QString::number(refId);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
static Node fromJson(const QJsonObject& o) {
|
||||||
|
Node n;
|
||||||
|
n.id = o["id"].toString("0").toULongLong();
|
||||||
|
n.kind = kindFromString(o["kind"].toString());
|
||||||
|
n.name = o["name"].toString();
|
||||||
|
n.parentId = o["parentId"].toString("0").toULongLong();
|
||||||
|
n.offset = o["offset"].toInt(0);
|
||||||
|
n.arrayLen = o["arrayLen"].toInt(0);
|
||||||
|
n.strLen = o["strLen"].toInt(64);
|
||||||
|
n.collapsed = o["collapsed"].toBool(false);
|
||||||
|
n.refId = o["refId"].toString("0").toULongLong();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── NodeTree ──
|
||||||
|
|
||||||
|
struct NodeTree {
|
||||||
|
QVector<Node> nodes;
|
||||||
|
uint64_t baseAddress = 0x00400000;
|
||||||
|
uint64_t m_nextId = 1;
|
||||||
|
mutable QHash<uint64_t, int> m_idCache;
|
||||||
|
|
||||||
|
int addNode(const Node& n) {
|
||||||
|
Node copy = n;
|
||||||
|
if (copy.id == 0) copy.id = m_nextId++;
|
||||||
|
else if (copy.id >= m_nextId) m_nextId = copy.id + 1;
|
||||||
|
nodes.append(copy);
|
||||||
|
m_idCache.clear();
|
||||||
|
return nodes.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidateIdCache() const { m_idCache.clear(); }
|
||||||
|
|
||||||
|
int indexOfId(uint64_t id) const {
|
||||||
|
if (m_idCache.isEmpty() && !nodes.isEmpty()) {
|
||||||
|
for (int i = 0; i < nodes.size(); i++)
|
||||||
|
m_idCache[nodes[i].id] = i;
|
||||||
|
}
|
||||||
|
return m_idCache.value(id, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> childrenOf(uint64_t parentId) const {
|
||||||
|
QVector<int> result;
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
if (nodes[i].parentId == parentId) result.append(i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect node + all descendants (iterative, cycle-safe)
|
||||||
|
QVector<int> subtreeIndices(uint64_t nodeId) const {
|
||||||
|
int idx = indexOfId(nodeId);
|
||||||
|
if (idx < 0) return {};
|
||||||
|
// Build parent→children map
|
||||||
|
QHash<uint64_t, QVector<int>> childMap;
|
||||||
|
for (int i = 0; i < nodes.size(); i++)
|
||||||
|
childMap[nodes[i].parentId].append(i);
|
||||||
|
// BFS with visited guard
|
||||||
|
QVector<int> result;
|
||||||
|
QSet<uint64_t> visited;
|
||||||
|
QVector<uint64_t> stack;
|
||||||
|
stack.append(nodeId);
|
||||||
|
result.append(idx);
|
||||||
|
visited.insert(nodeId);
|
||||||
|
while (!stack.isEmpty()) {
|
||||||
|
uint64_t pid = stack.takeLast();
|
||||||
|
for (int ci : childMap.value(pid)) {
|
||||||
|
uint64_t cid = nodes[ci].id;
|
||||||
|
if (!visited.contains(cid)) {
|
||||||
|
visited.insert(cid);
|
||||||
|
result.append(ci);
|
||||||
|
stack.append(cid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int depthOf(int idx) const {
|
||||||
|
int d = 0;
|
||||||
|
QSet<int> visited;
|
||||||
|
int cur = idx;
|
||||||
|
while (cur >= 0 && cur < nodes.size() && nodes[cur].parentId != 0) {
|
||||||
|
if (visited.contains(cur)) break;
|
||||||
|
visited.insert(cur);
|
||||||
|
cur = indexOfId(nodes[cur].parentId);
|
||||||
|
if (cur < 0) break;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t computeOffset(int idx) const {
|
||||||
|
int64_t total = 0;
|
||||||
|
QSet<int> visited;
|
||||||
|
int cur = idx;
|
||||||
|
while (cur >= 0 && cur < nodes.size()) {
|
||||||
|
if (visited.contains(cur)) break;
|
||||||
|
visited.insert(cur);
|
||||||
|
total += nodes[cur].offset;
|
||||||
|
if (nodes[cur].parentId == 0) break;
|
||||||
|
cur = indexOfId(nodes[cur].parentId);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int structSpan(uint64_t structId,
|
||||||
|
const QHash<uint64_t, QVector<int>>* childMap = nullptr) const {
|
||||||
|
int maxEnd = 0;
|
||||||
|
QVector<int> kids = childMap ? childMap->value(structId) : childrenOf(structId);
|
||||||
|
for (int ci : kids) {
|
||||||
|
const Node& c = nodes[ci];
|
||||||
|
int sz = (c.kind == NodeKind::Struct || c.kind == NodeKind::Array)
|
||||||
|
? structSpan(c.id, childMap) : c.byteSize();
|
||||||
|
int end = c.offset + sz;
|
||||||
|
if (end > maxEnd) maxEnd = end;
|
||||||
|
}
|
||||||
|
return maxEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch selection normalizers
|
||||||
|
QSet<uint64_t> normalizePreferAncestors(const QSet<uint64_t>& ids) const;
|
||||||
|
QSet<uint64_t> normalizePreferDescendants(const QSet<uint64_t>& ids) const;
|
||||||
|
|
||||||
|
QJsonObject toJson() const {
|
||||||
|
QJsonObject o;
|
||||||
|
o["baseAddress"] = QString::number(baseAddress, 16);
|
||||||
|
o["nextId"] = QString::number(m_nextId);
|
||||||
|
QJsonArray arr;
|
||||||
|
for (const auto& n : nodes) arr.append(n.toJson());
|
||||||
|
o["nodes"] = arr;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NodeTree fromJson(const QJsonObject& o) {
|
||||||
|
NodeTree t;
|
||||||
|
t.baseAddress = o["baseAddress"].toString("400000").toULongLong(nullptr, 16);
|
||||||
|
t.m_nextId = o["nextId"].toString("1").toULongLong();
|
||||||
|
QJsonArray arr = o["nodes"].toArray();
|
||||||
|
for (const auto& v : arr) {
|
||||||
|
Node n = Node::fromJson(v.toObject());
|
||||||
|
t.nodes.append(n);
|
||||||
|
if (n.id >= t.m_nextId) t.m_nextId = n.id + 1;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── LineMeta ──
|
||||||
|
|
||||||
|
enum class LineKind : uint8_t {
|
||||||
|
Header, Field, Continuation, Footer
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LineMeta {
|
||||||
|
int nodeIdx = -1;
|
||||||
|
uint64_t nodeId = 0;
|
||||||
|
int subLine = 0;
|
||||||
|
int depth = 0;
|
||||||
|
int foldLevel = 0;
|
||||||
|
bool foldHead = false;
|
||||||
|
bool foldCollapsed = false;
|
||||||
|
bool isContinuation = false;
|
||||||
|
LineKind lineKind = LineKind::Field;
|
||||||
|
NodeKind nodeKind = NodeKind::Int32;
|
||||||
|
QString offsetText;
|
||||||
|
uint32_t markerMask = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── ComposeResult ──
|
||||||
|
|
||||||
|
struct ComposeResult {
|
||||||
|
QString text;
|
||||||
|
QVector<LineMeta> meta;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Command ──
|
||||||
|
|
||||||
|
namespace cmd {
|
||||||
|
struct OffsetAdj { uint64_t nodeId; int oldOffset, newOffset; };
|
||||||
|
struct ChangeKind { uint64_t nodeId; NodeKind oldKind, newKind;
|
||||||
|
QVector<OffsetAdj> offAdjs; };
|
||||||
|
struct Rename { uint64_t nodeId; QString oldName, newName; };
|
||||||
|
struct Collapse { uint64_t nodeId; bool oldState, newState; };
|
||||||
|
struct Insert { Node node; };
|
||||||
|
struct Remove { uint64_t nodeId; QVector<Node> subtree; };
|
||||||
|
struct ChangeBase { uint64_t oldBase, newBase; };
|
||||||
|
struct WriteBytes { uint64_t addr; QByteArray oldBytes, newBytes; };
|
||||||
|
}
|
||||||
|
|
||||||
|
using Command = std::variant<
|
||||||
|
cmd::ChangeKind, cmd::Rename, cmd::Collapse,
|
||||||
|
cmd::Insert, cmd::Remove, cmd::ChangeBase, cmd::WriteBytes
|
||||||
|
>;
|
||||||
|
|
||||||
|
// ── Column spans (for inline editing) ──
|
||||||
|
|
||||||
|
struct ColumnSpan {
|
||||||
|
int start = 0; // inclusive column index
|
||||||
|
int end = 0; // exclusive column index
|
||||||
|
bool valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EditTarget { Name, Type, Value };
|
||||||
|
|
||||||
|
// Column layout constants (shared with format.cpp span computation)
|
||||||
|
inline constexpr int kFoldCol = 3; // 3-char fold indicator prefix per line
|
||||||
|
inline constexpr int kColType = 10;
|
||||||
|
inline constexpr int kColName = 24;
|
||||||
|
inline constexpr int kSepWidth = 2;
|
||||||
|
|
||||||
|
inline ColumnSpan typeSpanFor(const LineMeta& lm) {
|
||||||
|
if (lm.lineKind != LineKind::Field || lm.isContinuation) return {};
|
||||||
|
int ind = kFoldCol + lm.depth * 3;
|
||||||
|
return {ind, ind + kColType, true};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnSpan nameSpanFor(const LineMeta& lm) {
|
||||||
|
if (lm.isContinuation || lm.lineKind != LineKind::Field) return {};
|
||||||
|
// Hex/Padding nodes show ASCII data preview instead of name
|
||||||
|
switch (lm.nodeKind) {
|
||||||
|
case NodeKind::Hex8: case NodeKind::Hex16:
|
||||||
|
case NodeKind::Hex32: case NodeKind::Hex64:
|
||||||
|
case NodeKind::Padding:
|
||||||
|
return {};
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
int ind = kFoldCol + lm.depth * 3;
|
||||||
|
int start = ind + kColType + kSepWidth;
|
||||||
|
return {start, start + kColName, true};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnSpan valueSpanFor(const LineMeta& lm, int lineLength) {
|
||||||
|
if (lm.lineKind == LineKind::Header || lm.lineKind == LineKind::Footer) return {};
|
||||||
|
int ind = kFoldCol + lm.depth * 3;
|
||||||
|
if (lm.isContinuation) {
|
||||||
|
int prefixW = kColType + kColName + 4; // 2 seps × 2 chars
|
||||||
|
int start = ind + prefixW;
|
||||||
|
return {start, lineLength, start < lineLength};
|
||||||
|
}
|
||||||
|
if (lm.lineKind != LineKind::Field) return {};
|
||||||
|
int start = ind + kColType + kSepWidth + kColName + kSepWidth;
|
||||||
|
return {start, lineLength, start < lineLength};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── ViewState ──
|
||||||
|
|
||||||
|
struct ViewState {
|
||||||
|
int scrollLine = 0;
|
||||||
|
int cursorLine = 0;
|
||||||
|
int cursorCol = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── Format function forward declarations ──
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
using TypeNameFn = QString (*)(NodeKind);
|
||||||
|
void setTypeNameProvider(TypeNameFn fn);
|
||||||
|
QString typeName(NodeKind kind);
|
||||||
|
QString fmtInt8(int8_t v);
|
||||||
|
QString fmtInt16(int16_t v);
|
||||||
|
QString fmtInt32(int32_t v);
|
||||||
|
QString fmtInt64(int64_t v);
|
||||||
|
QString fmtUInt8(uint8_t v);
|
||||||
|
QString fmtUInt16(uint16_t v);
|
||||||
|
QString fmtUInt32(uint32_t v);
|
||||||
|
QString fmtUInt64(uint64_t v);
|
||||||
|
QString fmtFloat(float v);
|
||||||
|
QString fmtDouble(double v);
|
||||||
|
QString fmtBool(uint8_t v);
|
||||||
|
QString fmtPointer32(uint32_t v);
|
||||||
|
QString fmtPointer64(uint64_t v);
|
||||||
|
QString fmtNodeLine(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int depth, int subLine = 0);
|
||||||
|
QString fmtOffsetMargin(int64_t relativeOffset, bool isContinuation);
|
||||||
|
QString fmtStructHeader(const Node& node, int depth);
|
||||||
|
QString fmtStructFooter(const Node& node, int depth, int totalSize = -1);
|
||||||
|
QString indent(int depth);
|
||||||
|
QString readValue(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int subLine);
|
||||||
|
QString editableValue(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int subLine);
|
||||||
|
QByteArray parseValue(NodeKind kind, const QString& text, bool* ok);
|
||||||
|
} // namespace fmt
|
||||||
|
|
||||||
|
// ── Compose function forward declaration ──
|
||||||
|
|
||||||
|
ComposeResult compose(const NodeTree& tree, const Provider& prov);
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
982
src/editor.cpp
Normal file
982
src/editor.cpp
Normal file
@@ -0,0 +1,982 @@
|
|||||||
|
#include "editor.h"
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
#include <Qsci/qsciscintillabase.h>
|
||||||
|
#include <Qsci/qscilexercpp.h>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QFocusEvent>
|
||||||
|
#include <QToolTip>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QCursor>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
// ── Theme constants ──
|
||||||
|
static const QColor kBgText("#1e1e1e");
|
||||||
|
static const QColor kBgMargin("#252526");
|
||||||
|
static const QColor kFgMargin("#858585");
|
||||||
|
static const QColor kFgMarginDim("#505050");
|
||||||
|
|
||||||
|
static constexpr int IND_EDITABLE = 8;
|
||||||
|
static constexpr int IND_HEX_DIM = 9;
|
||||||
|
static constexpr int IND_SELECTED = 10;
|
||||||
|
static constexpr int IND_HOVER = 11;
|
||||||
|
|
||||||
|
static QFont editorFont() {
|
||||||
|
QFont f("Consolas", 12);
|
||||||
|
f.setFixedPitch(true);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
RcxEditor::RcxEditor(QWidget* parent) : QWidget(parent) {
|
||||||
|
auto* layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
m_sci = new QsciScintilla(this);
|
||||||
|
layout->addWidget(m_sci);
|
||||||
|
|
||||||
|
setupScintilla();
|
||||||
|
setupLexer();
|
||||||
|
setupMargins();
|
||||||
|
setupFolding();
|
||||||
|
setupMarkers();
|
||||||
|
allocateMarginStyles();
|
||||||
|
|
||||||
|
m_sci->installEventFilter(this);
|
||||||
|
m_sci->viewport()->installEventFilter(this);
|
||||||
|
m_sci->viewport()->setMouseTracking(true);
|
||||||
|
|
||||||
|
// Hover cursor is applied synchronously in eventFilter (no timer).
|
||||||
|
|
||||||
|
connect(m_sci, &QsciScintilla::marginClicked,
|
||||||
|
this, [this](int margin, int line, Qt::KeyboardModifiers mods) {
|
||||||
|
emit marginClicked(margin, line, mods);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_sci->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_sci, &QWidget::customContextMenuRequested,
|
||||||
|
this, [this](const QPoint& pos) {
|
||||||
|
int line = m_sci->lineAt(pos);
|
||||||
|
int nodeIdx = -1;
|
||||||
|
int subLine = 0;
|
||||||
|
if (line >= 0 && line < m_meta.size()) {
|
||||||
|
nodeIdx = m_meta[line].nodeIdx;
|
||||||
|
subLine = m_meta[line].subLine;
|
||||||
|
}
|
||||||
|
emit contextMenuRequested(line, nodeIdx, subLine, m_sci->mapToGlobal(pos));
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_sci, &QsciScintilla::userListActivated,
|
||||||
|
this, [this](int id, const QString& text) {
|
||||||
|
if (id == 1 && m_editState.active && m_editState.target == EditTarget::Type) {
|
||||||
|
auto info = endInlineEdit();
|
||||||
|
emit inlineEditCommitted(info.nodeIdx, info.subLine, info.target, text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_sci, &QsciScintilla::cursorPositionChanged,
|
||||||
|
this, [this](int line, int /*col*/) { updateEditableUnderline(line); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::setupScintilla() {
|
||||||
|
m_sci->setFont(editorFont());
|
||||||
|
|
||||||
|
m_sci->setReadOnly(true);
|
||||||
|
m_sci->setWrapMode(QsciScintilla::WrapNone);
|
||||||
|
m_sci->setCaretLineVisible(true);
|
||||||
|
m_sci->setCaretLineBackgroundColor(QColor("#2c3338"));
|
||||||
|
|
||||||
|
m_sci->setPaper(kBgText);
|
||||||
|
m_sci->setColor(QColor("#d4d4d4"));
|
||||||
|
|
||||||
|
m_sci->setTabWidth(2);
|
||||||
|
m_sci->setIndentationsUseTabs(false);
|
||||||
|
|
||||||
|
// Caret color for dark theme
|
||||||
|
m_sci->setCaretForegroundColor(QColor("#d4d4d4"));
|
||||||
|
|
||||||
|
// Line spacing for readability
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETEXTRAASCENT, (long)2);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETEXTRADESCENT, (long)2);
|
||||||
|
|
||||||
|
// Selection colors
|
||||||
|
m_sci->setSelectionBackgroundColor(QColor("#264f78"));
|
||||||
|
m_sci->setSelectionForegroundColor(QColor("#d4d4d4"));
|
||||||
|
|
||||||
|
// Editable-field link-style indicator (colored text + underline)
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE,
|
||||||
|
IND_EDITABLE, 17 /*INDIC_TEXTFORE*/);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
|
||||||
|
IND_EDITABLE, QColor("#569cd6"));
|
||||||
|
|
||||||
|
// Hex/Padding node dim indicator — overrides text color to gray
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE,
|
||||||
|
IND_HEX_DIM, 17 /*INDIC_TEXTFORE*/);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
|
||||||
|
IND_HEX_DIM, QColor("#505050"));
|
||||||
|
|
||||||
|
// Selection overlay — translucent blue box
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE,
|
||||||
|
IND_SELECTED, 8 /*INDIC_STRAIGHTBOX*/);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
|
||||||
|
IND_SELECTED, QColor("#264f78"));
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETALPHA,
|
||||||
|
IND_SELECTED, (long)50);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETOUTLINEALPHA,
|
||||||
|
IND_SELECTED, (long)100);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETUNDER,
|
||||||
|
IND_SELECTED, (long)1);
|
||||||
|
|
||||||
|
// Hover row highlight — very subtle fill
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE,
|
||||||
|
IND_HOVER, 16 /*INDIC_FULLBOX*/);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
|
||||||
|
IND_HOVER, QColor("#264f78"));
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETALPHA,
|
||||||
|
IND_HOVER, (long)25);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETOUTLINEALPHA,
|
||||||
|
IND_HOVER, (long)0);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETUNDER,
|
||||||
|
IND_HOVER, (long)1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::setupLexer() {
|
||||||
|
m_lexer = new QsciLexerCPP(m_sci);
|
||||||
|
QFont font = editorFont();
|
||||||
|
m_lexer->setFont(font);
|
||||||
|
|
||||||
|
// Dark theme colors
|
||||||
|
m_lexer->setColor(QColor("#569cd6"), QsciLexerCPP::Keyword);
|
||||||
|
m_lexer->setColor(QColor("#4ec9b0"), QsciLexerCPP::KeywordSet2);
|
||||||
|
m_lexer->setColor(QColor("#b5cea8"), QsciLexerCPP::Number);
|
||||||
|
m_lexer->setColor(QColor("#ce9178"), QsciLexerCPP::DoubleQuotedString);
|
||||||
|
m_lexer->setColor(QColor("#ce9178"), QsciLexerCPP::SingleQuotedString);
|
||||||
|
m_lexer->setColor(QColor("#6a9955"), QsciLexerCPP::Comment);
|
||||||
|
m_lexer->setColor(QColor("#6a9955"), QsciLexerCPP::CommentLine);
|
||||||
|
m_lexer->setColor(QColor("#6a9955"), QsciLexerCPP::CommentDoc);
|
||||||
|
m_lexer->setColor(QColor("#d4d4d4"), QsciLexerCPP::Default);
|
||||||
|
m_lexer->setColor(QColor("#dcdcaa"), QsciLexerCPP::Identifier);
|
||||||
|
m_lexer->setColor(QColor("#c586c0"), QsciLexerCPP::PreProcessor);
|
||||||
|
m_lexer->setColor(QColor("#d4d4d4"), QsciLexerCPP::Operator);
|
||||||
|
|
||||||
|
// Dark background for all styles
|
||||||
|
for (int i = 0; i <= 127; i++) {
|
||||||
|
m_lexer->setPaper(kBgText, i);
|
||||||
|
m_lexer->setFont(font, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sci->setLexer(m_lexer);
|
||||||
|
m_sci->setBraceMatching(QsciScintilla::SloppyBraceMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::setupMargins() {
|
||||||
|
m_sci->setMarginsFont(editorFont());
|
||||||
|
|
||||||
|
// Margin 0: Offset text
|
||||||
|
m_sci->setMarginType(0, QsciScintilla::TextMarginRightJustified);
|
||||||
|
m_sci->setMarginWidth(0, " +0x00000000 ");
|
||||||
|
m_sci->setMarginsBackgroundColor(kBgMargin);
|
||||||
|
m_sci->setMarginsForegroundColor(kFgMargin);
|
||||||
|
m_sci->setMarginSensitivity(0, true);
|
||||||
|
|
||||||
|
// Margin 1: hidden (fold chevrons moved to text column)
|
||||||
|
m_sci->setMarginWidth(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::setupFolding() {
|
||||||
|
// Hide fold margin (fold indicators are text-based now)
|
||||||
|
m_sci->setMarginWidth(2, 0);
|
||||||
|
m_sci->setFoldMarginColors(kBgMargin, kBgMargin);
|
||||||
|
|
||||||
|
// Fold indicators are now text in the line content (kFoldCol prefix),
|
||||||
|
// so no Scintilla markers needed for fold state.
|
||||||
|
|
||||||
|
// Keep Scintilla fold markers invisible (fold levels still used for click detection)
|
||||||
|
for (int i = 25; i <= 31; i++)
|
||||||
|
m_sci->markerDefine(QsciScintilla::Invisible, i);
|
||||||
|
|
||||||
|
// Disable automatic fold toggle — we handle collapse at model level
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETAUTOMATICFOLD,
|
||||||
|
(unsigned long)0);
|
||||||
|
|
||||||
|
// Disable lexer-driven folding — we set fold levels manually
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETPROPERTY,
|
||||||
|
(const char*)"fold", (const char*)"0");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::setupMarkers() {
|
||||||
|
// M_CONT (0): vertical line
|
||||||
|
m_sci->markerDefine(QsciScintilla::VLine, M_CONT);
|
||||||
|
m_sci->setMarkerBackgroundColor(kFgMarginDim, M_CONT);
|
||||||
|
m_sci->setMarkerForegroundColor(kFgMarginDim, M_CONT);
|
||||||
|
|
||||||
|
// M_PAD (1): small rectangle (dim gray)
|
||||||
|
m_sci->markerDefine(QsciScintilla::SmallRectangle, M_PAD);
|
||||||
|
m_sci->setMarkerBackgroundColor(QColor("#606060"), M_PAD);
|
||||||
|
m_sci->setMarkerForegroundColor(QColor("#606060"), M_PAD);
|
||||||
|
|
||||||
|
// M_PTR0 (2): right triangle (red)
|
||||||
|
m_sci->markerDefine(QsciScintilla::RightTriangle, M_PTR0);
|
||||||
|
m_sci->setMarkerBackgroundColor(QColor("#f44747"), M_PTR0);
|
||||||
|
m_sci->setMarkerForegroundColor(QColor("#f44747"), M_PTR0);
|
||||||
|
|
||||||
|
// M_CYCLE (3): arrows (orange)
|
||||||
|
m_sci->markerDefine(QsciScintilla::ThreeRightArrows, M_CYCLE);
|
||||||
|
m_sci->setMarkerBackgroundColor(QColor("#e5a00d"), M_CYCLE);
|
||||||
|
m_sci->setMarkerForegroundColor(QColor("#e5a00d"), M_CYCLE);
|
||||||
|
|
||||||
|
// M_ERR (4): background (dark red)
|
||||||
|
m_sci->markerDefine(QsciScintilla::Background, M_ERR);
|
||||||
|
m_sci->setMarkerBackgroundColor(QColor("#5c2020"), M_ERR);
|
||||||
|
m_sci->setMarkerForegroundColor(QColor("#ffffff"), M_ERR);
|
||||||
|
|
||||||
|
// M_STRUCT_BG (5): background tint for struct header/footer
|
||||||
|
m_sci->markerDefine(QsciScintilla::Background, M_STRUCT_BG);
|
||||||
|
m_sci->setMarkerBackgroundColor(QColor("#1a2332"), M_STRUCT_BG);
|
||||||
|
m_sci->setMarkerForegroundColor(QColor("#d4d4d4"), M_STRUCT_BG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::allocateMarginStyles() {
|
||||||
|
// Relative indices within margin style offset
|
||||||
|
static constexpr int MSTYLE_NORMAL = 0;
|
||||||
|
static constexpr int MSTYLE_CONT = 1;
|
||||||
|
|
||||||
|
long base = m_sci->SendScintilla(QsciScintillaBase::SCI_ALLOCATEEXTENDEDSTYLES, (long)2);
|
||||||
|
m_marginStyleBase = (int)base;
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_MARGINSETSTYLEOFFSET, base);
|
||||||
|
|
||||||
|
const long bgrMargin = 0x262525; // BGR for #252526
|
||||||
|
|
||||||
|
// Normal offset style: gray on dark
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_STYLESETFORE,
|
||||||
|
(unsigned long)(base + MSTYLE_NORMAL), (long)0x858585);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_STYLESETBACK,
|
||||||
|
(unsigned long)(base + MSTYLE_NORMAL), bgrMargin);
|
||||||
|
|
||||||
|
// Continuation style: dimmer
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_STYLESETFORE,
|
||||||
|
(unsigned long)(base + MSTYLE_CONT), (long)0x505050);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_STYLESETBACK,
|
||||||
|
(unsigned long)(base + MSTYLE_CONT), bgrMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyDocument(const ComposeResult& result) {
|
||||||
|
// Silently deactivate inline edit (no signal — refresh is already happening)
|
||||||
|
if (m_editState.active)
|
||||||
|
endInlineEdit();
|
||||||
|
|
||||||
|
m_meta = result.meta;
|
||||||
|
|
||||||
|
m_sci->setReadOnly(false);
|
||||||
|
m_sci->setText(result.text);
|
||||||
|
m_sci->setReadOnly(true);
|
||||||
|
|
||||||
|
// Force full re-lex to fix stale syntax coloring after edits
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, (uintptr_t)0, (long)-1);
|
||||||
|
|
||||||
|
applyMarginText(result.meta);
|
||||||
|
applyMarkers(result.meta);
|
||||||
|
applyFoldLevels(result.meta);
|
||||||
|
applyHexDimming(result.meta);
|
||||||
|
|
||||||
|
// Re-apply editable underline for current cursor line
|
||||||
|
m_hintLine = -1;
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
updateEditableUnderline(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyMarginText(const QVector<LineMeta>& meta) {
|
||||||
|
// Clear all margin text
|
||||||
|
m_sci->clearMarginText(-1);
|
||||||
|
|
||||||
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
|
const auto& lm = meta[i];
|
||||||
|
if (!lm.offsetText.isEmpty()) {
|
||||||
|
int style = lm.isContinuation ? 1 : 0;
|
||||||
|
m_sci->setMarginText(i, lm.offsetText, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyMarkers(const QVector<LineMeta>& meta) {
|
||||||
|
for (int m = M_CONT; m <= M_STRUCT_BG; m++) {
|
||||||
|
m_sci->markerDeleteAll(m);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
|
uint32_t mask = meta[i].markerMask;
|
||||||
|
for (int m = M_CONT; m <= M_STRUCT_BG; m++) {
|
||||||
|
if (mask & (1u << m)) {
|
||||||
|
m_sci->markerAdd(i, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyFoldLevels(const QVector<LineMeta>& meta) {
|
||||||
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETFOLDLEVEL,
|
||||||
|
(unsigned long)i, (long)meta[i].foldLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyHexDimming(const QVector<LineMeta>& meta) {
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_HEX_DIM);
|
||||||
|
for (int i = 0; i < meta.size(); i++) {
|
||||||
|
switch (meta[i].nodeKind) {
|
||||||
|
case NodeKind::Hex8: case NodeKind::Hex16:
|
||||||
|
case NodeKind::Hex32: case NodeKind::Hex64:
|
||||||
|
case NodeKind::Padding: {
|
||||||
|
long pos = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)i);
|
||||||
|
long len = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINELENGTH, (unsigned long)i);
|
||||||
|
if (len > 0)
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, pos, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applySelectionOverlay(const QSet<uint64_t>& selIds) {
|
||||||
|
m_currentSelIds = selIds;
|
||||||
|
|
||||||
|
// Clear all selection indicators
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_SELECTED);
|
||||||
|
long docLen = m_sci->SendScintilla(QsciScintillaBase::SCI_GETLENGTH);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE, (uintptr_t)0, docLen);
|
||||||
|
|
||||||
|
if (selIds.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_meta.size(); i++) {
|
||||||
|
if (selIds.contains(m_meta[i].nodeId)) {
|
||||||
|
long pos = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)i);
|
||||||
|
long len = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINELENGTH, (unsigned long)i);
|
||||||
|
if (len > 0)
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, pos, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh hover since selection may suppress it
|
||||||
|
applyHoverHighlight();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::applyHoverHighlight() {
|
||||||
|
// Clear previous hover indicator
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_HOVER);
|
||||||
|
long docLen = m_sci->SendScintilla(QsciScintillaBase::SCI_GETLENGTH);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE, (uintptr_t)0, docLen);
|
||||||
|
|
||||||
|
if (m_editState.active) return;
|
||||||
|
if (!m_hoverInside) return;
|
||||||
|
if (m_hoveredNodeId == 0) return;
|
||||||
|
if (m_currentSelIds.contains(m_hoveredNodeId)) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_meta.size(); i++) {
|
||||||
|
if (m_meta[i].nodeId == m_hoveredNodeId) {
|
||||||
|
long pos = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)i);
|
||||||
|
long len = m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINELENGTH, (unsigned long)i);
|
||||||
|
if (len > 0)
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, pos, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewState RcxEditor::saveViewState() const {
|
||||||
|
ViewState vs;
|
||||||
|
vs.scrollLine = (int)m_sci->SendScintilla(QsciScintillaBase::SCI_GETFIRSTVISIBLELINE);
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
vs.cursorLine = line;
|
||||||
|
vs.cursorCol = col;
|
||||||
|
return vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RcxEditor::restoreViewState(const ViewState& vs) {
|
||||||
|
m_sci->setCursorPosition(vs.cursorLine, vs.cursorCol);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETFIRSTVISIBLELINE,
|
||||||
|
(unsigned long)vs.scrollLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LineMeta* RcxEditor::metaForLine(int line) const {
|
||||||
|
if (line >= 0 && line < m_meta.size())
|
||||||
|
return &m_meta[line];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RcxEditor::currentNodeIndex() const {
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
auto* lm = metaForLine(line);
|
||||||
|
return lm ? lm->nodeIdx : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Column span computation ──
|
||||||
|
|
||||||
|
ColumnSpan RcxEditor::typeSpan(const LineMeta& lm) { return typeSpanFor(lm); }
|
||||||
|
ColumnSpan RcxEditor::nameSpan(const LineMeta& lm) { return nameSpanFor(lm); }
|
||||||
|
ColumnSpan RcxEditor::valueSpan(const LineMeta& lm, int lineLength) { return valueSpanFor(lm, lineLength); }
|
||||||
|
|
||||||
|
// ── Multi-selection ──
|
||||||
|
|
||||||
|
QSet<int> RcxEditor::selectedNodeIndices() const {
|
||||||
|
int lineFrom, indexFrom, lineTo, indexTo;
|
||||||
|
m_sci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
|
||||||
|
if (lineFrom < 0) {
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
auto* lm = metaForLine(line);
|
||||||
|
return lm && lm->nodeIdx >= 0 ? QSet<int>{lm->nodeIdx} : QSet<int>{};
|
||||||
|
}
|
||||||
|
QSet<int> result;
|
||||||
|
for (int line = lineFrom; line <= lineTo; line++) {
|
||||||
|
auto* lm = metaForLine(line);
|
||||||
|
if (lm && lm->nodeIdx >= 0) result.insert(lm->nodeIdx);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Inline edit helpers ──
|
||||||
|
|
||||||
|
static QString getLineText(QsciScintilla* sci, int line) {
|
||||||
|
int len = (int)sci->SendScintilla(QsciScintillaBase::SCI_LINELENGTH, (unsigned long)line);
|
||||||
|
if (len <= 0) return {};
|
||||||
|
QByteArray buf(len + 1, '\0');
|
||||||
|
sci->SendScintilla(QsciScintillaBase::SCI_GETLINE, (unsigned long)line, (void*)buf.data());
|
||||||
|
QString text = QString::fromUtf8(buf.data(), len);
|
||||||
|
while (text.endsWith('\n') || text.endsWith('\r'))
|
||||||
|
text.chop(1);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Shared inline-edit shutdown ──
|
||||||
|
|
||||||
|
RcxEditor::EndEditInfo RcxEditor::endInlineEdit() {
|
||||||
|
EndEditInfo info{m_editState.nodeIdx, m_editState.subLine, m_editState.target};
|
||||||
|
m_editState.active = false;
|
||||||
|
m_sci->setReadOnly(true);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETUNDOCOLLECTION, (long)1);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_EMPTYUNDOBUFFER);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Span helpers ──
|
||||||
|
|
||||||
|
static ColumnSpan headerNameSpan(const LineMeta& lm, const QString& lineText) {
|
||||||
|
if (lm.lineKind != LineKind::Header) return {};
|
||||||
|
int bracePos = lineText.lastIndexOf(QStringLiteral(" {"));
|
||||||
|
if (bracePos <= 0) return {};
|
||||||
|
int ind = kFoldCol + lm.depth * 3;
|
||||||
|
int typeEnd = lineText.indexOf(' ', ind);
|
||||||
|
if (typeEnd <= ind || typeEnd >= bracePos) return {};
|
||||||
|
return {typeEnd + 1, bracePos, true};
|
||||||
|
}
|
||||||
|
|
||||||
|
RcxEditor::NormalizedSpan RcxEditor::normalizeSpan(
|
||||||
|
const ColumnSpan& raw, const QString& lineText,
|
||||||
|
EditTarget target, bool skipPrefixes) const
|
||||||
|
{
|
||||||
|
if (!raw.valid) return {};
|
||||||
|
int textLen = lineText.size();
|
||||||
|
if (raw.start >= textLen) return {};
|
||||||
|
|
||||||
|
int start = raw.start;
|
||||||
|
int end = qMin(raw.end, textLen);
|
||||||
|
if (end <= start) return {};
|
||||||
|
|
||||||
|
if (skipPrefixes && target == EditTarget::Value) {
|
||||||
|
QString spanText = lineText.mid(start, end - start);
|
||||||
|
int arrow = spanText.indexOf(QStringLiteral("->"));
|
||||||
|
if (arrow >= 0) {
|
||||||
|
int i = arrow + 2;
|
||||||
|
while (i < spanText.size() && spanText[i].isSpace()) i++;
|
||||||
|
start += i;
|
||||||
|
} else {
|
||||||
|
int eq = spanText.indexOf('=');
|
||||||
|
if (eq >= 0 && eq <= 3) {
|
||||||
|
int i = eq + 1;
|
||||||
|
while (i < spanText.size() && spanText[i].isSpace()) i++;
|
||||||
|
start += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start >= end) return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString inner = lineText.mid(start, end - start);
|
||||||
|
int lead = 0;
|
||||||
|
while (lead < inner.size() && inner[lead].isSpace()) lead++;
|
||||||
|
int trail = inner.size();
|
||||||
|
while (trail > lead && inner[trail - 1].isSpace()) trail--;
|
||||||
|
if (trail <= lead) return {};
|
||||||
|
|
||||||
|
return {start + lead, start + trail, true};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Double-click hit test ──
|
||||||
|
|
||||||
|
static bool hitTestTarget(QsciScintilla* sci,
|
||||||
|
const QVector<LineMeta>& meta,
|
||||||
|
const QPoint& viewportPos,
|
||||||
|
int& outLine, EditTarget& outTarget)
|
||||||
|
{
|
||||||
|
long pos = sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMPOINTCLOSE,
|
||||||
|
(unsigned long)viewportPos.x(), (long)viewportPos.y());
|
||||||
|
if (pos < 0) return false;
|
||||||
|
int line = (int)sci->SendScintilla(QsciScintillaBase::SCI_LINEFROMPOSITION,
|
||||||
|
(unsigned long)pos);
|
||||||
|
int col = (int)sci->SendScintilla(QsciScintillaBase::SCI_GETCOLUMN,
|
||||||
|
(unsigned long)pos);
|
||||||
|
if (line < 0 || line >= meta.size()) return false;
|
||||||
|
|
||||||
|
QString lineText = getLineText(sci, line);
|
||||||
|
int textLen = lineText.size();
|
||||||
|
|
||||||
|
const LineMeta& lm = meta[line];
|
||||||
|
ColumnSpan ts = RcxEditor::typeSpan(lm);
|
||||||
|
ColumnSpan ns = RcxEditor::nameSpan(lm);
|
||||||
|
ColumnSpan vs = RcxEditor::valueSpan(lm, textLen);
|
||||||
|
|
||||||
|
if (!ns.valid)
|
||||||
|
ns = headerNameSpan(lm, lineText);
|
||||||
|
|
||||||
|
auto inSpan = [&](const ColumnSpan& s) {
|
||||||
|
return s.valid && col >= s.start && col < s.end;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (inSpan(ts)) outTarget = EditTarget::Type;
|
||||||
|
else if (inSpan(ns)) outTarget = EditTarget::Name;
|
||||||
|
else if (inSpan(vs)) outTarget = EditTarget::Value;
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
outLine = line;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Event filter ──
|
||||||
|
|
||||||
|
bool RcxEditor::eventFilter(QObject* obj, QEvent* event) {
|
||||||
|
if (obj == m_sci && event->type() == QEvent::KeyPress) {
|
||||||
|
auto* ke = static_cast<QKeyEvent*>(event);
|
||||||
|
return m_editState.active ? handleEditKey(ke) : handleNormalKey(ke);
|
||||||
|
}
|
||||||
|
if (obj == m_sci->viewport() && event->type() == QEvent::MouseButtonPress
|
||||||
|
&& m_editState.active) {
|
||||||
|
// Only commit if click is outside the active edit span
|
||||||
|
auto* me = static_cast<QMouseEvent*>(event);
|
||||||
|
long pos = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMPOINTCLOSE,
|
||||||
|
(unsigned long)me->pos().x(), (long)me->pos().y());
|
||||||
|
bool insideEdit = false;
|
||||||
|
if (pos >= 0) {
|
||||||
|
int clickLine = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINEFROMPOSITION, (unsigned long)pos);
|
||||||
|
int clickCol = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_GETCOLUMN, (unsigned long)pos);
|
||||||
|
if (clickLine == m_editState.line) {
|
||||||
|
QString lineText = getLineText(m_sci, m_editState.line);
|
||||||
|
int delta = lineText.size() - m_editState.linelenAfterReplace;
|
||||||
|
int editEnd = m_editState.spanStart + m_editState.original.size() + delta;
|
||||||
|
insideEdit = (clickCol >= m_editState.spanStart && clickCol < editEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!insideEdit)
|
||||||
|
commitInlineEdit();
|
||||||
|
return false; // always let click through to Scintilla
|
||||||
|
}
|
||||||
|
// Single-click on fold column (" - " / " + ") toggles fold
|
||||||
|
// Other left-clicks emit nodeClicked for selection
|
||||||
|
if (obj == m_sci->viewport() && !m_editState.active
|
||||||
|
&& event->type() == QEvent::MouseButtonPress) {
|
||||||
|
auto* me = static_cast<QMouseEvent*>(event);
|
||||||
|
if (me->button() == Qt::LeftButton) {
|
||||||
|
long pos = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMPOINTCLOSE,
|
||||||
|
(unsigned long)me->pos().x(), (long)me->pos().y());
|
||||||
|
if (pos >= 0) {
|
||||||
|
int line = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINEFROMPOSITION, (unsigned long)pos);
|
||||||
|
int col = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_GETCOLUMN, (unsigned long)pos);
|
||||||
|
if (col < kFoldCol && line >= 0 && line < m_meta.size()
|
||||||
|
&& m_meta[line].foldHead) {
|
||||||
|
emit marginClicked(0, line, me->modifiers());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Selection click — emit for controller to manage
|
||||||
|
if (line >= 0 && line < m_meta.size()) {
|
||||||
|
uint64_t nid = m_meta[line].nodeId;
|
||||||
|
if (nid != 0)
|
||||||
|
emit nodeClicked(line, nid, me->modifiers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj == m_sci->viewport() && !m_editState.active
|
||||||
|
&& event->type() == QEvent::MouseButtonDblClick) {
|
||||||
|
auto* me = static_cast<QMouseEvent*>(event);
|
||||||
|
int line; EditTarget t;
|
||||||
|
if (hitTestTarget(m_sci, m_meta, me->pos(), line, t))
|
||||||
|
return beginInlineEdit(t, line);
|
||||||
|
}
|
||||||
|
if (obj == m_sci && event->type() == QEvent::FocusOut) {
|
||||||
|
auto* fe = static_cast<QFocusEvent*>(event);
|
||||||
|
// Commit active edit on focus loss (click-away = save)
|
||||||
|
// Deferred so autocomplete popup has time to register as active
|
||||||
|
if (m_editState.active && fe->reason() != Qt::PopupFocusReason) {
|
||||||
|
QTimer::singleShot(0, this, [this]() {
|
||||||
|
if (m_editState.active && !m_sci->hasFocus()
|
||||||
|
&& !m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCACTIVE))
|
||||||
|
commitInlineEdit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Clear underlines when editor loses focus
|
||||||
|
if (m_hintLine >= 0) {
|
||||||
|
long start = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)m_hintLine);
|
||||||
|
long len = m_sci->SendScintilla(QsciScintillaBase::SCI_LINELENGTH, (unsigned long)m_hintLine);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_EDITABLE);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE, start, len);
|
||||||
|
m_hintLine = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj == m_sci && event->type() == QEvent::FocusIn) {
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
updateEditableUnderline(line);
|
||||||
|
}
|
||||||
|
if (obj == m_sci->viewport() && !m_editState.active) {
|
||||||
|
if (event->type() == QEvent::MouseMove) {
|
||||||
|
m_lastHoverPos = static_cast<QMouseEvent*>(event)->pos();
|
||||||
|
m_hoverInside = true;
|
||||||
|
} else if (event->type() == QEvent::Leave) {
|
||||||
|
m_hoverInside = false;
|
||||||
|
m_hoveredNodeId = 0;
|
||||||
|
applyHoverHighlight();
|
||||||
|
} else if (event->type() == QEvent::Wheel) {
|
||||||
|
m_lastHoverPos = m_sci->viewport()->mapFromGlobal(QCursor::pos());
|
||||||
|
m_hoverInside = m_sci->viewport()->rect().contains(m_lastHoverPos);
|
||||||
|
}
|
||||||
|
// Resolve hovered nodeId on move/wheel
|
||||||
|
if (event->type() == QEvent::MouseMove
|
||||||
|
|| event->type() == QEvent::Wheel) {
|
||||||
|
long pos = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMPOINTCLOSE,
|
||||||
|
(unsigned long)m_lastHoverPos.x(),
|
||||||
|
(long)m_lastHoverPos.y());
|
||||||
|
uint64_t newHoverId = 0;
|
||||||
|
if (pos >= 0 && m_hoverInside) {
|
||||||
|
int hLine = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINEFROMPOSITION, (unsigned long)pos);
|
||||||
|
if (hLine >= 0 && hLine < m_meta.size())
|
||||||
|
newHoverId = m_meta[hLine].nodeId;
|
||||||
|
}
|
||||||
|
if (newHoverId != m_hoveredNodeId) {
|
||||||
|
m_hoveredNodeId = newHoverId;
|
||||||
|
applyHoverHighlight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event->type() == QEvent::MouseMove
|
||||||
|
|| event->type() == QEvent::Leave
|
||||||
|
|| event->type() == QEvent::Wheel)
|
||||||
|
applyHoverCursor();
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Normal mode key handling ──
|
||||||
|
|
||||||
|
bool RcxEditor::handleNormalKey(QKeyEvent* ke) {
|
||||||
|
switch (ke->key()) {
|
||||||
|
case Qt::Key_F2:
|
||||||
|
return beginInlineEdit(EditTarget::Name);
|
||||||
|
case Qt::Key_T:
|
||||||
|
if (ke->modifiers() == Qt::NoModifier)
|
||||||
|
return beginInlineEdit(EditTarget::Type);
|
||||||
|
return false;
|
||||||
|
case Qt::Key_Return:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
return beginInlineEdit(EditTarget::Value);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Edit mode key handling ──
|
||||||
|
|
||||||
|
bool RcxEditor::handleEditKey(QKeyEvent* ke) {
|
||||||
|
bool autocActive = m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCACTIVE);
|
||||||
|
|
||||||
|
switch (ke->key()) {
|
||||||
|
case Qt::Key_Return:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
case Qt::Key_Tab:
|
||||||
|
if (autocActive) {
|
||||||
|
if (m_editState.target == EditTarget::Type) {
|
||||||
|
// Extract selected typeName directly from autocomplete
|
||||||
|
QByteArray buf(256, '\0');
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCGETCURRENTTEXT,
|
||||||
|
(unsigned long)256, (void*)buf.data());
|
||||||
|
QString selectedType = QString::fromUtf8(buf.constData());
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCCANCEL);
|
||||||
|
|
||||||
|
auto info = endInlineEdit();
|
||||||
|
emit inlineEditCommitted(info.nodeIdx, info.subLine, EditTarget::Type, selectedType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Other targets: let Scintilla complete, then auto-commit
|
||||||
|
QTimer::singleShot(0, this, &RcxEditor::commitInlineEdit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
commitInlineEdit();
|
||||||
|
return true;
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
if (autocActive) {
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCCANCEL);
|
||||||
|
return true; // close popup, stay in edit mode
|
||||||
|
}
|
||||||
|
cancelInlineEdit();
|
||||||
|
return true;
|
||||||
|
case Qt::Key_Up:
|
||||||
|
case Qt::Key_Down:
|
||||||
|
case Qt::Key_PageUp:
|
||||||
|
case Qt::Key_PageDown:
|
||||||
|
if (autocActive) return false; // let Scintilla navigate list
|
||||||
|
return true; // block line navigation
|
||||||
|
case Qt::Key_Delete:
|
||||||
|
return true; // block to prevent eating trailing content
|
||||||
|
case Qt::Key_Left:
|
||||||
|
case Qt::Key_Backspace: {
|
||||||
|
int line, col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
if (col <= m_editState.spanStart) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case Qt::Key_Home:
|
||||||
|
m_sci->setCursorPosition(m_editState.line, m_editState.spanStart);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Begin inline edit ──
|
||||||
|
|
||||||
|
bool RcxEditor::beginInlineEdit(EditTarget target, int line) {
|
||||||
|
if (m_editState.active) return false;
|
||||||
|
if (m_cursorOverridden) {
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_cursorOverridden = false;
|
||||||
|
}
|
||||||
|
m_hoveredNodeId = 0;
|
||||||
|
applyHoverHighlight();
|
||||||
|
|
||||||
|
if (line >= 0) {
|
||||||
|
m_sci->setCursorPosition(line, 0);
|
||||||
|
}
|
||||||
|
int col;
|
||||||
|
m_sci->getCursorPosition(&line, &col);
|
||||||
|
auto* lm = metaForLine(line);
|
||||||
|
if (!lm || lm->nodeIdx < 0) return false;
|
||||||
|
|
||||||
|
QString lineText = getLineText(m_sci, line);
|
||||||
|
int textLen = lineText.size();
|
||||||
|
|
||||||
|
ColumnSpan span;
|
||||||
|
switch (target) {
|
||||||
|
case EditTarget::Type: span = typeSpan(*lm); break;
|
||||||
|
case EditTarget::Name: span = nameSpan(*lm); break;
|
||||||
|
case EditTarget::Value: span = valueSpan(*lm, textLen); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!span.valid && target == EditTarget::Name)
|
||||||
|
span = headerNameSpan(*lm, lineText);
|
||||||
|
|
||||||
|
auto norm = normalizeSpan(span, lineText, target, /*skipPrefixes=*/true);
|
||||||
|
if (!norm.valid) return false;
|
||||||
|
|
||||||
|
QString trimmed = lineText.mid(norm.start, norm.end - norm.start);
|
||||||
|
|
||||||
|
m_editState.active = true;
|
||||||
|
m_editState.line = line;
|
||||||
|
m_editState.nodeIdx = lm->nodeIdx;
|
||||||
|
m_editState.subLine = lm->subLine;
|
||||||
|
m_editState.target = target;
|
||||||
|
m_editState.spanStart = norm.start;
|
||||||
|
m_editState.original = trimmed;
|
||||||
|
m_editState.linelenAfterReplace = textLen;
|
||||||
|
|
||||||
|
// Disable Scintilla undo during inline edit
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETUNDOCOLLECTION, (long)0);
|
||||||
|
m_sci->setReadOnly(false);
|
||||||
|
|
||||||
|
// Select just the trimmed text (keeps columns aligned)
|
||||||
|
long lineStart = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,
|
||||||
|
(unsigned long)line);
|
||||||
|
long posSelStart = lineStart + m_editState.spanStart;
|
||||||
|
long posSelEnd = posSelStart + trimmed.toUtf8().size();
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETSEL, posSelStart, posSelEnd);
|
||||||
|
|
||||||
|
if (target == EditTarget::Type)
|
||||||
|
QTimer::singleShot(0, this, &RcxEditor::showTypeAutocomplete);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Commit inline edit ──
|
||||||
|
|
||||||
|
void RcxEditor::commitInlineEdit() {
|
||||||
|
if (!m_editState.active) return;
|
||||||
|
|
||||||
|
QString lineText = getLineText(m_sci, m_editState.line);
|
||||||
|
int currentLen = lineText.size();
|
||||||
|
int delta = currentLen - m_editState.linelenAfterReplace;
|
||||||
|
int editedLen = m_editState.original.size() + delta;
|
||||||
|
|
||||||
|
QString editedText;
|
||||||
|
if (editedLen > 0)
|
||||||
|
editedText = lineText.mid(m_editState.spanStart, editedLen).trimmed();
|
||||||
|
|
||||||
|
auto info = endInlineEdit();
|
||||||
|
emit inlineEditCommitted(info.nodeIdx, info.subLine, info.target, editedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Cancel inline edit ──
|
||||||
|
|
||||||
|
void RcxEditor::cancelInlineEdit() {
|
||||||
|
if (!m_editState.active) return;
|
||||||
|
|
||||||
|
endInlineEdit();
|
||||||
|
emit inlineEditCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Type autocomplete ──
|
||||||
|
|
||||||
|
void RcxEditor::showTypeAutocomplete() {
|
||||||
|
if (!m_editState.active || m_editState.target != EditTarget::Type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Collapse selection to start — old type text stays visible
|
||||||
|
long lineStart = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,
|
||||||
|
(unsigned long)m_editState.line);
|
||||||
|
long posStart = lineStart + m_editState.spanStart;
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_GOTOPOS, posStart);
|
||||||
|
|
||||||
|
// Build list from typeName (matches what the editor displays)
|
||||||
|
QStringList types;
|
||||||
|
for (const auto& m : kKindMeta)
|
||||||
|
types << m.typeName;
|
||||||
|
types.sort(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
QByteArray list = types.join(QChar(' ')).toUtf8();
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSETSEPARATOR, (long)' ');
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSETIGNORECASE, (long)1);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSETDROPRESTOFWORD, (long)1);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSHOW,
|
||||||
|
(uintptr_t)0, list.constData());
|
||||||
|
|
||||||
|
// Highlight the current type in the list
|
||||||
|
QByteArray cur = m_editState.original.toUtf8();
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCSELECT,
|
||||||
|
(uintptr_t)0, cur.constData());
|
||||||
|
|
||||||
|
long pos = m_sci->SendScintilla(QsciScintillaBase::SCI_GETCURRENTPOS);
|
||||||
|
int x = (int)m_sci->SendScintilla(QsciScintillaBase::SCI_POINTXFROMPOSITION, 0, pos);
|
||||||
|
int y = (int)m_sci->SendScintilla(QsciScintillaBase::SCI_POINTYFROMPOSITION, 0, pos);
|
||||||
|
QToolTip::showText(
|
||||||
|
m_sci->viewport()->mapToGlobal(QPoint(x, y + 20)),
|
||||||
|
QStringLiteral("Type to filter \u2022 \u2191/\u2193 select \u2022 Enter apply \u2022 Esc cancel"),
|
||||||
|
m_sci);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Editable-field underline indicator ──
|
||||||
|
|
||||||
|
void RcxEditor::updateEditableUnderline(int line) {
|
||||||
|
if (m_editState.active) return;
|
||||||
|
if (line == m_hintLine) return;
|
||||||
|
|
||||||
|
auto clearLine = [&](int l) {
|
||||||
|
if (l < 0) return;
|
||||||
|
long start = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)l);
|
||||||
|
long len = m_sci->SendScintilla(QsciScintillaBase::SCI_LINELENGTH, (unsigned long)l);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_EDITABLE);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE, start, len);
|
||||||
|
};
|
||||||
|
|
||||||
|
clearLine(m_hintLine);
|
||||||
|
m_hintLine = line;
|
||||||
|
|
||||||
|
const LineMeta* lm = metaForLine(line);
|
||||||
|
if (!lm || lm->nodeIdx < 0) return;
|
||||||
|
|
||||||
|
QString lineText = getLineText(m_sci, line);
|
||||||
|
int textLen = lineText.size();
|
||||||
|
|
||||||
|
ColumnSpan ts = typeSpan(*lm);
|
||||||
|
ColumnSpan ns = nameSpan(*lm);
|
||||||
|
ColumnSpan vs = valueSpan(*lm, textLen);
|
||||||
|
|
||||||
|
if (!ns.valid)
|
||||||
|
ns = headerNameSpan(*lm, lineText);
|
||||||
|
|
||||||
|
auto underlineSpan = [&](ColumnSpan s, EditTarget tgt) {
|
||||||
|
auto norm = normalizeSpan(s, lineText, tgt, /*skipPrefixes=*/true);
|
||||||
|
if (!norm.valid) return;
|
||||||
|
|
||||||
|
long lineStart = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE, (unsigned long)line);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_EDITABLE);
|
||||||
|
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE,
|
||||||
|
lineStart + norm.start, norm.end - norm.start);
|
||||||
|
};
|
||||||
|
|
||||||
|
underlineSpan(ts, EditTarget::Type);
|
||||||
|
underlineSpan(ns, EditTarget::Name);
|
||||||
|
underlineSpan(vs, EditTarget::Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Hover cursor (coalesced) ──
|
||||||
|
|
||||||
|
void RcxEditor::applyHoverCursor() {
|
||||||
|
if (m_editState.active || !m_hoverInside
|
||||||
|
|| !m_sci->viewport()->underMouse()) {
|
||||||
|
if (m_cursorOverridden) {
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_cursorOverridden = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int line; EditTarget t;
|
||||||
|
bool interactive = hitTestTarget(m_sci, m_meta, m_lastHoverPos, line, t);
|
||||||
|
|
||||||
|
// Also show pointer cursor for fold column on fold-head lines
|
||||||
|
if (!interactive) {
|
||||||
|
long pos = m_sci->SendScintilla(QsciScintillaBase::SCI_POSITIONFROMPOINTCLOSE,
|
||||||
|
(unsigned long)m_lastHoverPos.x(),
|
||||||
|
(long)m_lastHoverPos.y());
|
||||||
|
if (pos >= 0) {
|
||||||
|
int hLine = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINEFROMPOSITION, (unsigned long)pos);
|
||||||
|
int hCol = (int)m_sci->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_GETCOLUMN, (unsigned long)pos);
|
||||||
|
if (hCol < kFoldCol && hLine >= 0 && hLine < m_meta.size()
|
||||||
|
&& m_meta[hLine].foldHead)
|
||||||
|
interactive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interactive && !m_cursorOverridden) {
|
||||||
|
QApplication::setOverrideCursor(Qt::PointingHandCursor);
|
||||||
|
m_cursorOverridden = true;
|
||||||
|
} else if (!interactive && m_cursorOverridden) {
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
m_cursorOverridden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
109
src/editor.h
Normal file
109
src/editor.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core.h"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
class QsciScintilla;
|
||||||
|
class QsciLexerCPP;
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
class RcxEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RcxEditor(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void applyDocument(const ComposeResult& result);
|
||||||
|
|
||||||
|
ViewState saveViewState() const;
|
||||||
|
void restoreViewState(const ViewState& vs);
|
||||||
|
|
||||||
|
QsciScintilla* scintilla() const { return m_sci; }
|
||||||
|
const LineMeta* metaForLine(int line) const;
|
||||||
|
int currentNodeIndex() const;
|
||||||
|
|
||||||
|
// ── Column span computation ──
|
||||||
|
static ColumnSpan typeSpan(const LineMeta& lm);
|
||||||
|
static ColumnSpan nameSpan(const LineMeta& lm);
|
||||||
|
static ColumnSpan valueSpan(const LineMeta& lm, int lineLength);
|
||||||
|
|
||||||
|
// ── Multi-selection ──
|
||||||
|
QSet<int> selectedNodeIndices() const;
|
||||||
|
|
||||||
|
// ── Inline editing ──
|
||||||
|
bool isEditing() const { return m_editState.active; }
|
||||||
|
bool beginInlineEdit(EditTarget target, int line = -1);
|
||||||
|
void cancelInlineEdit();
|
||||||
|
|
||||||
|
void applySelectionOverlay(const QSet<uint64_t>& selIds);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void marginClicked(int margin, int line, Qt::KeyboardModifiers mods);
|
||||||
|
void contextMenuRequested(int line, int nodeIdx, int subLine, QPoint globalPos);
|
||||||
|
void nodeClicked(int line, uint64_t nodeId, Qt::KeyboardModifiers mods);
|
||||||
|
void inlineEditCommitted(int nodeIdx, int subLine,
|
||||||
|
EditTarget target, const QString& text);
|
||||||
|
void inlineEditCancelled();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciScintilla* m_sci = nullptr;
|
||||||
|
QsciLexerCPP* m_lexer = nullptr;
|
||||||
|
QVector<LineMeta> m_meta;
|
||||||
|
|
||||||
|
int m_marginStyleBase = -1;
|
||||||
|
int m_hintLine = -1;
|
||||||
|
|
||||||
|
// ── Hover cursor + highlight ──
|
||||||
|
QPoint m_lastHoverPos;
|
||||||
|
bool m_hoverInside = false;
|
||||||
|
bool m_cursorOverridden = false;
|
||||||
|
uint64_t m_hoveredNodeId = 0;
|
||||||
|
QSet<uint64_t> m_currentSelIds;
|
||||||
|
|
||||||
|
// ── Inline edit state ──
|
||||||
|
struct InlineEditState {
|
||||||
|
bool active = false;
|
||||||
|
int line = -1;
|
||||||
|
int nodeIdx = -1;
|
||||||
|
int subLine = 0;
|
||||||
|
EditTarget target = EditTarget::Name;
|
||||||
|
int spanStart = 0;
|
||||||
|
int linelenAfterReplace = 0;
|
||||||
|
QString original;
|
||||||
|
};
|
||||||
|
InlineEditState m_editState;
|
||||||
|
|
||||||
|
void setupScintilla();
|
||||||
|
void setupLexer();
|
||||||
|
void setupMargins();
|
||||||
|
void setupFolding();
|
||||||
|
void setupMarkers();
|
||||||
|
void allocateMarginStyles();
|
||||||
|
|
||||||
|
void applyMarginText(const QVector<LineMeta>& meta);
|
||||||
|
void applyMarkers(const QVector<LineMeta>& meta);
|
||||||
|
void applyFoldLevels(const QVector<LineMeta>& meta);
|
||||||
|
void applyHexDimming(const QVector<LineMeta>& meta);
|
||||||
|
|
||||||
|
void commitInlineEdit();
|
||||||
|
bool handleNormalKey(QKeyEvent* ke);
|
||||||
|
bool handleEditKey(QKeyEvent* ke);
|
||||||
|
void showTypeAutocomplete();
|
||||||
|
void updateEditableUnderline(int line);
|
||||||
|
void applyHoverCursor();
|
||||||
|
void applyHoverHighlight();
|
||||||
|
|
||||||
|
// ── Refactored helpers ──
|
||||||
|
struct EndEditInfo { int nodeIdx; int subLine; EditTarget target; };
|
||||||
|
EndEditInfo endInlineEdit();
|
||||||
|
|
||||||
|
struct NormalizedSpan { int start = 0; int end = 0; bool valid = false; };
|
||||||
|
NormalizedSpan normalizeSpan(const ColumnSpan& raw, const QString& lineText,
|
||||||
|
EditTarget target, bool skipPrefixes) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
364
src/format.cpp
Normal file
364
src/format.cpp
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
#include "core.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace rcx::fmt {
|
||||||
|
|
||||||
|
// ── Column layout ──
|
||||||
|
// COL_TYPE and COL_NAME use shared constants from core.h (kColType, kColName)
|
||||||
|
static constexpr int COL_TYPE = kColType;
|
||||||
|
static constexpr int COL_NAME = kColName;
|
||||||
|
static constexpr int COL_VALUE = 22;
|
||||||
|
static const QString SEP = QStringLiteral(" ");
|
||||||
|
|
||||||
|
static QString fit(QString s, int w) {
|
||||||
|
if (w <= 0) return {};
|
||||||
|
if (s.size() > w) {
|
||||||
|
if (w >= 2) s = s.left(w - 1) + QChar(0x2026); // ellipsis
|
||||||
|
else s = s.left(w);
|
||||||
|
}
|
||||||
|
return s.leftJustified(w, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Type name ──
|
||||||
|
|
||||||
|
// Override seam: injectable type-name provider
|
||||||
|
static TypeNameFn g_typeNameFn = nullptr;
|
||||||
|
|
||||||
|
void setTypeNameProvider(TypeNameFn fn) { g_typeNameFn = fn; }
|
||||||
|
|
||||||
|
QString typeName(NodeKind kind) {
|
||||||
|
if (g_typeNameFn) return fit(g_typeNameFn(kind), COL_TYPE);
|
||||||
|
auto* m = kindMeta(kind);
|
||||||
|
return fit(m ? QString::fromLatin1(m->typeName) : QStringLiteral("???"), COL_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Value formatting ──
|
||||||
|
|
||||||
|
static QString hexStr(uint64_t v, int digits) {
|
||||||
|
return QStringLiteral("0x") + QString::number(v, 16).toUpper().rightJustified(digits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString rawHex(uint64_t v, int digits) {
|
||||||
|
return QString::number(v, 16).toUpper().rightJustified(digits, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fmtInt8(int8_t v) { return QString::number(v); }
|
||||||
|
QString fmtInt16(int16_t v) { return QString::number(v); }
|
||||||
|
QString fmtInt32(int32_t v) { return QString::number(v); }
|
||||||
|
QString fmtInt64(int64_t v) { return QString::number(v); }
|
||||||
|
QString fmtUInt8(uint8_t v) { return QString::number(v); }
|
||||||
|
QString fmtUInt16(uint16_t v) { return QString::number(v); }
|
||||||
|
QString fmtUInt32(uint32_t v) { return QString::number(v); }
|
||||||
|
QString fmtUInt64(uint64_t v) { return QString::number(v); }
|
||||||
|
|
||||||
|
QString fmtFloat(float v) { return QString::number(v, 'f', 3); }
|
||||||
|
QString fmtDouble(double v) { return QString::number(v, 'f', 6); }
|
||||||
|
QString fmtBool(uint8_t v) { return v ? QStringLiteral("true") : QStringLiteral("false"); }
|
||||||
|
|
||||||
|
QString fmtPointer32(uint32_t v) {
|
||||||
|
if (v == 0) return QStringLiteral("-> NULL");
|
||||||
|
return QStringLiteral("-> ") + hexStr(v, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fmtPointer64(uint64_t v) {
|
||||||
|
if (v == 0) return QStringLiteral("-> NULL");
|
||||||
|
return QStringLiteral("-> ") + hexStr(v, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Indentation ──
|
||||||
|
|
||||||
|
QString indent(int depth) {
|
||||||
|
return QString(depth * 3, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Offset margin ──
|
||||||
|
|
||||||
|
QString fmtOffsetMargin(int64_t relativeOffset, bool isContinuation) {
|
||||||
|
if (isContinuation) return QStringLiteral(" \u00B7");
|
||||||
|
return QStringLiteral("+0x") + QString::number(relativeOffset, 16).toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Struct header / footer ──
|
||||||
|
|
||||||
|
QString fmtStructHeader(const Node& node, int depth) {
|
||||||
|
return indent(depth) + typeName(node.kind).trimmed() +
|
||||||
|
QStringLiteral(" ") + node.name + QStringLiteral(" {");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fmtStructFooter(const Node& node, int depth, int totalSize) {
|
||||||
|
QString s = indent(depth) + QStringLiteral("}; // ") + node.name;
|
||||||
|
if (totalSize > 0)
|
||||||
|
s += QStringLiteral(" sizeof=0x") + QString::number(totalSize, 16).toUpper();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Hex / ASCII preview ──
|
||||||
|
|
||||||
|
static inline bool isAsciiPrintable(uint8_t c) { return c >= 0x20 && c <= 0x7E; }
|
||||||
|
|
||||||
|
static QString bytesToAscii(const QByteArray& b, int slot) {
|
||||||
|
QString out;
|
||||||
|
out.reserve(slot);
|
||||||
|
for (int i = 0; i < slot; ++i) {
|
||||||
|
uint8_t c = (i < b.size()) ? (uint8_t)b[i] : 0;
|
||||||
|
out += isAsciiPrintable(c) ? QChar(c) : QChar('.');
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString bytesToHex(const QByteArray& b, int slot) {
|
||||||
|
QString out;
|
||||||
|
out.reserve(slot * 3);
|
||||||
|
for (int i = 0; i < slot; ++i) {
|
||||||
|
uint8_t c = (i < b.size()) ? (uint8_t)b[i] : 0;
|
||||||
|
out += QString::asprintf("%02X", (unsigned)c);
|
||||||
|
if (i + 1 < slot) out += ' ';
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString fmtAsciiAndBytes(const Provider& prov, uint64_t addr,
|
||||||
|
int sizeBytes, int slotBytes = 8) {
|
||||||
|
const int slot = qMax(slotBytes, sizeBytes);
|
||||||
|
QByteArray b = prov.isReadable(addr, slot)
|
||||||
|
? prov.readBytes(addr, slot)
|
||||||
|
: QByteArray(slot, '\0');
|
||||||
|
return bytesToAscii(b, slot) + QStringLiteral(" ") + bytesToHex(b, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Single value from provider (unified) ──
|
||||||
|
|
||||||
|
enum class ValueMode { Display, Editable };
|
||||||
|
|
||||||
|
static QString readValueImpl(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int subLine, ValueMode mode) {
|
||||||
|
const bool display = (mode == ValueMode::Display);
|
||||||
|
switch (node.kind) {
|
||||||
|
case NodeKind::Hex8: return display ? hexStr(prov.readU8(addr), 2) : rawHex(prov.readU8(addr), 2);
|
||||||
|
case NodeKind::Hex16: return display ? hexStr(prov.readU16(addr), 4) : rawHex(prov.readU16(addr), 4);
|
||||||
|
case NodeKind::Hex32: return display ? hexStr(prov.readU32(addr), 8) : rawHex(prov.readU32(addr), 8);
|
||||||
|
case NodeKind::Hex64: return display ? hexStr(prov.readU64(addr), 16): rawHex(prov.readU64(addr), 16);
|
||||||
|
case NodeKind::Int8: return fmtInt8((int8_t)prov.readU8(addr));
|
||||||
|
case NodeKind::Int16: return fmtInt16((int16_t)prov.readU16(addr));
|
||||||
|
case NodeKind::Int32: return fmtInt32((int32_t)prov.readU32(addr));
|
||||||
|
case NodeKind::Int64: return fmtInt64((int64_t)prov.readU64(addr));
|
||||||
|
case NodeKind::UInt8: return fmtUInt8(prov.readU8(addr));
|
||||||
|
case NodeKind::UInt16: return fmtUInt16(prov.readU16(addr));
|
||||||
|
case NodeKind::UInt32: return fmtUInt32(prov.readU32(addr));
|
||||||
|
case NodeKind::UInt64: return fmtUInt64(prov.readU64(addr));
|
||||||
|
case NodeKind::Float: { auto s = fmtFloat(prov.readF32(addr)); return display ? s : s.trimmed(); }
|
||||||
|
case NodeKind::Double: { auto s = fmtDouble(prov.readF64(addr)); return display ? s : s.trimmed(); }
|
||||||
|
case NodeKind::Bool: return fmtBool(prov.readU8(addr));
|
||||||
|
case NodeKind::Pointer32: return display ? fmtPointer32(prov.readU32(addr)) : rawHex(prov.readU32(addr), 8);
|
||||||
|
case NodeKind::Pointer64: return display ? fmtPointer64(prov.readU64(addr)) : rawHex(prov.readU64(addr), 16);
|
||||||
|
case NodeKind::Vec2:
|
||||||
|
case NodeKind::Vec3:
|
||||||
|
case NodeKind::Vec4: {
|
||||||
|
int maxSub = linesForKind(node.kind);
|
||||||
|
if (subLine < 0 || subLine >= maxSub) return QStringLiteral("?");
|
||||||
|
float component = prov.readF32(addr + subLine * 4);
|
||||||
|
if (!display) return fmtFloat(component).trimmed();
|
||||||
|
static const char* labels[] = {"x", "y", "z", "w"};
|
||||||
|
return QString(labels[subLine]) + QStringLiteral(" = ") + fmtFloat(component);
|
||||||
|
}
|
||||||
|
case NodeKind::Mat4x4: {
|
||||||
|
if (!display) return {}; // not editable as single value
|
||||||
|
if (subLine < 0 || subLine >= 4) return QStringLiteral("?");
|
||||||
|
QString line = QStringLiteral("[");
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
if (c > 0) line += QStringLiteral(", ");
|
||||||
|
line += fmtFloat(prov.readF32(addr + (subLine * 4 + c) * 4)).trimmed();
|
||||||
|
}
|
||||||
|
line += QStringLiteral("]");
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
case NodeKind::Padding: return display ? hexStr(prov.readU8(addr), 2) : rawHex(prov.readU8(addr), 2);
|
||||||
|
case NodeKind::UTF8: {
|
||||||
|
QByteArray bytes = prov.readBytes(addr, node.strLen);
|
||||||
|
int end = bytes.indexOf('\0');
|
||||||
|
if (end >= 0) bytes.truncate(end);
|
||||||
|
QString s = QString::fromUtf8(bytes);
|
||||||
|
return display ? (QStringLiteral("\"") + s + QStringLiteral("\"")) : s;
|
||||||
|
}
|
||||||
|
case NodeKind::UTF16: {
|
||||||
|
QByteArray bytes = prov.readBytes(addr, node.strLen * 2);
|
||||||
|
QString s = QString::fromUtf16(reinterpret_cast<const char16_t*>(bytes.data()),
|
||||||
|
bytes.size() / 2);
|
||||||
|
int end = s.indexOf(QChar(0));
|
||||||
|
if (end >= 0) s.truncate(end);
|
||||||
|
return display ? (QStringLiteral("L\"") + s + QStringLiteral("\"")) : s;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString readValue(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int subLine) {
|
||||||
|
return readValueImpl(node, prov, addr, subLine, ValueMode::Display);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Full node line ──
|
||||||
|
|
||||||
|
QString fmtNodeLine(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int depth, int subLine) {
|
||||||
|
QString ind = indent(depth);
|
||||||
|
QString type = typeName(node.kind);
|
||||||
|
QString name = fit(node.name, COL_NAME);
|
||||||
|
// Blank prefix for continuation lines (same width as type+sep+name+sep)
|
||||||
|
const int prefixW = COL_TYPE + COL_NAME + 4; // 2 seps × 2 chars
|
||||||
|
|
||||||
|
// Mat4x4: subLine 0..3 = rows
|
||||||
|
if (node.kind == NodeKind::Mat4x4) {
|
||||||
|
QString val = readValue(node, prov, addr, subLine);
|
||||||
|
if (subLine == 0) return ind + type + SEP + name + SEP + val;
|
||||||
|
return ind + QString(prefixW, ' ') + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For vector types, subLine selects component
|
||||||
|
if (subLine > 0 && (node.kind == NodeKind::Vec2 ||
|
||||||
|
node.kind == NodeKind::Vec3 ||
|
||||||
|
node.kind == NodeKind::Vec4)) {
|
||||||
|
QString val = readValue(node, prov, addr, subLine);
|
||||||
|
return ind + QString(prefixW, ' ') + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex nodes and Padding: ASCII preview + hex bytes (compact)
|
||||||
|
if (node.kind == NodeKind::Hex8 || node.kind == NodeKind::Hex16 ||
|
||||||
|
node.kind == NodeKind::Hex32 || node.kind == NodeKind::Hex64 ||
|
||||||
|
node.kind == NodeKind::Padding)
|
||||||
|
{
|
||||||
|
if (node.kind == NodeKind::Padding) {
|
||||||
|
const int totalSz = qMax(1, node.arrayLen);
|
||||||
|
const int lineOff = subLine * 8;
|
||||||
|
const int lineBytes = qMin(8, totalSz - lineOff);
|
||||||
|
QByteArray b = prov.isReadable(addr + lineOff, lineBytes)
|
||||||
|
? prov.readBytes(addr + lineOff, lineBytes) : QByteArray(lineBytes, '\0');
|
||||||
|
QString ascii = bytesToAscii(b, lineBytes);
|
||||||
|
QString hex = bytesToHex(b, lineBytes);
|
||||||
|
if (subLine == 0)
|
||||||
|
return ind + type + SEP + ascii + SEP + hex;
|
||||||
|
return ind + QString(COL_TYPE + (int)SEP.size(), ' ') + ascii + SEP + hex;
|
||||||
|
}
|
||||||
|
// Hex8..Hex64: single line, ASCII padded to 8 chars so hex column aligns
|
||||||
|
const int sz = sizeForKind(node.kind);
|
||||||
|
QByteArray b = prov.isReadable(addr, sz)
|
||||||
|
? prov.readBytes(addr, sz) : QByteArray(sz, '\0');
|
||||||
|
QString ascii = bytesToAscii(b, sz).leftJustified(8, ' ');
|
||||||
|
QString hex = bytesToHex(b, sz);
|
||||||
|
return ind + type + SEP + ascii + SEP + hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString val = readValue(node, prov, addr, subLine);
|
||||||
|
return ind + type + SEP + name + SEP + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Editable value (parse-friendly form for edit dialog) ──
|
||||||
|
|
||||||
|
QString editableValue(const Node& node, const Provider& prov,
|
||||||
|
uint64_t addr, int subLine) {
|
||||||
|
return readValueImpl(node, prov, addr, subLine, ValueMode::Editable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Value parsing (text → bytes) ──
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static QByteArray toBytes(T v) {
|
||||||
|
QByteArray b(sizeof(T), Qt::Uninitialized);
|
||||||
|
memcpy(b.data(), &v, sizeof(T));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString stripHex(const QString& s) {
|
||||||
|
if (s.startsWith(QStringLiteral("0x"), Qt::CaseInsensitive))
|
||||||
|
return s.mid(2);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range-checked narrowing: sets *ok = false if parsed value doesn't fit in T
|
||||||
|
template<class T, class ParseT>
|
||||||
|
static QByteArray parseIntChecked(ParseT val, bool* ok) {
|
||||||
|
if (*ok) {
|
||||||
|
using L = std::numeric_limits<T>;
|
||||||
|
if constexpr (std::is_signed_v<T>) {
|
||||||
|
if (val < (ParseT)L::min() || val > (ParseT)L::max()) *ok = false;
|
||||||
|
} else {
|
||||||
|
if (val > (ParseT)L::max()) *ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *ok ? toBytes<T>(static_cast<T>(val)) : QByteArray{};
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray parseValue(NodeKind kind, const QString& text, bool* ok) {
|
||||||
|
*ok = false;
|
||||||
|
QString s = text.trimmed();
|
||||||
|
|
||||||
|
// Allow empty for string types (will produce zero-length content, caller pads)
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
if (kind == NodeKind::UTF8 || kind == NodeKind::UTF16) {
|
||||||
|
*ok = true;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case NodeKind::Hex8: { uint val = stripHex(s).remove(' ').toUInt(ok, 16); return parseIntChecked<uint8_t>(val, ok); }
|
||||||
|
case NodeKind::Hex16: { uint val = stripHex(s).remove(' ').toUInt(ok, 16); return parseIntChecked<uint16_t>(val, ok); }
|
||||||
|
case NodeKind::Hex32: { uint val = stripHex(s).remove(' ').toUInt(ok, 16); return *ok ? toBytes<uint32_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::Hex64: { qulonglong val = stripHex(s).remove(' ').toULongLong(ok, 16); return *ok ? toBytes<uint64_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::Int8: { int val = s.toInt(ok); return parseIntChecked<int8_t>(val, ok); }
|
||||||
|
case NodeKind::Int16: { int val = s.toInt(ok); return parseIntChecked<int16_t>(val, ok); }
|
||||||
|
case NodeKind::Int32: { int val = s.toInt(ok); return *ok ? toBytes<int32_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::Int64: { qlonglong val = s.toLongLong(ok); return *ok ? toBytes<int64_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::UInt8: { uint val = s.toUInt(ok); return parseIntChecked<uint8_t>(val, ok); }
|
||||||
|
case NodeKind::UInt16: { uint val = s.toUInt(ok); return parseIntChecked<uint16_t>(val, ok); }
|
||||||
|
case NodeKind::UInt32: { uint val = s.toUInt(ok); return *ok ? toBytes<uint32_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::UInt64: { qulonglong val = s.toULongLong(ok); return *ok ? toBytes<uint64_t>(val) : QByteArray{}; }
|
||||||
|
case NodeKind::Float: {
|
||||||
|
float val = s.toFloat(ok);
|
||||||
|
return *ok ? toBytes<float>(val) : QByteArray{};
|
||||||
|
}
|
||||||
|
case NodeKind::Double: {
|
||||||
|
double val = s.toDouble(ok);
|
||||||
|
return *ok ? toBytes<double>(val) : QByteArray{};
|
||||||
|
}
|
||||||
|
case NodeKind::Bool: {
|
||||||
|
if (s == QStringLiteral("true") || s == QStringLiteral("1")) {
|
||||||
|
*ok = true; return toBytes<uint8_t>(1);
|
||||||
|
}
|
||||||
|
if (s == QStringLiteral("false") || s == QStringLiteral("0")) {
|
||||||
|
*ok = true; return toBytes<uint8_t>(0);
|
||||||
|
}
|
||||||
|
return {}; // unknown token → ok stays false
|
||||||
|
}
|
||||||
|
case NodeKind::Pointer32: {
|
||||||
|
uint val = stripHex(s).toUInt(ok, 16);
|
||||||
|
return *ok ? toBytes<uint32_t>(val) : QByteArray{};
|
||||||
|
}
|
||||||
|
case NodeKind::Pointer64: {
|
||||||
|
qulonglong val = stripHex(s).toULongLong(ok, 16);
|
||||||
|
return *ok ? toBytes<uint64_t>(val) : QByteArray{};
|
||||||
|
}
|
||||||
|
case NodeKind::UTF8: {
|
||||||
|
*ok = true;
|
||||||
|
if (s.startsWith('"') && s.endsWith('"'))
|
||||||
|
s = s.mid(1, s.size() - 2);
|
||||||
|
return s.toUtf8();
|
||||||
|
}
|
||||||
|
case NodeKind::UTF16: {
|
||||||
|
*ok = true;
|
||||||
|
if (s.startsWith(QStringLiteral("L\""))) s = s.mid(2);
|
||||||
|
else if (s.startsWith('"')) s = s.mid(1);
|
||||||
|
if (s.endsWith('"')) s.chop(1);
|
||||||
|
QByteArray b(s.size() * 2, Qt::Uninitialized);
|
||||||
|
memcpy(b.data(), s.utf16(), s.size() * 2);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rcx::fmt
|
||||||
6
src/icons.qrc
Normal file
6
src/icons.qrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/icons">
|
||||||
|
<file alias="chevron-right.png">icons/chevron-right.png</file>
|
||||||
|
<file alias="chevron-down.png">icons/chevron-down.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
BIN
src/icons/chevron-down.png
Normal file
BIN
src/icons/chevron-down.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 B |
BIN
src/icons/chevron-right.png
Normal file
BIN
src/icons/chevron-right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 174 B |
BIN
src/icons/close.png
Normal file
BIN
src/icons/close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 169 B |
636
src/main.cpp
Normal file
636
src/main.cpp
Normal file
@@ -0,0 +1,636 @@
|
|||||||
|
#include "controller.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QMdiArea>
|
||||||
|
#include <QMdiSubWindow>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QMetaObject>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <dbghelp.h>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
static LONG WINAPI crashHandler(EXCEPTION_POINTERS* ep) {
|
||||||
|
fprintf(stderr, "\n=== UNHANDLED EXCEPTION ===\n");
|
||||||
|
fprintf(stderr, "Code : 0x%08lX\n", ep->ExceptionRecord->ExceptionCode);
|
||||||
|
fprintf(stderr, "Addr : %p\n", ep->ExceptionRecord->ExceptionAddress);
|
||||||
|
|
||||||
|
HANDLE process = GetCurrentProcess();
|
||||||
|
HANDLE thread = GetCurrentThread();
|
||||||
|
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
|
||||||
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
|
||||||
|
CONTEXT* ctx = ep->ContextRecord;
|
||||||
|
STACKFRAME64 frame = {};
|
||||||
|
DWORD machineType;
|
||||||
|
#ifdef _M_X64
|
||||||
|
machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
frame.AddrPC.Offset = ctx->Rip;
|
||||||
|
frame.AddrFrame.Offset = ctx->Rbp;
|
||||||
|
frame.AddrStack.Offset = ctx->Rsp;
|
||||||
|
#else
|
||||||
|
machineType = IMAGE_FILE_MACHINE_I386;
|
||||||
|
frame.AddrPC.Offset = ctx->Eip;
|
||||||
|
frame.AddrFrame.Offset = ctx->Ebp;
|
||||||
|
frame.AddrStack.Offset = ctx->Esp;
|
||||||
|
#endif
|
||||||
|
frame.AddrPC.Mode = AddrModeFlat;
|
||||||
|
frame.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
frame.AddrStack.Mode = AddrModeFlat;
|
||||||
|
|
||||||
|
fprintf(stderr, "\nStack trace:\n");
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
if (!StackWalk64(machineType, process, thread, &frame, ctx,
|
||||||
|
NULL, SymFunctionTableAccess64,
|
||||||
|
SymGetModuleBase64, NULL))
|
||||||
|
break;
|
||||||
|
if (frame.AddrPC.Offset == 0) break;
|
||||||
|
|
||||||
|
char buf[sizeof(SYMBOL_INFO) + 256];
|
||||||
|
SYMBOL_INFO* sym = reinterpret_cast<SYMBOL_INFO*>(buf);
|
||||||
|
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
sym->MaxNameLen = 255;
|
||||||
|
|
||||||
|
DWORD64 disp64 = 0;
|
||||||
|
DWORD disp32 = 0;
|
||||||
|
IMAGEHLP_LINE64 line = {};
|
||||||
|
line.SizeOfStruct = sizeof(line);
|
||||||
|
|
||||||
|
bool hasSym = SymFromAddr(process, frame.AddrPC.Offset, &disp64, sym);
|
||||||
|
bool hasLine = SymGetLineFromAddr64(process, frame.AddrPC.Offset,
|
||||||
|
&disp32, &line);
|
||||||
|
if (hasSym && hasLine) {
|
||||||
|
fprintf(stderr, " [%2d] %s+0x%llx (%s:%lu)\n",
|
||||||
|
i, sym->Name, (unsigned long long)disp64,
|
||||||
|
line.FileName, line.LineNumber);
|
||||||
|
} else if (hasSym) {
|
||||||
|
fprintf(stderr, " [%2d] %s+0x%llx\n",
|
||||||
|
i, sym->Name, (unsigned long long)disp64);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " [%2d] 0x%llx\n",
|
||||||
|
i, (unsigned long long)frame.AddrPC.Offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SymCleanup(process);
|
||||||
|
fprintf(stderr, "=== END CRASH ===\n");
|
||||||
|
fflush(stderr);
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace rcx {
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void newFile();
|
||||||
|
void openFile();
|
||||||
|
void saveFile();
|
||||||
|
void saveFileAs();
|
||||||
|
void loadBinary();
|
||||||
|
|
||||||
|
void addNode();
|
||||||
|
void removeNode();
|
||||||
|
void changeNodeType();
|
||||||
|
void renameNodeAction();
|
||||||
|
void splitView();
|
||||||
|
void unsplitView();
|
||||||
|
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
void about();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMdiArea* m_mdiArea;
|
||||||
|
QLabel* m_statusLabel;
|
||||||
|
|
||||||
|
struct TabState {
|
||||||
|
RcxDocument* doc;
|
||||||
|
RcxController* ctrl;
|
||||||
|
QSplitter* splitter;
|
||||||
|
};
|
||||||
|
QMap<QMdiSubWindow*, TabState> m_tabs;
|
||||||
|
|
||||||
|
void createMenus();
|
||||||
|
void createStatusBar();
|
||||||
|
|
||||||
|
RcxController* activeController() const;
|
||||||
|
TabState* activeTab();
|
||||||
|
QMdiSubWindow* createTab(RcxDocument* doc);
|
||||||
|
void updateWindowTitle();
|
||||||
|
};
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
|
||||||
|
setWindowTitle("ReclassX");
|
||||||
|
resize(1200, 800);
|
||||||
|
|
||||||
|
m_mdiArea = new QMdiArea(this);
|
||||||
|
m_mdiArea->setViewMode(QMdiArea::TabbedView);
|
||||||
|
m_mdiArea->setTabsClosable(true);
|
||||||
|
m_mdiArea->setTabsMovable(true);
|
||||||
|
setCentralWidget(m_mdiArea);
|
||||||
|
|
||||||
|
createMenus();
|
||||||
|
createStatusBar();
|
||||||
|
|
||||||
|
connect(m_mdiArea, &QMdiArea::subWindowActivated,
|
||||||
|
this, [this](QMdiSubWindow*) { updateWindowTitle(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createMenus() {
|
||||||
|
// File
|
||||||
|
auto* file = menuBar()->addMenu("&File");
|
||||||
|
file->addAction("&New", QKeySequence::New, this, &MainWindow::newFile);
|
||||||
|
file->addAction("&Open...", QKeySequence::Open, this, &MainWindow::openFile);
|
||||||
|
file->addSeparator();
|
||||||
|
file->addAction("&Save", QKeySequence::Save, this, &MainWindow::saveFile);
|
||||||
|
file->addAction("Save &As...", QKeySequence::SaveAs, this, &MainWindow::saveFileAs);
|
||||||
|
file->addSeparator();
|
||||||
|
file->addAction("Load &Binary...", this, &MainWindow::loadBinary);
|
||||||
|
file->addSeparator();
|
||||||
|
file->addAction("E&xit", QKeySequence::Quit, this, &QMainWindow::close);
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
auto* edit = menuBar()->addMenu("&Edit");
|
||||||
|
edit->addAction("&Undo", QKeySequence::Undo, this, &MainWindow::undo);
|
||||||
|
edit->addAction("&Redo", QKeySequence::Redo, this, &MainWindow::redo);
|
||||||
|
|
||||||
|
// View
|
||||||
|
auto* view = menuBar()->addMenu("&View");
|
||||||
|
view->addAction("Split &Horizontal", this, &MainWindow::splitView);
|
||||||
|
view->addAction("&Unsplit", this, &MainWindow::unsplitView);
|
||||||
|
|
||||||
|
// Node
|
||||||
|
auto* node = menuBar()->addMenu("&Node");
|
||||||
|
node->addAction("&Add Field", QKeySequence(Qt::Key_Insert), this, &MainWindow::addNode);
|
||||||
|
node->addAction("&Remove Field", QKeySequence::Delete, this, &MainWindow::removeNode);
|
||||||
|
auto* actType = node->addAction("Change &Type", this, &MainWindow::changeNodeType);
|
||||||
|
actType->setText("Change &Type\tT");
|
||||||
|
auto* actName = node->addAction("Re&name", this, &MainWindow::renameNodeAction);
|
||||||
|
actName->setText("Re&name\tF2");
|
||||||
|
|
||||||
|
// Help
|
||||||
|
auto* help = menuBar()->addMenu("&Help");
|
||||||
|
help->addAction("&About ReclassX", this, &MainWindow::about);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createStatusBar() {
|
||||||
|
m_statusLabel = new QLabel("Ready");
|
||||||
|
statusBar()->addWidget(m_statusLabel, 1);
|
||||||
|
statusBar()->setStyleSheet("QStatusBar { background: #252526; color: #858585; }");
|
||||||
|
}
|
||||||
|
|
||||||
|
QMdiSubWindow* MainWindow::createTab(RcxDocument* doc) {
|
||||||
|
auto* splitter = new QSplitter(Qt::Horizontal);
|
||||||
|
auto* ctrl = new RcxController(doc, splitter);
|
||||||
|
ctrl->addSplitEditor(splitter);
|
||||||
|
|
||||||
|
auto* sub = m_mdiArea->addSubWindow(splitter);
|
||||||
|
sub->setWindowTitle(doc->filePath.isEmpty()
|
||||||
|
? "Untitled" : QFileInfo(doc->filePath).fileName());
|
||||||
|
sub->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
sub->showMaximized();
|
||||||
|
|
||||||
|
m_tabs[sub] = { doc, ctrl, splitter };
|
||||||
|
|
||||||
|
connect(sub, &QObject::destroyed, this, [this, sub]() {
|
||||||
|
auto it = m_tabs.find(sub);
|
||||||
|
if (it != m_tabs.end()) {
|
||||||
|
it->doc->deleteLater();
|
||||||
|
m_tabs.erase(it);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ctrl, &RcxController::nodeSelected,
|
||||||
|
this, [this, ctrl](int nodeIdx) {
|
||||||
|
if (nodeIdx >= 0 && nodeIdx < ctrl->document()->tree.nodes.size()) {
|
||||||
|
auto& node = ctrl->document()->tree.nodes[nodeIdx];
|
||||||
|
m_statusLabel->setText(
|
||||||
|
QString("%1 %2 offset: +0x%3 size: %4 bytes")
|
||||||
|
.arg(kindToString(node.kind))
|
||||||
|
.arg(node.name)
|
||||||
|
.arg(node.offset, 4, 16, QChar('0'))
|
||||||
|
.arg(node.byteSize()));
|
||||||
|
} else {
|
||||||
|
m_statusLabel->setText("Ready");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ctrl->refresh();
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::newFile() {
|
||||||
|
auto* doc = new RcxDocument(this);
|
||||||
|
|
||||||
|
// Autoload self as binary data
|
||||||
|
doc->loadData(QCoreApplication::applicationFilePath());
|
||||||
|
doc->tree.baseAddress = 0;
|
||||||
|
|
||||||
|
// Read e_lfanew to find PE header offset
|
||||||
|
uint32_t lfanew = doc->provider->readU32(0x3C);
|
||||||
|
if (lfanew < 0x40 || lfanew >= (uint32_t)doc->provider->size())
|
||||||
|
lfanew = 0x40;
|
||||||
|
uint32_t pe = lfanew; // PE signature
|
||||||
|
uint32_t fh = pe + 4; // IMAGE_FILE_HEADER
|
||||||
|
uint32_t oh = fh + 20; // IMAGE_OPTIONAL_HEADER (PE32+)
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "PE_HEADER";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.offset = 0;
|
||||||
|
int ri = doc->tree.addNode(root);
|
||||||
|
uint64_t rootId = doc->tree.nodes[ri].id;
|
||||||
|
|
||||||
|
auto add = [&](NodeKind k, const QString& name, int off) {
|
||||||
|
Node n;
|
||||||
|
n.kind = k;
|
||||||
|
n.name = name;
|
||||||
|
n.offset = off;
|
||||||
|
n.parentId = rootId;
|
||||||
|
doc->tree.addNode(n);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── IMAGE_DOS_HEADER (0x00 – 0x3F) ──
|
||||||
|
add(NodeKind::UInt16, "e_magic", 0x00);
|
||||||
|
add(NodeKind::UInt16, "e_cblp", 0x02);
|
||||||
|
add(NodeKind::UInt16, "e_cp", 0x04);
|
||||||
|
add(NodeKind::UInt16, "e_crlc", 0x06);
|
||||||
|
add(NodeKind::UInt16, "e_cparhdr", 0x08);
|
||||||
|
add(NodeKind::UInt16, "e_minalloc", 0x0A);
|
||||||
|
add(NodeKind::UInt16, "e_maxalloc", 0x0C);
|
||||||
|
add(NodeKind::UInt16, "e_ss", 0x0E);
|
||||||
|
add(NodeKind::UInt16, "e_sp", 0x10);
|
||||||
|
add(NodeKind::UInt16, "e_csum", 0x12);
|
||||||
|
add(NodeKind::UInt16, "e_ip", 0x14);
|
||||||
|
add(NodeKind::UInt16, "e_cs", 0x16);
|
||||||
|
add(NodeKind::UInt16, "e_lfarlc", 0x18);
|
||||||
|
add(NodeKind::UInt16, "e_ovno", 0x1A);
|
||||||
|
add(NodeKind::Hex64, "e_res", 0x1C);
|
||||||
|
add(NodeKind::UInt16, "e_oemid", 0x24);
|
||||||
|
add(NodeKind::UInt16, "e_oeminfo", 0x26);
|
||||||
|
add(NodeKind::Hex64, "e_res2_0", 0x28);
|
||||||
|
add(NodeKind::Hex64, "e_res2_1", 0x30);
|
||||||
|
add(NodeKind::Hex32, "e_res2_2", 0x38);
|
||||||
|
add(NodeKind::UInt32, "e_lfanew", 0x3C);
|
||||||
|
|
||||||
|
// ── DOS Stub (0x40 to PE signature) — fill with Hex nodes ──
|
||||||
|
{
|
||||||
|
int cursor = 0x40;
|
||||||
|
while (cursor + 8 <= (int)pe) {
|
||||||
|
add(NodeKind::Hex64,
|
||||||
|
QString("stub_%1").arg(cursor, 4, 16, QChar('0')),
|
||||||
|
cursor);
|
||||||
|
cursor += 8;
|
||||||
|
}
|
||||||
|
if (cursor + 4 <= (int)pe) {
|
||||||
|
add(NodeKind::Hex32,
|
||||||
|
QString("stub_%1").arg(cursor, 4, 16, QChar('0')),
|
||||||
|
cursor);
|
||||||
|
cursor += 4;
|
||||||
|
}
|
||||||
|
if (cursor + 2 <= (int)pe) {
|
||||||
|
add(NodeKind::Hex16,
|
||||||
|
QString("stub_%1").arg(cursor, 4, 16, QChar('0')),
|
||||||
|
cursor);
|
||||||
|
cursor += 2;
|
||||||
|
}
|
||||||
|
if (cursor + 1 <= (int)pe) {
|
||||||
|
add(NodeKind::Hex8,
|
||||||
|
QString("stub_%1").arg(cursor, 4, 16, QChar('0')),
|
||||||
|
cursor);
|
||||||
|
cursor += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── PE Signature ──
|
||||||
|
add(NodeKind::UInt32, "Signature", pe);
|
||||||
|
|
||||||
|
// ── IMAGE_FILE_HEADER (nested struct) ──
|
||||||
|
{
|
||||||
|
Node fhStruct;
|
||||||
|
fhStruct.kind = NodeKind::Struct;
|
||||||
|
fhStruct.name = "IMAGE_FILE_HEADER";
|
||||||
|
fhStruct.parentId = rootId;
|
||||||
|
fhStruct.offset = fh;
|
||||||
|
int fi = doc->tree.addNode(fhStruct);
|
||||||
|
uint64_t fhId = doc->tree.nodes[fi].id;
|
||||||
|
|
||||||
|
auto addFH = [&](NodeKind k, const QString& name, int off) {
|
||||||
|
Node n;
|
||||||
|
n.kind = k;
|
||||||
|
n.name = name;
|
||||||
|
n.offset = off;
|
||||||
|
n.parentId = fhId;
|
||||||
|
doc->tree.addNode(n);
|
||||||
|
};
|
||||||
|
|
||||||
|
addFH(NodeKind::UInt16, "Machine", 0x00);
|
||||||
|
addFH(NodeKind::UInt16, "NumberOfSections", 0x02);
|
||||||
|
addFH(NodeKind::UInt32, "TimeDateStamp", 0x04);
|
||||||
|
addFH(NodeKind::UInt32, "PtrToSymbolTable", 0x08);
|
||||||
|
addFH(NodeKind::UInt32, "NumberOfSymbols", 0x0C);
|
||||||
|
addFH(NodeKind::UInt16, "SizeOfOptionalHeader", 0x10);
|
||||||
|
addFH(NodeKind::UInt16, "Characteristics", 0x12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── IMAGE_OPTIONAL_HEADER64 (nested struct) ──
|
||||||
|
{
|
||||||
|
Node ohStruct;
|
||||||
|
ohStruct.kind = NodeKind::Struct;
|
||||||
|
ohStruct.name = "IMAGE_OPTIONAL_HEADER64";
|
||||||
|
ohStruct.parentId = rootId;
|
||||||
|
ohStruct.offset = oh;
|
||||||
|
int oi = doc->tree.addNode(ohStruct);
|
||||||
|
uint64_t ohId = doc->tree.nodes[oi].id;
|
||||||
|
|
||||||
|
auto addOH = [&](NodeKind k, const QString& name, int off) {
|
||||||
|
Node n;
|
||||||
|
n.kind = k;
|
||||||
|
n.name = name;
|
||||||
|
n.offset = off;
|
||||||
|
n.parentId = ohId;
|
||||||
|
doc->tree.addNode(n);
|
||||||
|
};
|
||||||
|
|
||||||
|
addOH(NodeKind::UInt16, "Magic", 0x00);
|
||||||
|
addOH(NodeKind::UInt8, "MajorLinkerVersion", 0x02);
|
||||||
|
addOH(NodeKind::UInt8, "MinorLinkerVersion", 0x03);
|
||||||
|
addOH(NodeKind::UInt32, "SizeOfCode", 0x04);
|
||||||
|
addOH(NodeKind::UInt32, "SizeOfInitData", 0x08);
|
||||||
|
addOH(NodeKind::UInt32, "SizeOfUninitData", 0x0C);
|
||||||
|
addOH(NodeKind::UInt32, "AddressOfEntryPoint", 0x10);
|
||||||
|
addOH(NodeKind::UInt32, "BaseOfCode", 0x14);
|
||||||
|
addOH(NodeKind::UInt64, "ImageBase", 0x18);
|
||||||
|
addOH(NodeKind::UInt32, "SectionAlignment", 0x20);
|
||||||
|
addOH(NodeKind::UInt32, "FileAlignment", 0x24);
|
||||||
|
addOH(NodeKind::UInt16, "MajorOSVersion", 0x28);
|
||||||
|
addOH(NodeKind::UInt16, "MinorOSVersion", 0x2A);
|
||||||
|
addOH(NodeKind::UInt16, "MajorImageVersion", 0x2C);
|
||||||
|
addOH(NodeKind::UInt16, "MinorImageVersion", 0x2E);
|
||||||
|
addOH(NodeKind::UInt16, "MajorSubsysVersion", 0x30);
|
||||||
|
addOH(NodeKind::UInt16, "MinorSubsysVersion", 0x32);
|
||||||
|
addOH(NodeKind::UInt32, "Win32VersionValue", 0x34);
|
||||||
|
addOH(NodeKind::UInt32, "SizeOfImage", 0x38);
|
||||||
|
addOH(NodeKind::UInt32, "SizeOfHeaders", 0x3C);
|
||||||
|
addOH(NodeKind::UInt32, "CheckSum", 0x40);
|
||||||
|
addOH(NodeKind::UInt16, "Subsystem", 0x44);
|
||||||
|
addOH(NodeKind::UInt16, "DllCharacteristics", 0x46);
|
||||||
|
addOH(NodeKind::UInt64, "SizeOfStackReserve", 0x48);
|
||||||
|
addOH(NodeKind::UInt64, "SizeOfStackCommit", 0x50);
|
||||||
|
addOH(NodeKind::UInt64, "SizeOfHeapReserve", 0x58);
|
||||||
|
addOH(NodeKind::UInt64, "SizeOfHeapCommit", 0x60);
|
||||||
|
addOH(NodeKind::UInt32, "LoaderFlags", 0x68);
|
||||||
|
addOH(NodeKind::UInt32, "NumberOfRvaAndSizes", 0x6C);
|
||||||
|
|
||||||
|
// Data directories (16 entries × 8 bytes)
|
||||||
|
static const char* dirNames[] = {
|
||||||
|
"Export", "Import", "Resource", "Exception",
|
||||||
|
"Security", "BaseReloc", "Debug", "Architecture",
|
||||||
|
"GlobalPtr", "TLS", "LoadConfig", "BoundImport",
|
||||||
|
"IAT", "DelayImport", "CLR", "Reserved"
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
int doff = 0x70 + i * 8;
|
||||||
|
addOH(NodeKind::UInt32, QString("%1_RVA").arg(dirNames[i]), doff);
|
||||||
|
addOH(NodeKind::UInt32, QString("%1_Size").arg(dirNames[i]), doff + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 0x100 bytes of Hex64 padding (32 nodes) ──
|
||||||
|
int padStart = oh + 0xF0; // end of optional header
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
int off = padStart + i * 8;
|
||||||
|
add(NodeKind::Hex64,
|
||||||
|
QString("pad_%1").arg(off, 4, 16, QChar('0')),
|
||||||
|
off);
|
||||||
|
}
|
||||||
|
|
||||||
|
createTab(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openFile() {
|
||||||
|
QString path = QFileDialog::getOpenFileName(this,
|
||||||
|
"Open Definition", {}, "ReclassX (*.rcx);;JSON (*.json);;All (*)");
|
||||||
|
if (path.isEmpty()) return;
|
||||||
|
|
||||||
|
auto* doc = new RcxDocument(this);
|
||||||
|
if (!doc->load(path)) {
|
||||||
|
QMessageBox::warning(this, "Error", "Failed to load: " + path);
|
||||||
|
delete doc;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createTab(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::saveFile() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (!tab) return;
|
||||||
|
if (tab->doc->filePath.isEmpty()) { saveFileAs(); return; }
|
||||||
|
tab->doc->save(tab->doc->filePath);
|
||||||
|
updateWindowTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::saveFileAs() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (!tab) return;
|
||||||
|
QString path = QFileDialog::getSaveFileName(this,
|
||||||
|
"Save Definition", {}, "ReclassX (*.rcx);;JSON (*.json)");
|
||||||
|
if (path.isEmpty()) return;
|
||||||
|
tab->doc->save(path);
|
||||||
|
updateWindowTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::loadBinary() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (!tab) return;
|
||||||
|
QString path = QFileDialog::getOpenFileName(this,
|
||||||
|
"Load Binary Data", {}, "All Files (*)");
|
||||||
|
if (path.isEmpty()) return;
|
||||||
|
tab->doc->loadData(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::addNode() {
|
||||||
|
auto* ctrl = activeController();
|
||||||
|
if (!ctrl) return;
|
||||||
|
|
||||||
|
uint64_t parentId = 0;
|
||||||
|
auto* primary = ctrl->primaryEditor();
|
||||||
|
if (primary && primary->isEditing()) return;
|
||||||
|
if (primary) {
|
||||||
|
int ni = primary->currentNodeIndex();
|
||||||
|
if (ni >= 0) {
|
||||||
|
auto& node = ctrl->document()->tree.nodes[ni];
|
||||||
|
if (node.kind == NodeKind::Struct || node.kind == NodeKind::Array)
|
||||||
|
parentId = node.id;
|
||||||
|
else
|
||||||
|
parentId = node.parentId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctrl->insertNode(parentId, -1, NodeKind::Hex64, "newField");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::removeNode() {
|
||||||
|
auto* ctrl = activeController();
|
||||||
|
if (!ctrl) return;
|
||||||
|
auto* primary = ctrl->primaryEditor();
|
||||||
|
if (!primary || primary->isEditing()) return;
|
||||||
|
QSet<int> indices = primary->selectedNodeIndices();
|
||||||
|
if (indices.size() > 1) {
|
||||||
|
ctrl->batchRemoveNodes(indices.values());
|
||||||
|
} else if (indices.size() == 1) {
|
||||||
|
ctrl->removeNode(*indices.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::changeNodeType() {
|
||||||
|
auto* ctrl = activeController();
|
||||||
|
if (!ctrl) return;
|
||||||
|
auto* primary = ctrl->primaryEditor();
|
||||||
|
if (!primary) return;
|
||||||
|
primary->beginInlineEdit(EditTarget::Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::renameNodeAction() {
|
||||||
|
auto* ctrl = activeController();
|
||||||
|
if (!ctrl) return;
|
||||||
|
auto* primary = ctrl->primaryEditor();
|
||||||
|
if (!primary) return;
|
||||||
|
primary->beginInlineEdit(EditTarget::Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::splitView() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (!tab) return;
|
||||||
|
tab->ctrl->addSplitEditor(tab->splitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::unsplitView() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (!tab) return;
|
||||||
|
auto editors = tab->ctrl->editors();
|
||||||
|
if (editors.size() > 1)
|
||||||
|
tab->ctrl->removeSplitEditor(editors.last());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::undo() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (tab) tab->doc->undoStack.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::redo() {
|
||||||
|
auto* tab = activeTab();
|
||||||
|
if (tab) tab->doc->undoStack.redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::about() {
|
||||||
|
QMessageBox::about(this, "About ReclassX",
|
||||||
|
"ReclassX - Structured Binary Editor\n"
|
||||||
|
"Built with Qt 6 + QScintilla\n\n"
|
||||||
|
"Margin-driven UI with offset display,\n"
|
||||||
|
"fold markers, and status flags.");
|
||||||
|
}
|
||||||
|
|
||||||
|
RcxController* MainWindow::activeController() const {
|
||||||
|
auto* sub = m_mdiArea->activeSubWindow();
|
||||||
|
if (sub && m_tabs.contains(sub))
|
||||||
|
return m_tabs[sub].ctrl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::TabState* MainWindow::activeTab() {
|
||||||
|
auto* sub = m_mdiArea->activeSubWindow();
|
||||||
|
if (sub && m_tabs.contains(sub))
|
||||||
|
return &m_tabs[sub];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateWindowTitle() {
|
||||||
|
auto* sub = m_mdiArea->activeSubWindow();
|
||||||
|
if (sub && m_tabs.contains(sub)) {
|
||||||
|
auto& tab = m_tabs[sub];
|
||||||
|
QString name = tab.doc->filePath.isEmpty() ? "Untitled"
|
||||||
|
: QFileInfo(tab.doc->filePath).fileName();
|
||||||
|
if (tab.doc->modified) name += " *";
|
||||||
|
setWindowTitle(name + " - ReclassX");
|
||||||
|
} else {
|
||||||
|
setWindowTitle("ReclassX");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rcx
|
||||||
|
|
||||||
|
// ── Entry point ──
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetUnhandledExceptionFilter(crashHandler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
app.setApplicationName("ReclassX");
|
||||||
|
app.setOrganizationName("ReclassX");
|
||||||
|
app.setStyle("Fusion"); // Fusion style respects dark palette well
|
||||||
|
|
||||||
|
// Global dark palette
|
||||||
|
QPalette darkPalette;
|
||||||
|
darkPalette.setColor(QPalette::Window, QColor("#1e1e1e"));
|
||||||
|
darkPalette.setColor(QPalette::WindowText, QColor("#d4d4d4"));
|
||||||
|
darkPalette.setColor(QPalette::Base, QColor("#252526"));
|
||||||
|
darkPalette.setColor(QPalette::AlternateBase, QColor("#2a2d2e"));
|
||||||
|
darkPalette.setColor(QPalette::Text, QColor("#d4d4d4"));
|
||||||
|
darkPalette.setColor(QPalette::Button, QColor("#333333"));
|
||||||
|
darkPalette.setColor(QPalette::ButtonText, QColor("#d4d4d4"));
|
||||||
|
darkPalette.setColor(QPalette::Highlight, QColor("#264f78"));
|
||||||
|
darkPalette.setColor(QPalette::HighlightedText, QColor("#ffffff"));
|
||||||
|
darkPalette.setColor(QPalette::ToolTipBase, QColor("#252526"));
|
||||||
|
darkPalette.setColor(QPalette::ToolTipText, QColor("#d4d4d4"));
|
||||||
|
darkPalette.setColor(QPalette::Mid, QColor("#3c3c3c"));
|
||||||
|
darkPalette.setColor(QPalette::Dark, QColor("#1e1e1e"));
|
||||||
|
darkPalette.setColor(QPalette::Light, QColor("#505050"));
|
||||||
|
app.setPalette(darkPalette);
|
||||||
|
|
||||||
|
rcx::MainWindow window;
|
||||||
|
|
||||||
|
bool screenshotMode = app.arguments().contains("--screenshot");
|
||||||
|
if (screenshotMode)
|
||||||
|
window.setAttribute(Qt::WA_DontShowOnScreen);
|
||||||
|
window.show();
|
||||||
|
|
||||||
|
// Always auto-open PE header demo on startup
|
||||||
|
QMetaObject::invokeMethod(&window, "newFile");
|
||||||
|
|
||||||
|
if (screenshotMode) {
|
||||||
|
QString out = "screenshot.png";
|
||||||
|
int idx = app.arguments().indexOf("--screenshot");
|
||||||
|
if (idx + 1 < app.arguments().size())
|
||||||
|
out = app.arguments().at(idx + 1);
|
||||||
|
|
||||||
|
QTimer::singleShot(1000, [&window, &app, out]() {
|
||||||
|
QDir().mkpath(QFileInfo(out).absolutePath());
|
||||||
|
window.grab().save(out);
|
||||||
|
app.quit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "main.moc"
|
||||||
674
tests/test_compose.cpp
Normal file
674
tests/test_compose.cpp
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
using namespace rcx;
|
||||||
|
|
||||||
|
class TestCompose : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testBasicStruct() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f1;
|
||||||
|
f1.kind = NodeKind::Hex32;
|
||||||
|
f1.name = "field_0";
|
||||||
|
f1.parentId = rootId;
|
||||||
|
f1.offset = 0;
|
||||||
|
tree.addNode(f1);
|
||||||
|
|
||||||
|
Node f2;
|
||||||
|
f2.kind = NodeKind::Float;
|
||||||
|
f2.name = "value";
|
||||||
|
f2.parentId = rootId;
|
||||||
|
f2.offset = 4;
|
||||||
|
tree.addNode(f2);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Header + 2 fields + footer = 4 lines
|
||||||
|
QCOMPARE(result.meta.size(), 4);
|
||||||
|
|
||||||
|
// Header is fold head
|
||||||
|
QVERIFY(result.meta[0].foldHead);
|
||||||
|
QCOMPARE(result.meta[0].lineKind, LineKind::Header);
|
||||||
|
|
||||||
|
// Fields are not fold heads
|
||||||
|
QVERIFY(!result.meta[1].foldHead);
|
||||||
|
QVERIFY(!result.meta[2].foldHead);
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
QCOMPARE(result.meta[3].lineKind, LineKind::Footer);
|
||||||
|
|
||||||
|
// Offset text
|
||||||
|
QCOMPARE(result.meta[0].offsetText, QString("+0x0"));
|
||||||
|
QCOMPARE(result.meta[1].offsetText, QString("+0x0"));
|
||||||
|
QCOMPARE(result.meta[2].offsetText, QString("+0x4"));
|
||||||
|
|
||||||
|
// Header is expanded by default (fold indicator in line text)
|
||||||
|
QVERIFY(!result.meta[0].foldCollapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testVec3Continuation() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node v;
|
||||||
|
v.kind = NodeKind::Vec3;
|
||||||
|
v.name = "pos";
|
||||||
|
v.parentId = rootId;
|
||||||
|
v.offset = 0;
|
||||||
|
tree.addNode(v);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Header + 3 Vec3 lines + footer = 5 lines
|
||||||
|
QCOMPARE(result.meta.size(), 5);
|
||||||
|
|
||||||
|
// Line 1 (first Vec3 component): not continuation
|
||||||
|
QVERIFY(!result.meta[1].isContinuation);
|
||||||
|
QCOMPARE(result.meta[1].offsetText, QString("+0x0"));
|
||||||
|
|
||||||
|
// Lines 2-3: continuation
|
||||||
|
QVERIFY(result.meta[2].isContinuation);
|
||||||
|
QCOMPARE(result.meta[2].offsetText, QString(" \u00B7"));
|
||||||
|
QVERIFY(result.meta[3].isContinuation);
|
||||||
|
QCOMPARE(result.meta[3].offsetText, QString(" \u00B7"));
|
||||||
|
|
||||||
|
// Continuation marker
|
||||||
|
QVERIFY(result.meta[2].markerMask & (1u << M_CONT));
|
||||||
|
QVERIFY(result.meta[3].markerMask & (1u << M_CONT));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPaddingMarker() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "R";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node pad;
|
||||||
|
pad.kind = NodeKind::Padding;
|
||||||
|
pad.name = "pad";
|
||||||
|
pad.parentId = rootId;
|
||||||
|
pad.offset = 0;
|
||||||
|
tree.addNode(pad);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Header + padding + footer = 3
|
||||||
|
QCOMPARE(result.meta.size(), 3);
|
||||||
|
QVERIFY(result.meta[1].markerMask & (1u << M_PAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNullPointerMarker() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "R";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "ptr";
|
||||||
|
ptr.parentId = rootId;
|
||||||
|
ptr.offset = 0;
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// Provider with zeros (null ptr)
|
||||||
|
QByteArray data(64, '\0');
|
||||||
|
FileProvider prov(data);
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
QCOMPARE(result.meta.size(), 3);
|
||||||
|
QVERIFY(result.meta[1].markerMask & (1u << M_PTR0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testCollapsedStruct() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.collapsed = true;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f;
|
||||||
|
f.kind = NodeKind::Hex32;
|
||||||
|
f.name = "field";
|
||||||
|
f.parentId = rootId;
|
||||||
|
f.offset = 0;
|
||||||
|
tree.addNode(f);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Collapsed: header + footer only = 2 lines
|
||||||
|
QCOMPARE(result.meta.size(), 2);
|
||||||
|
QVERIFY(result.meta[0].foldHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testUnreadablePointerNoRead() {
|
||||||
|
// A pointer at an unreadable address should get M_ERR, not M_PTR0
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "R";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "ptr";
|
||||||
|
ptr.parentId = rootId;
|
||||||
|
ptr.offset = 0;
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// Provider with only 4 bytes — not enough for Pointer64 (8 bytes)
|
||||||
|
QByteArray data(4, '\0');
|
||||||
|
FileProvider prov(data);
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
QCOMPARE(result.meta.size(), 3);
|
||||||
|
// Should have M_ERR, should NOT have M_PTR0
|
||||||
|
QVERIFY(result.meta[1].markerMask & (1u << M_ERR));
|
||||||
|
QVERIFY(!(result.meta[1].markerMask & (1u << M_PTR0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFoldLevels() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node child;
|
||||||
|
child.kind = NodeKind::Struct;
|
||||||
|
child.name = "Child";
|
||||||
|
child.parentId = rootId;
|
||||||
|
child.offset = 0;
|
||||||
|
int ci = tree.addNode(child);
|
||||||
|
uint64_t childId = tree.nodes[ci].id;
|
||||||
|
|
||||||
|
Node leaf;
|
||||||
|
leaf.kind = NodeKind::Hex8;
|
||||||
|
leaf.name = "x";
|
||||||
|
leaf.parentId = childId;
|
||||||
|
leaf.offset = 0;
|
||||||
|
tree.addNode(leaf);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Root header (depth 0, head) -> 0x400 | 0x2000
|
||||||
|
QCOMPARE(result.meta[0].foldLevel, 0x400 | 0x2000);
|
||||||
|
QCOMPARE(result.meta[0].depth, 0);
|
||||||
|
|
||||||
|
// Child header (depth 1, head) -> 0x401 | 0x2000
|
||||||
|
QCOMPARE(result.meta[1].foldLevel, 0x401 | 0x2000);
|
||||||
|
QCOMPARE(result.meta[1].depth, 1);
|
||||||
|
|
||||||
|
// Leaf (depth 2, not head) -> 0x402
|
||||||
|
QCOMPARE(result.meta[2].foldLevel, 0x402);
|
||||||
|
QCOMPARE(result.meta[2].depth, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNestedStruct() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Outer";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f1;
|
||||||
|
f1.kind = NodeKind::UInt32;
|
||||||
|
f1.name = "flags";
|
||||||
|
f1.parentId = rootId;
|
||||||
|
f1.offset = 0;
|
||||||
|
tree.addNode(f1);
|
||||||
|
|
||||||
|
Node inner;
|
||||||
|
inner.kind = NodeKind::Struct;
|
||||||
|
inner.name = "Inner";
|
||||||
|
inner.parentId = rootId;
|
||||||
|
inner.offset = 4;
|
||||||
|
int ii = tree.addNode(inner);
|
||||||
|
uint64_t innerId = tree.nodes[ii].id;
|
||||||
|
|
||||||
|
Node f2;
|
||||||
|
f2.kind = NodeKind::UInt16;
|
||||||
|
f2.name = "x";
|
||||||
|
f2.parentId = innerId;
|
||||||
|
f2.offset = 0;
|
||||||
|
tree.addNode(f2);
|
||||||
|
|
||||||
|
Node f3;
|
||||||
|
f3.kind = NodeKind::UInt16;
|
||||||
|
f3.name = "y";
|
||||||
|
f3.parentId = innerId;
|
||||||
|
f3.offset = 2;
|
||||||
|
tree.addNode(f3);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Outer header + flags + Inner header + x + y + Inner footer + Outer footer = 7
|
||||||
|
QCOMPARE(result.meta.size(), 7);
|
||||||
|
|
||||||
|
// Outer header
|
||||||
|
QCOMPARE(result.meta[0].lineKind, LineKind::Header);
|
||||||
|
QCOMPARE(result.meta[0].depth, 0);
|
||||||
|
QVERIFY(result.meta[0].foldHead);
|
||||||
|
|
||||||
|
// flags field
|
||||||
|
QCOMPARE(result.meta[1].lineKind, LineKind::Field);
|
||||||
|
QCOMPARE(result.meta[1].depth, 1);
|
||||||
|
|
||||||
|
// Inner header
|
||||||
|
QCOMPARE(result.meta[2].lineKind, LineKind::Header);
|
||||||
|
QCOMPARE(result.meta[2].depth, 1);
|
||||||
|
QVERIFY(result.meta[2].foldHead);
|
||||||
|
QCOMPARE(result.meta[2].foldLevel, 0x401 | 0x2000);
|
||||||
|
|
||||||
|
// Inner fields at depth 2
|
||||||
|
QCOMPARE(result.meta[3].depth, 2);
|
||||||
|
QCOMPARE(result.meta[3].foldLevel, 0x402);
|
||||||
|
QCOMPARE(result.meta[4].depth, 2);
|
||||||
|
|
||||||
|
// Inner footer
|
||||||
|
QCOMPARE(result.meta[5].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[5].depth, 1);
|
||||||
|
|
||||||
|
// Outer footer
|
||||||
|
QCOMPARE(result.meta[6].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[6].depth, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPointerDerefExpansion() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
// Main struct
|
||||||
|
Node main;
|
||||||
|
main.kind = NodeKind::Struct;
|
||||||
|
main.name = "Main";
|
||||||
|
main.parentId = 0;
|
||||||
|
main.offset = 0;
|
||||||
|
int mi = tree.addNode(main);
|
||||||
|
uint64_t mainId = tree.nodes[mi].id;
|
||||||
|
|
||||||
|
Node magic;
|
||||||
|
magic.kind = NodeKind::UInt32;
|
||||||
|
magic.name = "magic";
|
||||||
|
magic.parentId = mainId;
|
||||||
|
magic.offset = 0;
|
||||||
|
tree.addNode(magic);
|
||||||
|
|
||||||
|
// Template struct (separate root)
|
||||||
|
Node tmpl;
|
||||||
|
tmpl.kind = NodeKind::Struct;
|
||||||
|
tmpl.name = "VTable";
|
||||||
|
tmpl.parentId = 0;
|
||||||
|
tmpl.offset = 200; // far away so standalone rendering uses offset 200
|
||||||
|
int ti = tree.addNode(tmpl);
|
||||||
|
uint64_t tmplId = tree.nodes[ti].id;
|
||||||
|
|
||||||
|
Node fn1;
|
||||||
|
fn1.kind = NodeKind::UInt64;
|
||||||
|
fn1.name = "fn_one";
|
||||||
|
fn1.parentId = tmplId;
|
||||||
|
fn1.offset = 0;
|
||||||
|
tree.addNode(fn1);
|
||||||
|
|
||||||
|
Node fn2;
|
||||||
|
fn2.kind = NodeKind::UInt64;
|
||||||
|
fn2.name = "fn_two";
|
||||||
|
fn2.parentId = tmplId;
|
||||||
|
fn2.offset = 8;
|
||||||
|
tree.addNode(fn2);
|
||||||
|
|
||||||
|
// Pointer in Main referencing VTable
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "vtable_ptr";
|
||||||
|
ptr.parentId = mainId;
|
||||||
|
ptr.offset = 4;
|
||||||
|
ptr.refId = tmplId;
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// Provider: pointer at offset 4 points to address 100
|
||||||
|
QByteArray data(256, '\0');
|
||||||
|
uint64_t ptrVal = 100;
|
||||||
|
memcpy(data.data() + 4, &ptrVal, 8);
|
||||||
|
// Some data at the pointer target
|
||||||
|
uint64_t v1 = 0xDEADBEEF;
|
||||||
|
memcpy(data.data() + 100, &v1, 8);
|
||||||
|
uint64_t v2 = 0xCAFEBABE;
|
||||||
|
memcpy(data.data() + 108, &v2, 8);
|
||||||
|
FileProvider prov(data);
|
||||||
|
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Main: header + magic + ptr(fold head) + VTable header + fn1 + fn2 + VTable footer + Main footer = 8
|
||||||
|
// VTable standalone: header + fn1 + fn2 + footer = 4
|
||||||
|
// Total = 12
|
||||||
|
QCOMPARE(result.meta.size(), 12);
|
||||||
|
|
||||||
|
// Main header
|
||||||
|
QCOMPARE(result.meta[0].lineKind, LineKind::Header);
|
||||||
|
QCOMPARE(result.meta[0].depth, 0);
|
||||||
|
|
||||||
|
// magic field
|
||||||
|
QCOMPARE(result.meta[1].lineKind, LineKind::Field);
|
||||||
|
QCOMPARE(result.meta[1].depth, 1);
|
||||||
|
|
||||||
|
// Pointer as fold head
|
||||||
|
QCOMPARE(result.meta[2].lineKind, LineKind::Field);
|
||||||
|
QCOMPARE(result.meta[2].depth, 1);
|
||||||
|
QVERIFY(result.meta[2].foldHead);
|
||||||
|
QCOMPARE(result.meta[2].nodeKind, NodeKind::Pointer64);
|
||||||
|
|
||||||
|
// Expanded VTable header at depth 2
|
||||||
|
QCOMPARE(result.meta[3].lineKind, LineKind::Header);
|
||||||
|
QCOMPARE(result.meta[3].depth, 2);
|
||||||
|
|
||||||
|
// Expanded fields at depth 3
|
||||||
|
QCOMPARE(result.meta[4].depth, 3);
|
||||||
|
QCOMPARE(result.meta[5].depth, 3);
|
||||||
|
|
||||||
|
// Expanded VTable footer
|
||||||
|
QCOMPARE(result.meta[6].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[6].depth, 2);
|
||||||
|
|
||||||
|
// Main footer
|
||||||
|
QCOMPARE(result.meta[7].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[7].depth, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPointerDerefNull() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node main;
|
||||||
|
main.kind = NodeKind::Struct;
|
||||||
|
main.name = "Main";
|
||||||
|
main.parentId = 0;
|
||||||
|
main.offset = 0;
|
||||||
|
int mi = tree.addNode(main);
|
||||||
|
uint64_t mainId = tree.nodes[mi].id;
|
||||||
|
|
||||||
|
Node tmpl;
|
||||||
|
tmpl.kind = NodeKind::Struct;
|
||||||
|
tmpl.name = "Target";
|
||||||
|
tmpl.parentId = 0;
|
||||||
|
tmpl.offset = 200;
|
||||||
|
int ti = tree.addNode(tmpl);
|
||||||
|
uint64_t tmplId = tree.nodes[ti].id;
|
||||||
|
|
||||||
|
Node tf;
|
||||||
|
tf.kind = NodeKind::UInt32;
|
||||||
|
tf.name = "field";
|
||||||
|
tf.parentId = tmplId;
|
||||||
|
tf.offset = 0;
|
||||||
|
tree.addNode(tf);
|
||||||
|
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "ptr";
|
||||||
|
ptr.parentId = mainId;
|
||||||
|
ptr.offset = 0;
|
||||||
|
ptr.refId = tmplId;
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// All zeros = null pointer
|
||||||
|
QByteArray data(256, '\0');
|
||||||
|
FileProvider prov(data);
|
||||||
|
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Main: header + ptr(fold head, no expansion) + footer = 3
|
||||||
|
// Target standalone: header + field + footer = 3
|
||||||
|
// Total = 6
|
||||||
|
QCOMPARE(result.meta.size(), 6);
|
||||||
|
|
||||||
|
// Pointer is fold head but has no children (null ptr)
|
||||||
|
QCOMPARE(result.meta[1].lineKind, LineKind::Field);
|
||||||
|
QVERIFY(result.meta[1].foldHead);
|
||||||
|
|
||||||
|
// Next line is Main footer (no expansion)
|
||||||
|
QCOMPARE(result.meta[2].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[2].depth, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPointerDerefCollapsed() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node main;
|
||||||
|
main.kind = NodeKind::Struct;
|
||||||
|
main.name = "Main";
|
||||||
|
main.parentId = 0;
|
||||||
|
main.offset = 0;
|
||||||
|
int mi = tree.addNode(main);
|
||||||
|
uint64_t mainId = tree.nodes[mi].id;
|
||||||
|
|
||||||
|
Node tmpl;
|
||||||
|
tmpl.kind = NodeKind::Struct;
|
||||||
|
tmpl.name = "Target";
|
||||||
|
tmpl.parentId = 0;
|
||||||
|
tmpl.offset = 200;
|
||||||
|
int ti = tree.addNode(tmpl);
|
||||||
|
uint64_t tmplId = tree.nodes[ti].id;
|
||||||
|
|
||||||
|
Node tf;
|
||||||
|
tf.kind = NodeKind::UInt32;
|
||||||
|
tf.name = "field";
|
||||||
|
tf.parentId = tmplId;
|
||||||
|
tf.offset = 0;
|
||||||
|
tree.addNode(tf);
|
||||||
|
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "ptr";
|
||||||
|
ptr.parentId = mainId;
|
||||||
|
ptr.offset = 0;
|
||||||
|
ptr.refId = tmplId;
|
||||||
|
ptr.collapsed = true; // collapsed
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// Non-null pointer
|
||||||
|
QByteArray data(256, '\0');
|
||||||
|
uint64_t ptrVal = 100;
|
||||||
|
memcpy(data.data(), &ptrVal, 8);
|
||||||
|
FileProvider prov(data);
|
||||||
|
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Main: header + ptr(fold head, collapsed) + footer = 3
|
||||||
|
// Target standalone: header + field + footer = 3
|
||||||
|
// Total = 6
|
||||||
|
QCOMPARE(result.meta.size(), 6);
|
||||||
|
|
||||||
|
// Pointer is fold head
|
||||||
|
QVERIFY(result.meta[1].foldHead);
|
||||||
|
|
||||||
|
// No expansion — next is Main footer
|
||||||
|
QCOMPARE(result.meta[2].lineKind, LineKind::Footer);
|
||||||
|
QCOMPARE(result.meta[2].depth, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPointerDerefCycle() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node main;
|
||||||
|
main.kind = NodeKind::Struct;
|
||||||
|
main.name = "Main";
|
||||||
|
main.parentId = 0;
|
||||||
|
main.offset = 0;
|
||||||
|
int mi = tree.addNode(main);
|
||||||
|
uint64_t mainId = tree.nodes[mi].id;
|
||||||
|
|
||||||
|
// Template struct with a self-referencing pointer
|
||||||
|
Node tmpl;
|
||||||
|
tmpl.kind = NodeKind::Struct;
|
||||||
|
tmpl.name = "Recursive";
|
||||||
|
tmpl.parentId = 0;
|
||||||
|
tmpl.offset = 200;
|
||||||
|
int ti = tree.addNode(tmpl);
|
||||||
|
uint64_t tmplId = tree.nodes[ti].id;
|
||||||
|
|
||||||
|
Node tf;
|
||||||
|
tf.kind = NodeKind::UInt32;
|
||||||
|
tf.name = "data";
|
||||||
|
tf.parentId = tmplId;
|
||||||
|
tf.offset = 0;
|
||||||
|
tree.addNode(tf);
|
||||||
|
|
||||||
|
// Self-referencing pointer inside the template
|
||||||
|
Node backPtr;
|
||||||
|
backPtr.kind = NodeKind::Pointer64;
|
||||||
|
backPtr.name = "self";
|
||||||
|
backPtr.parentId = tmplId;
|
||||||
|
backPtr.offset = 4;
|
||||||
|
backPtr.refId = tmplId; // points back to same struct
|
||||||
|
tree.addNode(backPtr);
|
||||||
|
|
||||||
|
// Pointer in Main → Recursive
|
||||||
|
Node ptr;
|
||||||
|
ptr.kind = NodeKind::Pointer64;
|
||||||
|
ptr.name = "ptr";
|
||||||
|
ptr.parentId = mainId;
|
||||||
|
ptr.offset = 0;
|
||||||
|
ptr.refId = tmplId;
|
||||||
|
tree.addNode(ptr);
|
||||||
|
|
||||||
|
// Provider: main ptr at offset 0 points to 100
|
||||||
|
// Inside expansion: backPtr at offset 100+4=104 also points to 100
|
||||||
|
QByteArray data(256, '\0');
|
||||||
|
uint64_t ptrVal = 100;
|
||||||
|
memcpy(data.data(), &ptrVal, 8); // main ptr → 100
|
||||||
|
memcpy(data.data() + 104, &ptrVal, 8); // backPtr at 104 → 100
|
||||||
|
FileProvider prov(data);
|
||||||
|
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Must not infinite-loop. Verify we got a finite result.
|
||||||
|
QVERIFY(result.meta.size() > 0);
|
||||||
|
QVERIFY(result.meta.size() < 100); // sanity: bounded output
|
||||||
|
|
||||||
|
// First expansion happens: Main header + ptr fold head + Recursive header + data + backPtr fold head
|
||||||
|
// Second expansion blocked by cycle guard: no children under backPtr
|
||||||
|
// Then: Recursive footer + Main footer
|
||||||
|
// Plus standalone Recursive rendering
|
||||||
|
// The exact count depends on cycle guard behavior but must be finite
|
||||||
|
QCOMPARE(result.meta[0].lineKind, LineKind::Header); // Main header
|
||||||
|
QVERIFY(result.meta[1].foldHead); // ptr fold head
|
||||||
|
QCOMPARE(result.meta[2].lineKind, LineKind::Header); // Recursive header (expansion)
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStructFooterSizeof() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Sized";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f1;
|
||||||
|
f1.kind = NodeKind::UInt32;
|
||||||
|
f1.name = "a";
|
||||||
|
f1.parentId = rootId;
|
||||||
|
f1.offset = 0;
|
||||||
|
tree.addNode(f1);
|
||||||
|
|
||||||
|
Node f2;
|
||||||
|
f2.kind = NodeKind::UInt64;
|
||||||
|
f2.name = "b";
|
||||||
|
f2.parentId = rootId;
|
||||||
|
f2.offset = 4;
|
||||||
|
tree.addNode(f2);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
// Footer is the last line
|
||||||
|
int lastLine = result.meta.size() - 1;
|
||||||
|
QCOMPARE(result.meta[lastLine].lineKind, LineKind::Footer);
|
||||||
|
|
||||||
|
// Footer text should contain sizeof=0xC (4+8=12=0xC)
|
||||||
|
QString footerText = result.text.split('\n').last();
|
||||||
|
QVERIFY(footerText.contains("sizeof=0xC"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testLineMetaHasNodeId() {
|
||||||
|
using namespace rcx;
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
Node root; root.kind = NodeKind::Struct; root.name = "Root"; root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f; f.kind = NodeKind::Hex32; f.name = "x"; f.parentId = rootId; f.offset = 0;
|
||||||
|
tree.addNode(f);
|
||||||
|
|
||||||
|
NullProvider prov;
|
||||||
|
ComposeResult result = compose(tree, prov);
|
||||||
|
|
||||||
|
for (int i = 0; i < result.meta.size(); i++) {
|
||||||
|
QVERIFY2(result.meta[i].nodeId != 0,
|
||||||
|
qPrintable(QString("Line %1 has nodeId=0").arg(i)));
|
||||||
|
int ni = result.meta[i].nodeIdx;
|
||||||
|
QVERIFY(ni >= 0 && ni < tree.nodes.size());
|
||||||
|
QCOMPARE(result.meta[i].nodeId, tree.nodes[ni].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(TestCompose)
|
||||||
|
#include "test_compose.moc"
|
||||||
557
tests/test_core.cpp
Normal file
557
tests/test_core.cpp
Normal file
@@ -0,0 +1,557 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
class TestCore : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testSizeForKind() {
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Hex8), 1);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Hex16), 2);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Hex32), 4);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Hex64), 8);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Float), 4);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Double), 8);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Vec3), 12);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Mat4x4), 64);
|
||||||
|
QCOMPARE(rcx::sizeForKind(rcx::NodeKind::Struct), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testLinesForKind() {
|
||||||
|
QCOMPARE(rcx::linesForKind(rcx::NodeKind::Hex32), 1);
|
||||||
|
QCOMPARE(rcx::linesForKind(rcx::NodeKind::Vec2), 2);
|
||||||
|
QCOMPARE(rcx::linesForKind(rcx::NodeKind::Vec3), 3);
|
||||||
|
QCOMPARE(rcx::linesForKind(rcx::NodeKind::Vec4), 4);
|
||||||
|
QCOMPARE(rcx::linesForKind(rcx::NodeKind::Mat4x4), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testKindStringRoundTrip() {
|
||||||
|
for (int i = 0; i <= static_cast<int>(rcx::NodeKind::Array); i++) {
|
||||||
|
auto kind = static_cast<rcx::NodeKind>(i);
|
||||||
|
QString s = rcx::kindToString(kind);
|
||||||
|
QCOMPARE(rcx::kindFromString(s), kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNodeTree_addAndChildren() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node root;
|
||||||
|
root.kind = rcx::NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
QCOMPARE(ri, 0);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
rcx::Node child;
|
||||||
|
child.kind = rcx::NodeKind::Hex32;
|
||||||
|
child.name = "field";
|
||||||
|
child.parentId = rootId;
|
||||||
|
child.offset = 0;
|
||||||
|
tree.addNode(child);
|
||||||
|
|
||||||
|
auto children = tree.childrenOf(rootId);
|
||||||
|
QCOMPARE(children.size(), 1);
|
||||||
|
QCOMPARE(children[0], 1);
|
||||||
|
|
||||||
|
auto roots = tree.childrenOf(0);
|
||||||
|
QCOMPARE(roots.size(), 1);
|
||||||
|
QCOMPARE(roots[0], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNodeTree_depth() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node a; a.kind = rcx::NodeKind::Struct; a.name = "A"; a.parentId = 0;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
rcx::Node b; b.kind = rcx::NodeKind::Struct; b.name = "B"; b.parentId = aId;
|
||||||
|
int bi = tree.addNode(b);
|
||||||
|
uint64_t bId = tree.nodes[bi].id;
|
||||||
|
rcx::Node c; c.kind = rcx::NodeKind::Hex8; c.name = "c"; c.parentId = bId;
|
||||||
|
tree.addNode(c);
|
||||||
|
|
||||||
|
QCOMPARE(tree.depthOf(0), 0);
|
||||||
|
QCOMPARE(tree.depthOf(1), 1);
|
||||||
|
QCOMPARE(tree.depthOf(2), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNodeTree_computeOffset() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
tree.baseAddress = 0x1000;
|
||||||
|
rcx::Node root; root.kind = rcx::NodeKind::Struct; root.name = "R";
|
||||||
|
root.parentId = 0; root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
rcx::Node f; f.kind = rcx::NodeKind::Hex32; f.name = "f";
|
||||||
|
f.parentId = rootId; f.offset = 16;
|
||||||
|
tree.addNode(f);
|
||||||
|
|
||||||
|
QCOMPARE(tree.computeOffset(1), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNodeTree_jsonRoundTrip() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
tree.baseAddress = 0xDEAD;
|
||||||
|
rcx::Node root; root.kind = rcx::NodeKind::Struct; root.name = "Test";
|
||||||
|
root.parentId = 0; root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
rcx::Node child; child.kind = rcx::NodeKind::Float; child.name = "val";
|
||||||
|
child.parentId = rootId; child.offset = 8;
|
||||||
|
tree.addNode(child);
|
||||||
|
|
||||||
|
QJsonObject json = tree.toJson();
|
||||||
|
rcx::NodeTree tree2 = rcx::NodeTree::fromJson(json);
|
||||||
|
|
||||||
|
QCOMPARE(tree2.baseAddress, (uint64_t)0xDEAD);
|
||||||
|
QCOMPARE(tree2.nodes.size(), 2);
|
||||||
|
QCOMPARE(tree2.nodes[0].name, QString("Test"));
|
||||||
|
QCOMPARE(tree2.nodes[1].kind, rcx::NodeKind::Float);
|
||||||
|
QCOMPARE(tree2.nodes[1].offset, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFileProvider() {
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
data[0] = 0x42;
|
||||||
|
data[4] = 0x10;
|
||||||
|
data[5] = 0x20;
|
||||||
|
|
||||||
|
rcx::FileProvider prov(data);
|
||||||
|
QVERIFY(prov.isValid());
|
||||||
|
QCOMPARE(prov.size(), 16);
|
||||||
|
QCOMPARE(prov.readU8(0), (uint8_t)0x42);
|
||||||
|
QCOMPARE(prov.readU16(4), (uint16_t)0x2010);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNullProvider() {
|
||||||
|
rcx::NullProvider prov;
|
||||||
|
QVERIFY(!prov.isValid());
|
||||||
|
QVERIFY(!prov.isReadable(0, 1));
|
||||||
|
QCOMPARE(prov.readU8(0), (uint8_t)0);
|
||||||
|
QCOMPARE(prov.readU32(0), (uint32_t)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testIsReadable() {
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
rcx::FileProvider prov(data);
|
||||||
|
QVERIFY(prov.isReadable(0, 4));
|
||||||
|
QVERIFY(prov.isReadable(0, 16));
|
||||||
|
QVERIFY(!prov.isReadable(0, 17));
|
||||||
|
QVERIFY(!prov.isReadable(15, 2));
|
||||||
|
QVERIFY(prov.isReadable(15, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStableNodeIds() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node a; a.kind = rcx::NodeKind::Struct; a.name = "A"; a.parentId = 0;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
QCOMPARE(tree.nodes[ai].id, (uint64_t)1);
|
||||||
|
|
||||||
|
rcx::Node b; b.kind = rcx::NodeKind::Hex32; b.name = "B"; b.parentId = tree.nodes[ai].id;
|
||||||
|
int bi = tree.addNode(b);
|
||||||
|
QCOMPARE(tree.nodes[bi].id, (uint64_t)2);
|
||||||
|
|
||||||
|
QCOMPARE(tree.indexOfId(1), 0);
|
||||||
|
QCOMPARE(tree.indexOfId(2), 1);
|
||||||
|
QCOMPARE(tree.indexOfId(99), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testByteSizeDynamic() {
|
||||||
|
rcx::Node n;
|
||||||
|
n.kind = rcx::NodeKind::UTF8;
|
||||||
|
n.strLen = 128;
|
||||||
|
QCOMPARE(n.byteSize(), 128);
|
||||||
|
|
||||||
|
n.kind = rcx::NodeKind::UTF16;
|
||||||
|
n.strLen = 32;
|
||||||
|
QCOMPARE(n.byteSize(), 64); // 32 * 2
|
||||||
|
|
||||||
|
n.kind = rcx::NodeKind::Float;
|
||||||
|
QCOMPARE(n.byteSize(), 4); // falls back to sizeForKind
|
||||||
|
}
|
||||||
|
|
||||||
|
void testSubtreeCycleSafe() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node a; a.kind = rcx::NodeKind::Struct; a.name = "A"; a.parentId = 0;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
|
||||||
|
// Create a child that points back to A's id as parent — not a cycle per se,
|
||||||
|
// but test that subtree collection terminates
|
||||||
|
rcx::Node b; b.kind = rcx::NodeKind::Hex8; b.name = "B"; b.parentId = aId;
|
||||||
|
tree.addNode(b);
|
||||||
|
|
||||||
|
// Should return both nodes without hanging
|
||||||
|
auto sub = tree.subtreeIndices(aId);
|
||||||
|
QCOMPARE(sub.size(), 2);
|
||||||
|
QVERIFY(sub.contains(0));
|
||||||
|
QVERIFY(sub.contains(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testIsReadableOverflow() {
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
rcx::FileProvider prov(data);
|
||||||
|
// Normal cases
|
||||||
|
QVERIFY(prov.isReadable(0, 16));
|
||||||
|
QVERIFY(!prov.isReadable(0, 17));
|
||||||
|
// Large address
|
||||||
|
QVERIFY(!prov.isReadable(0xFFFFFFFFFFFFFFFFULL, 1));
|
||||||
|
// Negative len
|
||||||
|
QVERIFY(!prov.isReadable(0, -1));
|
||||||
|
// Zero len is readable
|
||||||
|
QVERIFY(prov.isReadable(0, 0));
|
||||||
|
QVERIFY(prov.isReadable(16, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testAlignmentFor() {
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Hex8), 1);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Hex16), 2);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Hex32), 4);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Hex64), 8);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Float), 4);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Double), 8);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Vec3), 4);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Mat4x4), 4);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::UTF8), 1);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::UTF16), 2);
|
||||||
|
QCOMPARE(rcx::alignmentFor(rcx::NodeKind::Struct), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testDepthOfCycle() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
// Create two nodes that reference each other as parents
|
||||||
|
rcx::Node a; a.kind = rcx::NodeKind::Struct; a.name = "A"; a.parentId = 0;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
|
||||||
|
rcx::Node b; b.kind = rcx::NodeKind::Struct; b.name = "B"; b.parentId = aId;
|
||||||
|
int bi = tree.addNode(b);
|
||||||
|
uint64_t bId = tree.nodes[bi].id;
|
||||||
|
|
||||||
|
// Manually create a cycle: A's parent → B
|
||||||
|
tree.nodes[ai].parentId = bId;
|
||||||
|
tree.invalidateIdCache();
|
||||||
|
|
||||||
|
// Should not hang — cycle detection terminates
|
||||||
|
int d = tree.depthOf(ai);
|
||||||
|
QVERIFY(d < 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testComputeOffsetCycle() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node a; a.kind = rcx::NodeKind::Struct; a.name = "A"; a.parentId = 0; a.offset = 10;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
|
||||||
|
rcx::Node b; b.kind = rcx::NodeKind::Struct; b.name = "B"; b.parentId = aId; b.offset = 20;
|
||||||
|
int bi = tree.addNode(b);
|
||||||
|
uint64_t bId = tree.nodes[bi].id;
|
||||||
|
|
||||||
|
// Create cycle: A → B → A
|
||||||
|
tree.nodes[ai].parentId = bId;
|
||||||
|
tree.invalidateIdCache();
|
||||||
|
|
||||||
|
// Should not hang
|
||||||
|
int off = tree.computeOffset(ai);
|
||||||
|
Q_UNUSED(off);
|
||||||
|
QVERIFY(true); // reaching here means no hang
|
||||||
|
}
|
||||||
|
|
||||||
|
void testProviderWrite() {
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
rcx::FileProvider prov(data);
|
||||||
|
QVERIFY(prov.isWritable());
|
||||||
|
|
||||||
|
QByteArray patch;
|
||||||
|
patch.append((char)0x42);
|
||||||
|
patch.append((char)0x43);
|
||||||
|
QVERIFY(prov.writeBytes(0, patch));
|
||||||
|
QCOMPARE(prov.readU8(0), (uint8_t)0x42);
|
||||||
|
QCOMPARE(prov.readU8(1), (uint8_t)0x43);
|
||||||
|
|
||||||
|
// Write past end should fail
|
||||||
|
QVERIFY(!prov.writeBytes(15, patch));
|
||||||
|
|
||||||
|
// NullProvider is not writable
|
||||||
|
rcx::NullProvider np;
|
||||||
|
QVERIFY(!np.isWritable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void testComputeOffsetLarge() {
|
||||||
|
// Verify computeOffset returns int64_t that doesn't overflow
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node root; root.kind = rcx::NodeKind::Struct; root.name = "R";
|
||||||
|
root.parentId = 0; root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
rcx::Node child; child.kind = rcx::NodeKind::Hex8; child.name = "f";
|
||||||
|
child.parentId = rootId; child.offset = 0x7FFFFFFF; // max int32
|
||||||
|
tree.addNode(child);
|
||||||
|
|
||||||
|
int64_t off = tree.computeOffset(1);
|
||||||
|
QCOMPARE(off, (int64_t)0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testKindMetaCompleteness() {
|
||||||
|
// Every NodeKind enum value must have a KindMeta entry
|
||||||
|
for (int i = 0; i <= static_cast<int>(rcx::NodeKind::Array); i++) {
|
||||||
|
auto kind = static_cast<rcx::NodeKind>(i);
|
||||||
|
const rcx::KindMeta* m = rcx::kindMeta(kind);
|
||||||
|
QVERIFY2(m != nullptr,
|
||||||
|
qPrintable(QString("Missing KindMeta for kind %1").arg(i)));
|
||||||
|
QCOMPARE(m->kind, kind);
|
||||||
|
QVERIFY(m->name != nullptr);
|
||||||
|
QVERIFY(m->typeName != nullptr);
|
||||||
|
QVERIFY(m->lines >= 1);
|
||||||
|
QVERIFY(m->align >= 1);
|
||||||
|
}
|
||||||
|
// sizeForKind/linesForKind/alignmentFor must agree with table
|
||||||
|
for (const auto& m : rcx::kKindMeta) {
|
||||||
|
QCOMPARE(rcx::sizeForKind(m.kind), m.size);
|
||||||
|
QCOMPARE(rcx::linesForKind(m.kind), m.lines);
|
||||||
|
QCOMPARE(rcx::alignmentFor(m.kind), m.align);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testColumnSpan_field() {
|
||||||
|
rcx::LineMeta lm;
|
||||||
|
lm.lineKind = rcx::LineKind::Field;
|
||||||
|
lm.depth = 1;
|
||||||
|
lm.isContinuation = false;
|
||||||
|
lm.nodeIdx = 0;
|
||||||
|
|
||||||
|
// kFoldCol (3) + depth*3 = 6
|
||||||
|
auto ts = rcx::typeSpanFor(lm);
|
||||||
|
QVERIFY(ts.valid);
|
||||||
|
QCOMPARE(ts.start, 6);
|
||||||
|
QCOMPARE(ts.end, 16); // 6 + 10
|
||||||
|
|
||||||
|
auto ns = rcx::nameSpanFor(lm);
|
||||||
|
QVERIFY(ns.valid);
|
||||||
|
QCOMPARE(ns.start, 18); // 6 + 10 + 2
|
||||||
|
QCOMPARE(ns.end, 42); // 18 + 24
|
||||||
|
|
||||||
|
auto vs = rcx::valueSpanFor(lm, 60);
|
||||||
|
QVERIFY(vs.valid);
|
||||||
|
QCOMPARE(vs.start, 44); // 18 + 24 + 2
|
||||||
|
QCOMPARE(vs.end, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testColumnSpan_continuation() {
|
||||||
|
rcx::LineMeta lm;
|
||||||
|
lm.lineKind = rcx::LineKind::Continuation;
|
||||||
|
lm.depth = 1;
|
||||||
|
lm.isContinuation = true;
|
||||||
|
lm.nodeIdx = 0;
|
||||||
|
|
||||||
|
QVERIFY(!rcx::typeSpanFor(lm).valid);
|
||||||
|
QVERIFY(!rcx::nameSpanFor(lm).valid);
|
||||||
|
|
||||||
|
auto vs = rcx::valueSpanFor(lm, 60);
|
||||||
|
QVERIFY(vs.valid);
|
||||||
|
QCOMPARE(vs.start, 6 + 10 + 24 + 4); // kFoldCol+indent + COL_TYPE + COL_NAME + 4
|
||||||
|
QCOMPARE(vs.end, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testColumnSpan_headerFooter() {
|
||||||
|
rcx::LineMeta lm;
|
||||||
|
lm.lineKind = rcx::LineKind::Header;
|
||||||
|
lm.depth = 0;
|
||||||
|
lm.nodeIdx = 0;
|
||||||
|
|
||||||
|
QVERIFY(!rcx::typeSpanFor(lm).valid);
|
||||||
|
QVERIFY(!rcx::nameSpanFor(lm).valid);
|
||||||
|
QVERIFY(!rcx::valueSpanFor(lm, 40).valid);
|
||||||
|
|
||||||
|
lm.lineKind = rcx::LineKind::Footer;
|
||||||
|
QVERIFY(!rcx::typeSpanFor(lm).valid);
|
||||||
|
QVERIFY(!rcx::nameSpanFor(lm).valid);
|
||||||
|
QVERIFY(!rcx::valueSpanFor(lm, 40).valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testColumnSpan_depth0() {
|
||||||
|
rcx::LineMeta lm;
|
||||||
|
lm.lineKind = rcx::LineKind::Field;
|
||||||
|
lm.depth = 0;
|
||||||
|
lm.isContinuation = false;
|
||||||
|
lm.nodeIdx = 0;
|
||||||
|
|
||||||
|
// kFoldCol (3) + depth*3(0) = 3
|
||||||
|
auto ts = rcx::typeSpanFor(lm);
|
||||||
|
QVERIFY(ts.valid);
|
||||||
|
QCOMPARE(ts.start, 3);
|
||||||
|
QCOMPARE(ts.end, 13); // 3 + 10
|
||||||
|
|
||||||
|
auto ns = rcx::nameSpanFor(lm);
|
||||||
|
QVERIFY(ns.valid);
|
||||||
|
QCOMPARE(ns.start, 15); // 3 + 10 + 2
|
||||||
|
QCOMPARE(ns.end, 39); // 15 + 24
|
||||||
|
|
||||||
|
auto vs = rcx::valueSpanFor(lm, 50);
|
||||||
|
QVERIFY(vs.valid);
|
||||||
|
QCOMPARE(vs.start, 41); // 15 + 24 + 2
|
||||||
|
QCOMPARE(vs.end, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNodeIdJsonRoundTrip() {
|
||||||
|
rcx::NodeTree tree;
|
||||||
|
rcx::Node n; n.kind = rcx::NodeKind::Float; n.name = "x"; n.parentId = 0;
|
||||||
|
tree.addNode(n);
|
||||||
|
tree.addNode(n);
|
||||||
|
|
||||||
|
QJsonObject json = tree.toJson();
|
||||||
|
rcx::NodeTree t2 = rcx::NodeTree::fromJson(json);
|
||||||
|
QCOMPARE(t2.nodes[0].id, tree.nodes[0].id);
|
||||||
|
QCOMPARE(t2.nodes[1].id, tree.nodes[1].id);
|
||||||
|
QVERIFY(t2.m_nextId >= 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStructSpan() {
|
||||||
|
using namespace rcx;
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
// Struct with UInt32 (offset 0, 4 bytes) + UInt64 (offset 4, 8 bytes)
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "Root";
|
||||||
|
root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f1;
|
||||||
|
f1.kind = NodeKind::UInt32;
|
||||||
|
f1.name = "a";
|
||||||
|
f1.parentId = rootId;
|
||||||
|
f1.offset = 0;
|
||||||
|
tree.addNode(f1);
|
||||||
|
|
||||||
|
Node f2;
|
||||||
|
f2.kind = NodeKind::UInt64;
|
||||||
|
f2.name = "b";
|
||||||
|
f2.parentId = rootId;
|
||||||
|
f2.offset = 4;
|
||||||
|
tree.addNode(f2);
|
||||||
|
|
||||||
|
// Span = max(0+4, 4+8) = 12
|
||||||
|
QCOMPARE(tree.structSpan(rootId), 12);
|
||||||
|
|
||||||
|
// Nested struct: inner at offset 0 with a UInt64 at offset 0 (size 8)
|
||||||
|
NodeTree tree2;
|
||||||
|
Node outer;
|
||||||
|
outer.kind = NodeKind::Struct;
|
||||||
|
outer.name = "Outer";
|
||||||
|
outer.parentId = 0;
|
||||||
|
int oi = tree2.addNode(outer);
|
||||||
|
uint64_t outerId = tree2.nodes[oi].id;
|
||||||
|
|
||||||
|
Node inner;
|
||||||
|
inner.kind = NodeKind::Struct;
|
||||||
|
inner.name = "Inner";
|
||||||
|
inner.parentId = outerId;
|
||||||
|
inner.offset = 0;
|
||||||
|
int ii = tree2.addNode(inner);
|
||||||
|
uint64_t innerId = tree2.nodes[ii].id;
|
||||||
|
|
||||||
|
Node leaf;
|
||||||
|
leaf.kind = NodeKind::UInt64;
|
||||||
|
leaf.name = "x";
|
||||||
|
leaf.parentId = innerId;
|
||||||
|
leaf.offset = 0;
|
||||||
|
tree2.addNode(leaf);
|
||||||
|
|
||||||
|
// Inner span = 8, outer span = max(0+8) = 8
|
||||||
|
QCOMPARE(tree2.structSpan(innerId), 8);
|
||||||
|
QCOMPARE(tree2.structSpan(outerId), 8);
|
||||||
|
|
||||||
|
// Empty struct = 0
|
||||||
|
NodeTree tree3;
|
||||||
|
Node empty;
|
||||||
|
empty.kind = NodeKind::Struct;
|
||||||
|
empty.name = "Empty";
|
||||||
|
empty.parentId = 0;
|
||||||
|
int ei = tree3.addNode(empty);
|
||||||
|
QCOMPARE(tree3.structSpan(tree3.nodes[ei].id), 0);
|
||||||
|
}
|
||||||
|
void testNormalizePreferAncestors() {
|
||||||
|
using namespace rcx;
|
||||||
|
NodeTree tree;
|
||||||
|
// Root -> A -> leaf
|
||||||
|
Node root; root.kind = NodeKind::Struct; root.name = "R"; root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node a; a.kind = NodeKind::Struct; a.name = "A"; a.parentId = rootId;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
|
||||||
|
Node leaf; leaf.kind = NodeKind::Hex8; leaf.name = "x"; leaf.parentId = aId;
|
||||||
|
int li = tree.addNode(leaf);
|
||||||
|
uint64_t leafId = tree.nodes[li].id;
|
||||||
|
|
||||||
|
// Select root + leaf: leaf should be pruned (root is ancestor)
|
||||||
|
QSet<uint64_t> sel = {rootId, leafId};
|
||||||
|
QSet<uint64_t> norm = tree.normalizePreferAncestors(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(rootId));
|
||||||
|
|
||||||
|
// Select A + leaf: leaf pruned (A is ancestor)
|
||||||
|
sel = {aId, leafId};
|
||||||
|
norm = tree.normalizePreferAncestors(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(aId));
|
||||||
|
|
||||||
|
// Select root + A: A pruned (root is ancestor)
|
||||||
|
sel = {rootId, aId};
|
||||||
|
norm = tree.normalizePreferAncestors(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(rootId));
|
||||||
|
|
||||||
|
// Select only leaf: nothing pruned
|
||||||
|
sel = {leafId};
|
||||||
|
norm = tree.normalizePreferAncestors(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(leafId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNormalizePreferDescendants() {
|
||||||
|
using namespace rcx;
|
||||||
|
NodeTree tree;
|
||||||
|
Node root; root.kind = NodeKind::Struct; root.name = "R"; root.parentId = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node a; a.kind = NodeKind::UInt32; a.name = "a"; a.parentId = rootId;
|
||||||
|
int ai = tree.addNode(a);
|
||||||
|
uint64_t aId = tree.nodes[ai].id;
|
||||||
|
|
||||||
|
Node b; b.kind = NodeKind::UInt32; b.name = "b"; b.parentId = rootId; b.offset = 4;
|
||||||
|
int bi = tree.addNode(b);
|
||||||
|
uint64_t bId = tree.nodes[bi].id;
|
||||||
|
|
||||||
|
// Select root + a + b: root dropped (has selected descendants)
|
||||||
|
QSet<uint64_t> sel = {rootId, aId, bId};
|
||||||
|
QSet<uint64_t> norm = tree.normalizePreferDescendants(sel);
|
||||||
|
QCOMPARE(norm.size(), 2);
|
||||||
|
QVERIFY(norm.contains(aId));
|
||||||
|
QVERIFY(norm.contains(bId));
|
||||||
|
QVERIFY(!norm.contains(rootId));
|
||||||
|
|
||||||
|
// Select root + a: root dropped, a kept
|
||||||
|
sel = {rootId, aId};
|
||||||
|
norm = tree.normalizePreferDescendants(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(aId));
|
||||||
|
|
||||||
|
// Select only root: nothing dropped (no descendants selected)
|
||||||
|
sel = {rootId};
|
||||||
|
norm = tree.normalizePreferDescendants(sel);
|
||||||
|
QCOMPARE(norm.size(), 1);
|
||||||
|
QVERIFY(norm.contains(rootId));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(TestCore)
|
||||||
|
#include "test_core.moc"
|
||||||
442
tests/test_editor.cpp
Normal file
442
tests/test_editor.cpp
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
#include <QtTest/QSignalSpy>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QFocusEvent>
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
#include "editor.h"
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
using namespace rcx;
|
||||||
|
|
||||||
|
// Minimal provider for testing
|
||||||
|
static FileProvider makeTestProvider() {
|
||||||
|
QByteArray data(256, '\0');
|
||||||
|
// Write known values: uint16_t=23117 at offset 0, Hex64 at offset 8
|
||||||
|
uint16_t u16 = 23117;
|
||||||
|
memcpy(data.data(), &u16, 2);
|
||||||
|
uint64_t h64 = 0x4D5A900000000000ULL;
|
||||||
|
memcpy(data.data() + 8, &h64, 8);
|
||||||
|
return FileProvider(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a simple tree with a struct containing a few fields
|
||||||
|
static NodeTree makeTestTree() {
|
||||||
|
NodeTree tree;
|
||||||
|
tree.baseAddress = 0;
|
||||||
|
|
||||||
|
Node root;
|
||||||
|
root.kind = NodeKind::Struct;
|
||||||
|
root.name = "TestStruct";
|
||||||
|
root.parentId = 0;
|
||||||
|
root.offset = 0;
|
||||||
|
int ri = tree.addNode(root);
|
||||||
|
uint64_t rootId = tree.nodes[ri].id;
|
||||||
|
|
||||||
|
Node f1;
|
||||||
|
f1.kind = NodeKind::UInt16;
|
||||||
|
f1.name = "field_u16";
|
||||||
|
f1.parentId = rootId;
|
||||||
|
f1.offset = 0;
|
||||||
|
tree.addNode(f1);
|
||||||
|
|
||||||
|
Node f2;
|
||||||
|
f2.kind = NodeKind::Hex64;
|
||||||
|
f2.name = "field_hex";
|
||||||
|
f2.parentId = rootId;
|
||||||
|
f2.offset = 8;
|
||||||
|
tree.addNode(f2);
|
||||||
|
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestEditor : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
RcxEditor* m_editor = nullptr;
|
||||||
|
ComposeResult m_result;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase() {
|
||||||
|
m_editor = new RcxEditor();
|
||||||
|
m_editor->resize(800, 600);
|
||||||
|
m_editor->show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(m_editor));
|
||||||
|
|
||||||
|
NodeTree tree = makeTestTree();
|
||||||
|
FileProvider prov = makeTestProvider();
|
||||||
|
m_result = compose(tree, prov);
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanupTestCase() {
|
||||||
|
delete m_editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: inline edit lifecycle (begin → commit → re-edit) ──
|
||||||
|
void testInlineEditReEntry() {
|
||||||
|
// Move cursor to line 1 (first field inside struct)
|
||||||
|
m_editor->scintilla()->setCursorPosition(1, 0);
|
||||||
|
|
||||||
|
// Should not be editing
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
|
||||||
|
// Begin edit on Name column
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Name, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Cancel the edit
|
||||||
|
m_editor->cancelInlineEdit();
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
|
||||||
|
// Re-apply document (simulates controller refresh)
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Should be able to edit again
|
||||||
|
ok = m_editor->beginInlineEdit(EditTarget::Name, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Cancel again
|
||||||
|
m_editor->cancelInlineEdit();
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: commit inline edit then re-edit same line ──
|
||||||
|
void testCommitThenReEdit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
m_editor->scintilla()->setCursorPosition(1, 0);
|
||||||
|
|
||||||
|
// Begin value edit
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Value, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Simulate Enter key → commit (via signal spy)
|
||||||
|
QSignalSpy spy(m_editor, &RcxEditor::inlineEditCommitted);
|
||||||
|
QKeyEvent enter(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla(), &enter);
|
||||||
|
|
||||||
|
// Should have emitted commit signal and exited edit mode
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
|
||||||
|
// Re-apply document (simulates refresh)
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Must be able to edit the same line again
|
||||||
|
ok = m_editor->beginInlineEdit(EditTarget::Value, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
m_editor->cancelInlineEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: mouse click during edit commits it ──
|
||||||
|
void testMouseClickCommitsEdit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Name, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Simulate mouse click on viewport — should commit (save), not cancel
|
||||||
|
QSignalSpy commitSpy(m_editor, &RcxEditor::inlineEditCommitted);
|
||||||
|
QSignalSpy cancelSpy(m_editor, &RcxEditor::inlineEditCancelled);
|
||||||
|
QMouseEvent click(QEvent::MouseButtonPress, QPointF(10, 10),
|
||||||
|
QPointF(10, 10), Qt::LeftButton,
|
||||||
|
Qt::LeftButton, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla()->viewport(), &click);
|
||||||
|
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
QCOMPARE(commitSpy.count(), 1);
|
||||||
|
QCOMPARE(cancelSpy.count(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: FocusOut during edit commits it ──
|
||||||
|
void testFocusOutCommitsEdit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Give focus to the scintilla widget first
|
||||||
|
m_editor->scintilla()->setFocus();
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Name, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
QSignalSpy commitSpy(m_editor, &RcxEditor::inlineEditCommitted);
|
||||||
|
QSignalSpy cancelSpy(m_editor, &RcxEditor::inlineEditCancelled);
|
||||||
|
|
||||||
|
// Create a dummy widget and transfer focus to it (triggers real FocusOut)
|
||||||
|
QWidget dummy;
|
||||||
|
dummy.show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&dummy));
|
||||||
|
dummy.setFocus();
|
||||||
|
QApplication::processEvents(); // process focus change + deferred timer
|
||||||
|
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
QCOMPARE(commitSpy.count(), 1);
|
||||||
|
QCOMPARE(cancelSpy.count(), 0);
|
||||||
|
|
||||||
|
// Restore focus to editor for subsequent tests
|
||||||
|
m_editor->scintilla()->setFocus();
|
||||||
|
QApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: type edit begins and can be cancelled ──
|
||||||
|
void testTypeEditCancel() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Begin type edit on a field line
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Type, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Process deferred events (showTypeAutocomplete is deferred via QTimer)
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// First Escape closes autocomplete popup (if active) or cancels edit
|
||||||
|
QKeyEvent esc1(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla(), &esc1);
|
||||||
|
|
||||||
|
// If autocomplete was open, first Esc only closed popup; need second Esc
|
||||||
|
if (m_editor->isEditing()) {
|
||||||
|
QKeyEvent esc2(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla(), &esc2);
|
||||||
|
}
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: edit on header line (Name is valid, Type/Value invalid) ──
|
||||||
|
void testHeaderLineEdit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Line 0 should be the struct header
|
||||||
|
const LineMeta* lm = m_editor->metaForLine(0);
|
||||||
|
QVERIFY(lm);
|
||||||
|
QCOMPARE(lm->lineKind, LineKind::Header);
|
||||||
|
|
||||||
|
// Type edit on header should fail (no type span)
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Type, 0);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
|
||||||
|
// Name edit on header should succeed (dynamic span)
|
||||||
|
ok = m_editor->beginInlineEdit(EditTarget::Name, 0);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
m_editor->cancelInlineEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: footer line rejects all edits ──
|
||||||
|
void testFooterLineEdit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Find the footer line
|
||||||
|
int footerLine = -1;
|
||||||
|
for (int i = 0; i < m_result.meta.size(); i++) {
|
||||||
|
if (m_result.meta[i].lineKind == LineKind::Footer) {
|
||||||
|
footerLine = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QVERIFY(footerLine >= 0);
|
||||||
|
|
||||||
|
QVERIFY(!m_editor->beginInlineEdit(EditTarget::Type, footerLine));
|
||||||
|
QVERIFY(!m_editor->beginInlineEdit(EditTarget::Name, footerLine));
|
||||||
|
QVERIFY(!m_editor->beginInlineEdit(EditTarget::Value, footerLine));
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: showTypeAutocomplete populates list (check via SCI_AUTOCACTIVE) ──
|
||||||
|
void testTypeAutocompleteShows() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Type, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
|
||||||
|
// Process deferred timer (autocomplete is deferred)
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// Check if the user list is active
|
||||||
|
long active = m_editor->scintilla()->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_AUTOCACTIVE);
|
||||||
|
QVERIFY2(active != 0, "Autocomplete list should be active after type edit begins");
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
m_editor->cancelInlineEdit();
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: parseValue accepts space-separated hex bytes ──
|
||||||
|
void testParseValueHexWithSpaces() {
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
// Hex8 with spaces (single byte, but test the .remove(' '))
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Hex8, "4D", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE((uint8_t)b[0], (uint8_t)0x4D);
|
||||||
|
|
||||||
|
// Hex32 with space-separated bytes
|
||||||
|
b = fmt::parseValue(NodeKind::Hex32, "DE AD BE EF", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 4);
|
||||||
|
uint32_t v32;
|
||||||
|
memcpy(&v32, b.data(), 4);
|
||||||
|
QCOMPARE(v32, (uint32_t)0xDEADBEEF);
|
||||||
|
|
||||||
|
// Hex64 with space-separated bytes
|
||||||
|
b = fmt::parseValue(NodeKind::Hex64, "4D 5A 90 00 00 00 00 00", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 8);
|
||||||
|
uint64_t v64;
|
||||||
|
memcpy(&v64, b.data(), 8);
|
||||||
|
QCOMPARE(v64, (uint64_t)0x4D5A900000000000ULL);
|
||||||
|
|
||||||
|
// Hex64 continuous (should still work)
|
||||||
|
b = fmt::parseValue(NodeKind::Hex64, "4D5A900000000000", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
memcpy(&v64, b.data(), 8);
|
||||||
|
QCOMPARE(v64, (uint64_t)0x4D5A900000000000ULL);
|
||||||
|
|
||||||
|
// Hex64 with 0x prefix and spaces
|
||||||
|
b = fmt::parseValue(NodeKind::Hex64, "0x4D 5A 90 00 00 00 00 00", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: type autocomplete accepts typed input and commits ──
|
||||||
|
void testTypeAutocompleteTypingAndCommit() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Type, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
|
||||||
|
// Process deferred autocomplete
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// Verify autocomplete is active
|
||||||
|
long active = m_editor->scintilla()->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_AUTOCACTIVE);
|
||||||
|
QVERIFY2(active != 0, "Autocomplete should be active");
|
||||||
|
|
||||||
|
// Simulate typing 'i' — filters to typeName entries starting with 'i'
|
||||||
|
QKeyEvent keyI(QEvent::KeyPress, Qt::Key_I, Qt::NoModifier, "i");
|
||||||
|
QApplication::sendEvent(m_editor->scintilla(), &keyI);
|
||||||
|
|
||||||
|
// Still editing
|
||||||
|
QVERIFY(m_editor->isEditing());
|
||||||
|
|
||||||
|
// Simulate Enter to select from autocomplete (handled synchronously)
|
||||||
|
QSignalSpy spy(m_editor, &RcxEditor::inlineEditCommitted);
|
||||||
|
QKeyEvent enter(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla(), &enter);
|
||||||
|
|
||||||
|
// Should have committed immediately (no deferred timer for type edits)
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
|
||||||
|
// The committed text should be a valid typeName starting with 'i'
|
||||||
|
QList<QVariant> args = spy.first();
|
||||||
|
QString committedText = args.at(3).toString();
|
||||||
|
QVERIFY2(committedText.startsWith('i'),
|
||||||
|
qPrintable("Expected typeName starting with 'i', got: " + committedText));
|
||||||
|
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: type edit click-away commits original (no change) ──
|
||||||
|
void testTypeEditClickAwayNoChange() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
bool ok = m_editor->beginInlineEdit(EditTarget::Type, 1);
|
||||||
|
QVERIFY(ok);
|
||||||
|
|
||||||
|
// Process deferred autocomplete
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// Click away on viewport — should commit (not cancel)
|
||||||
|
QSignalSpy commitSpy(m_editor, &RcxEditor::inlineEditCommitted);
|
||||||
|
QMouseEvent click(QEvent::MouseButtonPress, QPointF(10, 10),
|
||||||
|
QPointF(10, 10), Qt::LeftButton,
|
||||||
|
Qt::LeftButton, Qt::NoModifier);
|
||||||
|
QApplication::sendEvent(m_editor->scintilla()->viewport(), &click);
|
||||||
|
|
||||||
|
QVERIFY(!m_editor->isEditing());
|
||||||
|
QCOMPARE(commitSpy.count(), 1);
|
||||||
|
|
||||||
|
// The committed text should be the original typeName (no change)
|
||||||
|
QList<QVariant> args = commitSpy.first();
|
||||||
|
QString committedText = args.at(3).toString();
|
||||||
|
QVERIFY2(committedText == "uint16_t",
|
||||||
|
qPrintable("Expected 'uint16_t', got: " + committedText));
|
||||||
|
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: column span hit-testing for cursor shape ──
|
||||||
|
void testColumnSpanHitTest() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Line 1 is a field line (UInt16), verify spans are valid
|
||||||
|
const LineMeta* lm = m_editor->metaForLine(1);
|
||||||
|
QVERIFY(lm);
|
||||||
|
QCOMPARE(lm->lineKind, LineKind::Field);
|
||||||
|
|
||||||
|
// Type span should be valid for field lines
|
||||||
|
ColumnSpan ts = RcxEditor::typeSpan(*lm);
|
||||||
|
QVERIFY(ts.valid);
|
||||||
|
QVERIFY(ts.start < ts.end);
|
||||||
|
|
||||||
|
// Name span should be valid for field lines
|
||||||
|
ColumnSpan ns = RcxEditor::nameSpan(*lm);
|
||||||
|
QVERIFY(ns.valid);
|
||||||
|
QVERIFY(ns.start < ns.end);
|
||||||
|
|
||||||
|
// Value span should be valid for field lines
|
||||||
|
QString lineText;
|
||||||
|
int len = (int)m_editor->scintilla()->SendScintilla(
|
||||||
|
QsciScintillaBase::SCI_LINELENGTH, (unsigned long)1);
|
||||||
|
QVERIFY(len > 0);
|
||||||
|
ColumnSpan vs = RcxEditor::valueSpan(*lm, len);
|
||||||
|
QVERIFY(vs.valid);
|
||||||
|
QVERIFY(vs.start < vs.end);
|
||||||
|
|
||||||
|
// Footer line should have no valid type/name spans
|
||||||
|
int footerLine = -1;
|
||||||
|
for (int i = 0; i < m_result.meta.size(); i++) {
|
||||||
|
if (m_result.meta[i].lineKind == LineKind::Footer) {
|
||||||
|
footerLine = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QVERIFY(footerLine >= 0);
|
||||||
|
const LineMeta* flm = m_editor->metaForLine(footerLine);
|
||||||
|
QVERIFY(flm);
|
||||||
|
ColumnSpan fts = RcxEditor::typeSpan(*flm);
|
||||||
|
QVERIFY(!fts.valid);
|
||||||
|
ColumnSpan fns = RcxEditor::nameSpan(*flm);
|
||||||
|
QVERIFY(!fns.valid);
|
||||||
|
ColumnSpan fvs = RcxEditor::valueSpan(*flm, 10);
|
||||||
|
QVERIFY(!fvs.valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test: selectedNodeIndices ──
|
||||||
|
void testSelectedNodeIndices() {
|
||||||
|
m_editor->applyDocument(m_result);
|
||||||
|
|
||||||
|
// Put cursor on first field line
|
||||||
|
m_editor->scintilla()->setCursorPosition(1, 0);
|
||||||
|
QSet<int> sel = m_editor->selectedNodeIndices();
|
||||||
|
QCOMPARE(sel.size(), 1);
|
||||||
|
|
||||||
|
// The node index should match the first field
|
||||||
|
const LineMeta* lm = m_editor->metaForLine(1);
|
||||||
|
QVERIFY(lm);
|
||||||
|
QVERIFY(sel.contains(lm->nodeIdx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(TestEditor)
|
||||||
|
#include "test_editor.moc"
|
||||||
248
tests/test_format.cpp
Normal file
248
tests/test_format.cpp
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
#include <QtTest/QTest>
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
using namespace rcx;
|
||||||
|
|
||||||
|
class TestFormat : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testTypeName() {
|
||||||
|
QString s = fmt::typeName(NodeKind::Float);
|
||||||
|
QVERIFY(s.trimmed() == "float");
|
||||||
|
QCOMPARE(s.size(), 10); // COL_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtInt32() {
|
||||||
|
QCOMPARE(fmt::fmtInt32(-42), QString("-42"));
|
||||||
|
QCOMPARE(fmt::fmtInt32(0), QString("0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtFloat() {
|
||||||
|
QString s = fmt::fmtFloat(3.14159f);
|
||||||
|
QVERIFY(s.contains("3.14"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtBool() {
|
||||||
|
QCOMPARE(fmt::fmtBool(1), QString("true"));
|
||||||
|
QCOMPARE(fmt::fmtBool(0), QString("false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtPointer64_null() {
|
||||||
|
QCOMPARE(fmt::fmtPointer64(0), QString("-> NULL"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtPointer64_nonNull() {
|
||||||
|
QString s = fmt::fmtPointer64(0x400000);
|
||||||
|
QVERIFY(s.startsWith("-> 0x"));
|
||||||
|
QVERIFY(s.contains("400000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtOffsetMargin_primary() {
|
||||||
|
QCOMPARE(fmt::fmtOffsetMargin(0x10, false), QString("+0x10"));
|
||||||
|
QCOMPARE(fmt::fmtOffsetMargin(0, false), QString("+0x0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtOffsetMargin_continuation() {
|
||||||
|
QCOMPARE(fmt::fmtOffsetMargin(0x10, true), QString(" \u00B7"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtStructHeader() {
|
||||||
|
Node n;
|
||||||
|
n.kind = NodeKind::Struct;
|
||||||
|
n.name = "Test";
|
||||||
|
QString s = fmt::fmtStructHeader(n, 0);
|
||||||
|
QVERIFY(s.contains("struct"));
|
||||||
|
QVERIFY(s.contains("Test"));
|
||||||
|
QVERIFY(s.contains("{"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtStructFooter() {
|
||||||
|
Node n;
|
||||||
|
n.kind = NodeKind::Struct;
|
||||||
|
n.name = "Test";
|
||||||
|
QString s = fmt::fmtStructFooter(n, 0);
|
||||||
|
QVERIFY(s.contains("};"));
|
||||||
|
QVERIFY(s.contains("Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testIndent() {
|
||||||
|
QCOMPARE(fmt::indent(0), QString(""));
|
||||||
|
QCOMPARE(fmt::indent(1), QString(" "));
|
||||||
|
QCOMPARE(fmt::indent(3), QString(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueInt32() {
|
||||||
|
bool ok;
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Int32, "-42", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 4);
|
||||||
|
int32_t v;
|
||||||
|
memcpy(&v, b.data(), 4);
|
||||||
|
QCOMPARE(v, -42);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueFloat() {
|
||||||
|
bool ok;
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Float, "3.14", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 4);
|
||||||
|
float v;
|
||||||
|
memcpy(&v, b.data(), 4);
|
||||||
|
QVERIFY(qAbs(v - 3.14f) < 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueHex32() {
|
||||||
|
bool ok;
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Hex32, "DEADBEEF", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 4);
|
||||||
|
uint32_t v;
|
||||||
|
memcpy(&v, b.data(), 4);
|
||||||
|
QCOMPARE(v, (uint32_t)0xDEADBEEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueBool() {
|
||||||
|
bool ok;
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Bool, "true", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE(b.size(), 1);
|
||||||
|
QCOMPARE((uint8_t)b[0], (uint8_t)1);
|
||||||
|
|
||||||
|
b = fmt::parseValue(NodeKind::Bool, "false", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE((uint8_t)b[0], (uint8_t)0);
|
||||||
|
|
||||||
|
// Unknown token should fail
|
||||||
|
fmt::parseValue(NodeKind::Bool, "banana", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueHex0xPrefix() {
|
||||||
|
bool ok;
|
||||||
|
// Hex32 with 0x prefix should work
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::Hex32, "0xDEADBEEF", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
uint32_t v;
|
||||||
|
memcpy(&v, b.data(), 4);
|
||||||
|
QCOMPARE(v, (uint32_t)0xDEADBEEF);
|
||||||
|
|
||||||
|
// Pointer64 with 0x prefix
|
||||||
|
b = fmt::parseValue(NodeKind::Pointer64, "0x0000000000400000", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
uint64_t v64;
|
||||||
|
memcpy(&v64, b.data(), 8);
|
||||||
|
QCOMPARE(v64, (uint64_t)0x400000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueOverflow() {
|
||||||
|
bool ok;
|
||||||
|
// UInt8: 300 exceeds uint8_t max (255) → should fail
|
||||||
|
fmt::parseValue(NodeKind::UInt8, "300", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
|
||||||
|
// UInt8: 255 should succeed
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::UInt8, "255", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QCOMPARE((uint8_t)b[0], (uint8_t)255);
|
||||||
|
|
||||||
|
// Int8: 200 exceeds int8_t max (127) → should fail
|
||||||
|
fmt::parseValue(NodeKind::Int8, "200", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
|
||||||
|
// Int8: -129 below min → should fail
|
||||||
|
fmt::parseValue(NodeKind::Int8, "-129", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
|
||||||
|
// Int8: -128 is valid
|
||||||
|
b = fmt::parseValue(NodeKind::Int8, "-128", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
int8_t sv;
|
||||||
|
memcpy(&sv, b.data(), 1);
|
||||||
|
QCOMPARE(sv, (int8_t)-128);
|
||||||
|
|
||||||
|
// UInt16: 70000 exceeds uint16_t max → should fail
|
||||||
|
fmt::parseValue(NodeKind::UInt16, "70000", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
|
||||||
|
// Hex8: 0x1FF exceeds uint8_t → should fail
|
||||||
|
fmt::parseValue(NodeKind::Hex8, "1FF", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
|
||||||
|
// Hex16: 0x1FFFF exceeds uint16_t → should fail
|
||||||
|
fmt::parseValue(NodeKind::Hex16, "1FFFF", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testReadValueBoundsCheck() {
|
||||||
|
// Vec2 subLine=2 (out of bounds) should return "?"
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
FileProvider prov(data);
|
||||||
|
Node n;
|
||||||
|
n.kind = NodeKind::Vec2;
|
||||||
|
n.name = "v";
|
||||||
|
QCOMPARE(fmt::readValue(n, prov, 0, 2), QString("?"));
|
||||||
|
QCOMPARE(fmt::readValue(n, prov, 0, -1), QString("?"));
|
||||||
|
|
||||||
|
// Vec3 subLine=3 (out of bounds)
|
||||||
|
n.kind = NodeKind::Vec3;
|
||||||
|
QCOMPARE(fmt::readValue(n, prov, 0, 3), QString("?"));
|
||||||
|
|
||||||
|
// Vec3 subLine=2 (valid)
|
||||||
|
QVERIFY(fmt::readValue(n, prov, 0, 2) != QString("?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testEditableValueBasic() {
|
||||||
|
QByteArray data(16, '\0');
|
||||||
|
// Write a known float value
|
||||||
|
float val = 3.14f;
|
||||||
|
memcpy(data.data(), &val, 4);
|
||||||
|
FileProvider prov(data);
|
||||||
|
|
||||||
|
Node n;
|
||||||
|
n.kind = NodeKind::Float;
|
||||||
|
n.name = "f";
|
||||||
|
QString s = fmt::editableValue(n, prov, 0, 0);
|
||||||
|
QVERIFY(s.contains("3.14"));
|
||||||
|
|
||||||
|
// Vec2 out of bounds → "?"
|
||||||
|
n.kind = NodeKind::Vec2;
|
||||||
|
QCOMPARE(fmt::editableValue(n, prov, 0, 2), QString("?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseValueEmptyString() {
|
||||||
|
bool ok;
|
||||||
|
// Empty UTF8 should succeed (caller pads)
|
||||||
|
QByteArray b = fmt::parseValue(NodeKind::UTF8, "", &ok);
|
||||||
|
QVERIFY(ok);
|
||||||
|
QVERIFY(b.isEmpty());
|
||||||
|
|
||||||
|
// Empty non-string should fail
|
||||||
|
fmt::parseValue(NodeKind::Int32, "", &ok);
|
||||||
|
QVERIFY(!ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFmtStructFooterWithSize() {
|
||||||
|
Node n;
|
||||||
|
n.kind = NodeKind::Struct;
|
||||||
|
n.name = "Test";
|
||||||
|
|
||||||
|
// With size
|
||||||
|
QString s1 = fmt::fmtStructFooter(n, 0, 0x14);
|
||||||
|
QVERIFY(s1.contains("};"));
|
||||||
|
QVERIFY(s1.contains("Test"));
|
||||||
|
QVERIFY(s1.contains("sizeof=0x14"));
|
||||||
|
|
||||||
|
// Size 0 → no sizeof
|
||||||
|
QString s2 = fmt::fmtStructFooter(n, 0, 0);
|
||||||
|
QVERIFY(s2.contains("};"));
|
||||||
|
QVERIFY(!s2.contains("sizeof"));
|
||||||
|
|
||||||
|
// Default (no size arg) → no sizeof
|
||||||
|
QString s3 = fmt::fmtStructFooter(n, 0);
|
||||||
|
QVERIFY(s3.contains("};"));
|
||||||
|
QVERIFY(!s3.contains("sizeof"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(TestFormat)
|
||||||
|
#include "test_format.moc"
|
||||||
BIN
third_party/QScintilla_src.tar.gz
vendored
Normal file
BIN
third_party/QScintilla_src.tar.gz
vendored
Normal file
Binary file not shown.
6853
third_party/qscintilla/ChangeLog
vendored
Normal file
6853
third_party/qscintilla/ChangeLog
vendored
Normal file
File diff suppressed because it is too large
Load Diff
674
third_party/qscintilla/LICENSE
vendored
Normal file
674
third_party/qscintilla/LICENSE
vendored
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
604
third_party/qscintilla/NEWS
vendored
Normal file
604
third_party/qscintilla/NEWS
vendored
Normal file
@@ -0,0 +1,604 @@
|
|||||||
|
v2.14.1 7th June 2023
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.14.0 24th April 2023
|
||||||
|
- Added the QsciLexerAsm, QsciLexerMASM and QsciLexerNASM classes.
|
||||||
|
- Added the QsciLexerHex, QsciLexerIntelHex, QsciLexerSRec and
|
||||||
|
QsciLexerTekHex classes.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.13.4 6th December 2022
|
||||||
|
- Added the .api files for Python v3.10 and v3.11.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.13.3 25th April 2022
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.13.2 15th March 2022
|
||||||
|
- Bug fixes that only affect iOS.
|
||||||
|
|
||||||
|
v2.13.1 12th October 2021
|
||||||
|
- Documented how to build for multiple architectures on macOS.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.13.0 13th June 2021
|
||||||
|
- Added the QsciPrinter::printRange() overload that uses a supplied QPainter
|
||||||
|
to render the pages.
|
||||||
|
- Improved the appearence of the auto-completion popup.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.12.1 4th March 2021
|
||||||
|
- Packaging bug fixes.
|
||||||
|
|
||||||
|
v2.12.0 23rd February 2021
|
||||||
|
- Added support for Qt6.
|
||||||
|
- Removed support for Qt4 and Qt5 earlier than v5.11.0.
|
||||||
|
- sdists are now provided.
|
||||||
|
|
||||||
|
v2.11.6 23rd November 2020
|
||||||
|
- Added the --qsci-translations-dir option to sip-wheel.
|
||||||
|
- Added the .api file for Python v3.9.
|
||||||
|
- Build system changes.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.11.5 10th June 2020
|
||||||
|
- The bundled .api files are now included in Python wheels if the
|
||||||
|
QScintilla.api file is enabled.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.11.4 19th December 2019
|
||||||
|
- An administrative release with no code changes.
|
||||||
|
|
||||||
|
v2.11.3 3rd November 2019
|
||||||
|
- Added support for SIP v5.
|
||||||
|
- On macOS the install name of the C++ library is now relative to @rpath.
|
||||||
|
|
||||||
|
v2.11.2 26th June 2019
|
||||||
|
- Added QsciScintilla::findMatchingBrace().
|
||||||
|
- QsciScintiila::clear() is no longer undoable and instead clears the undo
|
||||||
|
history.
|
||||||
|
- Added support for building with WASM.
|
||||||
|
- Added the .api file for Python v3.8.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.11.1 14th February 2019
|
||||||
|
- There is a small (but potentially incompatible) change to the signature of
|
||||||
|
a QsciScintillaBase::SendScintilla() overload which may require an explicit
|
||||||
|
cast to be added.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.11 10th February 2019
|
||||||
|
- Based on Scintilla v3.10.1.
|
||||||
|
- Added setCaretLineFrameWidth() to QsciScintilla.
|
||||||
|
- The findFirst() and findFirstInSelection() methods of QsciScintilla now
|
||||||
|
support Cxx11 regular expressions.
|
||||||
|
- Added cancelFind() to QsciScintilla.
|
||||||
|
- Added GradientIndicator and CentreGradientIndicator to
|
||||||
|
QsciScintilla::IndicatorStyle.
|
||||||
|
- Added WrapIndentDeeplyIndented to QsciScintilla::WrapIndentMode.
|
||||||
|
- Added ReverseLines to QsciCommand::Command.
|
||||||
|
- Deprecated QsciLexer::styleBitsNeeded().
|
||||||
|
- Added the AddingPatchAdded, RemovingPatchAdded, AddingPatchRemoved and
|
||||||
|
RemovingPatchRemoved styles to QsciLexerDiff.
|
||||||
|
- Added the DoubleQuotedFString, SingleQuotedFString,
|
||||||
|
TripleSingleQuotedFString and TripleDoubleQuotedFString styles to
|
||||||
|
QsciLexerPython.
|
||||||
|
- Added SCLEX_INDENT, SCLEX_MAXIMA and SCLEX_STATA to QsciScintillaBase.
|
||||||
|
- Added SCI_SETACCESSIBILITY, SCI_GETACCESSIBILITY, SCI_GETCARETLINEFRAME,
|
||||||
|
SCI_SETCARETLINEFRAME, SCI_SETCOMMANDEVENTS, SCI_GETCOMMANDEVENTS,
|
||||||
|
SCI_LINEREVERSE and SCI_GETMOVEEXTENDSSELECTION to QsciScintillaBase.
|
||||||
|
- Added SCI_GETLINECHARACTERINDEX, SCI_ALLOCATELINECHARACTERINDEX,
|
||||||
|
SCI_RELEASELINECHARACTERINDEX, SCI_LINEFROMINDEXPOSITION,
|
||||||
|
SCI_INDEXPOSITIONFROMLINE, SCI_COUNTCODEUNITS and
|
||||||
|
SCI_POSITIONRELATIVECODEUNITS to QsciScintillaBase.
|
||||||
|
- Added SC_LINECHARACTERINDEX_NONE, SC_LINECHARACTERINDEX_UTF32 and
|
||||||
|
SC_LINECHARACTERINDEX_UTF16 to QsciScintillaBase.
|
||||||
|
- Added SCI_GETNAMEDSTYLES, SCI_NAMEOFSTYLE, SCI_TAGSOFSTYLE and
|
||||||
|
SCI_DESCRIPTIONOFSTYLE to QsciScintillaBase.
|
||||||
|
- Added the SCN_AUTOCSELECTIONCHANGE and SCN_URIDROPPED() signals to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added the overloaded SCN_USERLISTSELECTION() signal to QsciScintillaBase.
|
||||||
|
- Added INDIC_GRADIENT and INDIC_GRADIENTCENTRE to QsciScintillaBase.
|
||||||
|
- Added SC_PRINT_SCREENCOLOURS to QsciScintillaBase.
|
||||||
|
- Added SC_WRAPINDENT_DEEPINDENT to QsciScintillaBase.
|
||||||
|
- Added SCI_GETDOCUMENTOPTIONS, SC_DOCUMENTOPTION_DEFAULT,
|
||||||
|
SC_DOCUMENTOPTION_STYLES_NONE and SC_DOCUMENTOPTION_TEXT_LARGE to
|
||||||
|
QsciScintillaBase.
|
||||||
|
|
||||||
|
v2.10.8 1st October 2018
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.10.7 2nd July 2018
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.10.6 24th June 2018
|
||||||
|
- A pseudo-release to create a version number for updated Python wheels.
|
||||||
|
|
||||||
|
v2.10.5 23rd June 2018
|
||||||
|
- Added the QsciLexerEDIFACT class.
|
||||||
|
- Added setStyle() to QsciStyle.
|
||||||
|
- Control-wheel scroll will now zoom in and out of the document.
|
||||||
|
- Buffered drawing is now disabled by default.
|
||||||
|
- The Python bindings create a PEP 376 .dist-info directory on installation
|
||||||
|
that provides version information for dependent packages and allows pip to
|
||||||
|
uninstall.
|
||||||
|
- Added the --no-dist-info option to the Python bindings' configure.py.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.10.4 10th April 2018
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.10.3 26th February 2018
|
||||||
|
- Added accessibility support.
|
||||||
|
- Added the API file for Python v3.7.
|
||||||
|
|
||||||
|
v2.10.2 23rd November 2017
|
||||||
|
- Added setScrollWidth() , scrollWidth, setScrollWidthTracking() and
|
||||||
|
scrollWidthTracking() to QsciScintilla.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.10.1 3rd July 2017
|
||||||
|
- Changed the default font on macOS to Menlo 12pt.
|
||||||
|
- Added previously internal lexer methods to the Python bindings.
|
||||||
|
|
||||||
|
v2.10 20th February 2017
|
||||||
|
- Based on Scintilla v3.7.2.
|
||||||
|
- Added the QsciLexerJSON class.
|
||||||
|
- Added the QsciLexerMarkdown class.
|
||||||
|
- Added replaceHorizontalScrollBar() and replaceVerticalScrollBar() to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added bytes() and a corresponding text() overload to QsciScintilla.
|
||||||
|
- Added EdgeMultipleLines to QsciScintilla::EdgeMode.
|
||||||
|
- Added addEdgeColumn() and clearEdgeColumns() to QsciScintilla.
|
||||||
|
- Added the marginRightClicked() signal to QsciScintilla.
|
||||||
|
- Added SymbolMarginColor to QsciScintilla::MarginType.
|
||||||
|
- Added setMarginBackgroundColor() and marginBackgroundColor() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added setMargins() and margins() to QsciScintilla.
|
||||||
|
- Added TriangleIndicator and TriangleCharacterIndicator to
|
||||||
|
QsciScintilla::IndicatorStyle.
|
||||||
|
- Added WsVisibleOnlyInIndent to QsciScintilla::WhitespaceVisibility.
|
||||||
|
- Added TabDrawMode, setTabDrawMode() and tabDrawMode() to QsciScintilla.
|
||||||
|
- Added InstanceProperty to QsciLexerCoffeeScript.
|
||||||
|
- Added EDGE_MULTILINE to QsciScintillaBase.
|
||||||
|
- Added INDIC_POINT and INDIC_POINTCHARACTER to QsciScintillaBase.
|
||||||
|
- Added SC_AC_FILLUP, SC_AC_DOUBLECLICK, SC_AC_TAB, SC_AC_NEWLINE and
|
||||||
|
SC_AC_COMMAND to QsciScintillaBase.
|
||||||
|
- Added SC_CASE_CAMEL to QsciScintillaBase.
|
||||||
|
- Added SC_CHARSET_CYRILLIC and SC_CHARSET_OEM866 to QsciScintillaBase.
|
||||||
|
- Added SC_FOLDDISPLAYTEXT_HIDDEN, SC_FOLDDISPLAYTEXT_STANDARD and
|
||||||
|
SC_FOLDDISPLAYTEXT_BOXED to QsciScintillaBase.
|
||||||
|
- Added SC_IDLESTYLING_NONE, SC_IDLESTYLING_TOVISIBLE,
|
||||||
|
SC_IDLESTYLING_AFTERVISIBLE and SC_IDLESTYLING_ALL to QsciScintillaBase.
|
||||||
|
- Added SC_MARGIN_COLOUR to QsciScintillaBase.
|
||||||
|
- Added SC_POPUP_NEVER, SC_POPUP_ALL and SC_POPUP_TEXT to QsciScintillaBase.
|
||||||
|
- Added SCI_FOLDDISPLAYTEXTSETSTYLE and SCI_TOGGLEFOLDSHOWTEXT to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_GETIDLESTYLING and SCI_SETIDLESTYLING to QsciScintillaBase.
|
||||||
|
- Added SCI_GETMARGINBACKN and SCI_SETMARGINBACKN to QsciScintillaBase.
|
||||||
|
- Added SCI_GETMARGINS and SCI_SETMARGINS to QsciScintillaBase.
|
||||||
|
- Added SCI_GETMOUSEWHEELCAPTURES and SCI_SETMOUSEWHEELCAPTURES to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_GETTABDRAWMODE and SCI_SETTABDRAWMODE to QsciScintillaBase.
|
||||||
|
- Added SCI_ISRANGEWORD to QsciScintillaBase.
|
||||||
|
- Added SCI_MULTIEDGEADDLINE and SCI_MULTIEDGECLEARALL to QsciScintillaBase.
|
||||||
|
- Added SCI_MULTIPLESELECTADDNEXT and SCI_MULTIPLESELECTADDEACH to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_TARGETWHOLEDOCUMENT to QsciScintillaBase.
|
||||||
|
- Added SCLEX_JSON and SCLEX_EDIFACT to QsciScintillaBase.
|
||||||
|
- Added SCTD_LONGARROW and SCTD_STRIKEOUT to QsciScintillaBase.
|
||||||
|
- Added SCVS_NOWRAPLINESTART to QsciScintillaBase.
|
||||||
|
- Added SCWS_VISIBLEONLYININDENT to QsciScintillaBase.
|
||||||
|
- Added STYLE_FOLDDISPLAYTEXT to QsciScintillaBase.
|
||||||
|
- Added the SCN_AUTOCCOMPLETED() signal to QsciScintillaBase.
|
||||||
|
- Added the overloaded SCN_AUTOCSELECTION() and SCN_USERLISTSELECTION()
|
||||||
|
signals to QsciScintillaBase.
|
||||||
|
- Added the SCN_MARGINRIGHTCLICK() signal to QsciScintillaBase.
|
||||||
|
- Renamed SCI_GETTARGETRANGE to SCI_GETTARGETTEXT in QsciScintillaBase.
|
||||||
|
- Removed SCI_GETKEYSUNICODE and SCI_SETKEYSUNICODE to QsciScintillaBase.
|
||||||
|
- The autoCompletionFillups(), autoCompletionWordSeparators(), blockEnd(),
|
||||||
|
blockLookback(), blockStart(), blockStartKeyword(), braceStyle(),
|
||||||
|
caseSensitive(), indentationGuideView() and defaultStyle() methods of
|
||||||
|
QsciLexer are no longer marked as internal and are exposed to Python so
|
||||||
|
that they may be used by QsciLexerCustom sub-classes.
|
||||||
|
- The name of the library has been changed to include the major version
|
||||||
|
number of the version of Qt it is built against (ie. 4 or 5).
|
||||||
|
|
||||||
|
v2.9.4 25th December 2016
|
||||||
|
- Added the .api file for Python v3.6.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.9.3 25th July 2016
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.9.2 18th April 2016
|
||||||
|
- Added support for a PEP 484 stub file for the Python extension module.
|
||||||
|
|
||||||
|
v2.9.1 24th October 2015
|
||||||
|
- Added the .api file for Python v3.5.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.9 20th April 2015
|
||||||
|
- Based on Scintilla v3.5.4.
|
||||||
|
- Added UserLiteral, InactiveUserLiteral, TaskMarker, InactiveTaskMarker,
|
||||||
|
EscapeSequence, InactiveEscapeSequence, setHighlightBackQuotedStrings(),
|
||||||
|
highlightBackQuotedStrings(), setHighlightEscapeSequences(),
|
||||||
|
highlightEscapeSequences(), setVerbatimStringEscapeSequencesAllowed() and
|
||||||
|
verbatimStringEscapeSequencesAllowed() to QsciLexerCPP.
|
||||||
|
- Added CommentKeyword, DeclareInputPort, DeclareOutputPort,
|
||||||
|
DeclareInputOutputPort, PortConnection and the inactive versions of all
|
||||||
|
styles to QsciLexerVerilog.
|
||||||
|
- Added CommentBlock to QsciLexerVHDL.
|
||||||
|
- Added AnnotationIndented to QsciScintilla::AnnotationDisplay.
|
||||||
|
- Added FullBoxIndicator, ThickCompositionIndicator, ThinCompositionIndicator
|
||||||
|
and TextColorIndicator to QsciScintilla::IndicatorStyle.
|
||||||
|
- Added setIndicatorHoverForegroundColor() and setIndicatorHoverStyle() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added Bookmark to QsciScintilla::MarkerSymbol.
|
||||||
|
- Added WrapWhitespace to QsciScintilla::WrapMode.
|
||||||
|
- Added SCLEX_AS, SCLEX_BIBTEX, SCLEX_DMAP, SCLEX_DMIS, SCLEX_IHEX,
|
||||||
|
SCLEX_REGISTRY, SCLEX_SREC and SCLEX_TEHEX to QsciScintillaBase.
|
||||||
|
- Added SCI_CHANGEINSERTION to QsciScintillaBase.
|
||||||
|
- Added SCI_CLEARTABSTOPS, SCI_ADDTABSTOP and SCI_GETNEXTTABSTOP to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_GETIMEINTERACTION, SCI_SETIMEINTERACTION, SC_IME_WINDOWED and
|
||||||
|
SC_IME_INLINE to QsciScintillaBase.
|
||||||
|
- Added SC_MARK_BOOKMARK to QsciScintillaBase.
|
||||||
|
- Added INDIC_COMPOSITIONTHIN, INDIC_FULLBOX, INDIC_TEXTFORE, INDIC_IME,
|
||||||
|
INDIC_IME_MAX, SC_INDICVALUEBIT, SC_INDICVALUEMASK,
|
||||||
|
SC_INDICFLAG_VALUEBEFORE, SCI_INDICSETHOVERSTYLE, SCI_INDICGETHOVERSTYLE,
|
||||||
|
SCI_INDICSETHOVERFORE, SCI_INDICGETHOVERFORE, SCI_INDICSETFLAGS and
|
||||||
|
SCI_INDICGETFLAGS to QsciScintillaBase.
|
||||||
|
- Added SCI_SETTARGETRANGE and SCI_GETTARGETRANGE to QsciScintillaBase.
|
||||||
|
- Added SCFIND_CXX11REGEX to QsciScintillaBase.
|
||||||
|
- Added SCI_CALLTIPSETPOSSTART to QsciScintillaBase.
|
||||||
|
- Added SC_FOLDFLAG_LINESTATE to QsciScintillaBase.
|
||||||
|
- Added SC_WRAP_WHITESPACE to QsciScintillaBase.
|
||||||
|
- Added SC_PHASES_ONE, SC_PHASES_TWO, SC_PHASES_MULTIPLE, SCI_GETPHASESDRAW
|
||||||
|
and SCI_SETPHASESDRAW to QsciScintillaBase.
|
||||||
|
- Added SC_STATUS_OK, SC_STATUS_FAILURE, SC_STATUS_BADALLOC,
|
||||||
|
SC_STATUS_WARN_START and SC_STATUS_WARNREGEX to QsciScintillaBase.
|
||||||
|
- Added SC_MULTIAUTOC_ONCE, SC_MULTIAUTOC_EACH, SCI_AUTOCSETMULTI and
|
||||||
|
SCI_AUTOCGETMULTI to QsciScintillaBase.
|
||||||
|
- Added ANNOTATION_INDENTED to QsciScintillaBase.
|
||||||
|
- Added SCI_DROPSELECTIONN to QsciScintillaBase.
|
||||||
|
- Added SC_TECHNOLOGY_DIRECTWRITERETAIN and SC_TECHNOLOGY_DIRECTWRITEDC to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SC_LINE_END_TYPE_DEFAULT, SC_LINE_END_TYPE_UNICODE,
|
||||||
|
SCI_GETLINEENDTYPESSUPPORTED, SCI_SETLINEENDTYPESALLOWED,
|
||||||
|
SCI_GETLINEENDTYPESALLOWED and SCI_GETLINEENDTYPESACTIVE to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_ALLOCATESUBSTYLES, SCI_GETSUBSTYLESSTART, SCI_GETSUBSTYLESLENGTH,
|
||||||
|
SCI_GETSTYLEFROMSUBSTYLE, SCI_GETPRIMARYSTYLEFROMSTYLE, SCI_FREESUBSTYLES,
|
||||||
|
SCI_SETIDENTIFIERS, SCI_DISTANCETOSECONDARYSTYLES and SCI_GETSUBSTYLEBASES
|
||||||
|
to QsciScintillaBase.
|
||||||
|
- Added SC_MOD_INSERTCHECK and SC_MOD_CHANGETABSTOPS to QsciScintillaBase.
|
||||||
|
- Qt v3 and PyQt v3 are no longer supported.
|
||||||
|
|
||||||
|
v2.8.4 11th September 2014
|
||||||
|
- Added setHotspotForegroundColor(), resetHotspotForegroundColor(),
|
||||||
|
setHotspotBackgroundColor(), resetHotspotBackgroundColor(),
|
||||||
|
setHotspotUnderline() and setHotspotWrap() to QsciScintilla.
|
||||||
|
- Added SCI_SETHOTSPOTSINGLELINE to QsciScintillaBase.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.8.3 3rd July 2014
|
||||||
|
- Added the QsciLexerCoffeeScript class.
|
||||||
|
- Font sizes are now handled as floating point values rather than integers.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.8.2 26th May 2014
|
||||||
|
- Added the QsciLexerAVS class.
|
||||||
|
- Added the QsciLexerPO class.
|
||||||
|
- Added the --sysroot, --no-sip-files and --no-qsci-api options to the Python
|
||||||
|
bindings' configure.py.
|
||||||
|
- Cross-compilation (specifically to iOS and Android) is now supported.
|
||||||
|
- configure.py has been refactored and relicensed so that it can be used as a
|
||||||
|
template for wrapping other bindings.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.8.1 14th March 2014
|
||||||
|
- Added support for iOS and Android.
|
||||||
|
- Added support for retina displays.
|
||||||
|
- A qscintilla2.prf file is installed so that application .pro files only
|
||||||
|
need to add CONFIG += qscintilla2.
|
||||||
|
- Updated the keywords recognised by the Octave lexer.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.8 9th November 2013
|
||||||
|
- Based on Scintilla v3.3.6.
|
||||||
|
- Added the SCN_FOCUSIN() and SCN_FOCUSOUT() signals to QsciScintillaBase.
|
||||||
|
- Added PreProcessorCommentLineDoc and InactivePreProcessorCommentLineDoc to
|
||||||
|
QsciLexerCPP.
|
||||||
|
- Added SCLEX_LITERATEHASKELL, SCLEX_KVIRC, SCLEX_RUST and SCLEX_STTXT to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added ThickCompositionIndicator to QsciScintilla::IndicatorStyle.
|
||||||
|
- Added INDIC_COMPOSITIONTHICK to QsciScintillaBase.
|
||||||
|
- Added SC_FOLDACTION_CONTRACT, SC_FOLDACTION_EXPAND and SC_FOLDACTION_TOGGLE
|
||||||
|
to QsciScintillaBase.
|
||||||
|
- Added SCI_FOLDLINE, SCI_FOLDCHILDREN, SCI_EXPANDCHILDREN and SCI_FOLDALL to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SC_AUTOMATICFOLD_SHOW, SC_AUTOMATICFOLD_CLICK and
|
||||||
|
SC_AUTOMATICFOLD_CHANGE to QsciScintillaBase.
|
||||||
|
- Added SCI_SETAUTOMATICFOLD and SCI_GETAUTOMATICFOLD to QsciScintillaBase.
|
||||||
|
- Added SC_ORDER_PRESORTED, SC_ORDER_PERFORMSORT and SC_ORDER_CUSTOM to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_AUTOCSETORDER and SCI_AUTOCGETORDER to QsciScintillaBase.
|
||||||
|
- Added SCI_POSITIONRELATIVE to QsciScintillaBase.
|
||||||
|
- Added SCI_RELEASEALLEXTENDEDSTYLES and SCI_ALLOCATEEXTENDEDSTYLES to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_SCROLLRANGE to QsciScintillaBase.
|
||||||
|
- Added SCI_SETCARETLINEVISIBLEALWAYS and SCI_GETCARETLINEVISIBLEALWAYS to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SCI_SETMOUSESELECTIONRECTANGULARSWITCH and
|
||||||
|
SCI_GETMOUSESELECTIONRECTANGULARSWITCH to QsciScintillaBase.
|
||||||
|
- Added SCI_SETREPRESENTATION, SCI_GETREPRESENTATION and
|
||||||
|
SCI_CLEARREPRESENTATION to QsciScintillaBase.
|
||||||
|
- Input methods are now properly supported.
|
||||||
|
|
||||||
|
v2.7.2 16th June 2013
|
||||||
|
- The build script for the Python bindings now has a --pyqt argument for
|
||||||
|
specifying PyQt4 or PyQt5.
|
||||||
|
- The default EOL mode on OS/X is now EolUnix.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.7.1 1st March 2013
|
||||||
|
- Added support for the final release of Qt v5.
|
||||||
|
- The build script for the Python bindings should now work with SIP v5.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.7 8th December 2012
|
||||||
|
- Based on Scintilla v3.2.3.
|
||||||
|
- Added support for Qt v5-rc1.
|
||||||
|
- Added HashQuotedString, InactiveHashQuotedString, PreProcessorComment,
|
||||||
|
InactivePreProcessorComment, setHighlightHashQuotedStrings() and
|
||||||
|
highlightHashQuotedStrings() to QsciLexerCpp.
|
||||||
|
- Added Variable, setHSSLanguage(), HSSLanguage(), setLessLanguage(),
|
||||||
|
LessLanguage(), setSCCSLanguage() and SCCSLanguage() to QsciLexerCSS.
|
||||||
|
- Added setOverwriteMode() and overwriteMode() to QsciScintilla.
|
||||||
|
- Added wordAtLineIndex() to QsciScintilla.
|
||||||
|
- Added findFirstInSelection() to QsciScintilla.
|
||||||
|
- Added CallTipsPosition, callTipsPosition() and setCallTipsPosition() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added WrapFlagInMargin to QsciScintilla::WrapVisualFlag.
|
||||||
|
- Added SquigglePixmapIndicator to QsciScintilla::IndicatorStyle.
|
||||||
|
- The weight of a font (rather than whether it is just bold or not) is now
|
||||||
|
respected.
|
||||||
|
- Added SCLEX_AVS, SCLEX_COFFEESCRIPT, SCLEX_ECL, SCLEX_OSCRIPT,
|
||||||
|
SCLEX_TCMD and SCLEX_VISUALPROLOG to QsciScintillaBase.
|
||||||
|
- Added SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE and
|
||||||
|
SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE to QsciScintillaBase.
|
||||||
|
- Added SC_FONT_SIZE_MULTIPLIER to QsciScintillaBase.
|
||||||
|
- Added SC_WEIGHT_NORMAL, SC_WEIGHT_SEMIBOLD and SC_WEIGHT_BOLD to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SC_WRAPVISUALFLAG_MARGIN to QsciScintillaBase.
|
||||||
|
- Added INDIC_SQUIGGLEPIXMAP to QsciScintillaBase.
|
||||||
|
- Added SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR,
|
||||||
|
SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR, SCI_CALLTIPSETPOSITION,
|
||||||
|
SCI_COUNTCHARACTERS, SCI_CREATELOADER, SCI_DELETERANGE,
|
||||||
|
SCI_FINDINDICATORFLASH, SCI_FINDINDICATORHIDE, SCI_FINDINDICATORSHOW,
|
||||||
|
SCI_GETALLLINESVISIBLE, SCI_GETGAPPOSITION, SCI_GETPUNCTUATIONCHARS,
|
||||||
|
SCI_GETRANGEPOINTER, SCI_GETSELECTIONEMPTY, SCI_GETTECHNOLOGY,
|
||||||
|
SCI_GETWHITESPACECHARS, SCI_GETWORDCHARS, SCI_RGBAIMAGESETSCALE,
|
||||||
|
SCI_SETPUNCTUATIONCHARS, SCI_SETTECHNOLOGY, SCI_STYLESETSIZEFRACTIONAL,
|
||||||
|
SCI_STYLEGETSIZEFRACTIONAL, SCI_STYLESETWEIGHT and SCI_STYLEGETWEIGHT to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Removed SCI_GETUSEPALETTE and SCI_SETUSEPALETTE from QsciScintillaBase.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.6.2 20th June 2012
|
||||||
|
- Added support for Qt v5-alpha.
|
||||||
|
- QsciLexer::wordCharacters() is now part of the public API.
|
||||||
|
- Bug fixes.
|
||||||
|
|
||||||
|
v2.6.1 10th February 2012
|
||||||
|
- Support SCI_NAMESPACE to enable all internal Scintilla classes to be put
|
||||||
|
into the Scintilla namespace.
|
||||||
|
- APIs now allow for spaces between the end of a word and the opening
|
||||||
|
parenthesis.
|
||||||
|
- Building against Qt v3 is fixed.
|
||||||
|
|
||||||
|
v2.6 11th November 2011
|
||||||
|
- Based on Scintilla v2.29.
|
||||||
|
- Added Command, command() and execute() to QsciCommand.
|
||||||
|
- Added boundTo() and find() to QsciCommandSet.
|
||||||
|
- Added createStandardContextMenu() to QsciScintilla.
|
||||||
|
- Added StraightBoxIndicator, DashesIndicator, DotsIndicator,
|
||||||
|
SquiggleLowIndicator and DotBoxIndicator to QsciScintilla::IndicatorStyle.
|
||||||
|
- Added markerDefine() to QsciScintilla.
|
||||||
|
- Added MoNone, MoSublineSelect, marginOptions() and setMarginOptions() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added registerImage() to QsciScintilla.
|
||||||
|
- Added setIndicatorOutlineColor() to QsciScintilla.
|
||||||
|
- Added setMatchedBraceIndicator(), resetMatchedBraceIndicator(),
|
||||||
|
setUnmatchedBraceIndicator() and resetUnmatchedBraceIndicator() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added highlightTripleQuotedStrings() and setHighlightTripleQuotedStrings()
|
||||||
|
to QsciLexerCpp.
|
||||||
|
- Added Label to QsciLexerLua.
|
||||||
|
- Added DoubleQuotedStringVar, Translation, RegexVar, SubstitutionVar,
|
||||||
|
BackticksVar, DoubleQuotedHereDocumentVar, BacktickHereDocumentVar,
|
||||||
|
QuotedStringQQVar, QuotedStringQXVar, QuotedStringQRVar, setFoldAtElse()
|
||||||
|
and foldAtElse() to QsciLexerPerl.
|
||||||
|
- Added highlightSubidentifiers() and setHighlightSubidentifiers() to
|
||||||
|
QsciLexerPython.
|
||||||
|
- Added INDIC_STRAIGHTBOX, INDIC_DASH, INDIC_DOTS, INDIC_SQUIGGLELOW and
|
||||||
|
INDIC_DOTBOX to QsciScintillaBase.
|
||||||
|
- Added SC_MARGINOPTION_NONE and SC_MARGINOPTION_SUBLINESELECT to
|
||||||
|
QsciScintillaBase.
|
||||||
|
- Added SC_MARK_RGBAIMAGE to QsciScintillaBase.
|
||||||
|
- Added SCI_BRACEBADLIGHTINDICATOR, SCI_BRACEHIGHLIGHTINDICATOR,
|
||||||
|
SCI_GETIDENTIFIER, SCI_GETMARGINOPTIONS, SCI_INDICGETOUTLINEALPHA,
|
||||||
|
SCI_INDICSETOUTLINEALPHA, SCI_MARKERDEFINERGBAIMAGE,
|
||||||
|
SCI_MARKERENABLEHIGHLIGHT, SCI_MARKERSETBACKSELECTED,
|
||||||
|
SCI_MOVESELECTEDLINESDOWN, SCI_MOVESELECTEDLINESUP, SCI_REGISTERRGBAIMAGE,
|
||||||
|
SCI_RGBAIMAGESETHEIGHT, SCI_RGBAIMAGESETWIDTH, SCI_SCROLLTOEND,
|
||||||
|
SCI_SCROLLTOSTART, SCI_SETEMPTYSELECTION, SCI_SETIDENTIFIER and
|
||||||
|
SCI_SETMARGINOPTIONS to QsciScintillaBase.
|
||||||
|
|
||||||
|
v2.5.1 17th April 2011
|
||||||
|
- Added QsciLexerMatlab and QsciLexerOctave.
|
||||||
|
|
||||||
|
v2.5 29th March 2011
|
||||||
|
- Based on Scintilla v2.25.
|
||||||
|
- Rectangular selections are now fully supported and compatible with SciTE.
|
||||||
|
- The signature of the fromMimeData() and toMimeData() methods of
|
||||||
|
QsciScintillaBase have changed incompatibly in order to support rectangular
|
||||||
|
selections.
|
||||||
|
- Added QsciScintilla::setAutoCompletionUseSingle() to replace the now
|
||||||
|
deprecated setAutoCompletionShowSingle().
|
||||||
|
- Added QsciScintilla::autoCompletionUseSingle() to replace the now
|
||||||
|
deprecated autoCompletionShowSingle().
|
||||||
|
- QsciScintilla::setAutoCompletionCaseSensitivity() is no longer ignored if a
|
||||||
|
lexer has been set.
|
||||||
|
- Added FullRectangle, LeftRectangle and Underline to the
|
||||||
|
QsciScintilla::MarkerSymbol enum.
|
||||||
|
- Added setExtraAscent(), extraAscent(), setExtraDescent() and extraDescent()
|
||||||
|
to QsciScintilla.
|
||||||
|
- Added setWhitespaceSize() and whitespaceSize() to QsciScintilla.
|
||||||
|
- Added replaceSelectedText() to QsciScintilla.
|
||||||
|
- Added setWhitespaceBackgroundColor() and setWhitespaceForegroundColor() to
|
||||||
|
QsciScintilla.
|
||||||
|
- Added setWrapIndentMode() and wrapIndentMode() to QsciScintilla.
|
||||||
|
- Added setFirstVisibleLine() to QsciScintilla.
|
||||||
|
- Added setContractedFolds() and contractedFolds() to QsciScintilla.
|
||||||
|
- Added the SCN_HOTSPOTRELEASECLICK() signal to QsciScintillaBase.
|
||||||
|
- The signature of the QsciScintillaBase::SCN_UPDATEUI() signal has changed.
|
||||||
|
- Added the RawString and inactive styles to QsciLexerCPP.
|
||||||
|
- Added MediaRule to QsciLexerCSS.
|
||||||
|
- Added BackquoteString, RawString, KeywordSet5, KeywordSet6 and KeywordSet7
|
||||||
|
to QsciLexerD.
|
||||||
|
- Added setDjangoTemplates(), djangoTemplates(), setMakoTemplates() and
|
||||||
|
makoTemplates() to QsciLexerHTML.
|
||||||
|
- Added KeywordSet5, KeywordSet6, KeywordSet7 and KeywordSet8 to
|
||||||
|
QsciLexerLua.
|
||||||
|
- Added setInitialSpaces() and initialSpaces() to QsciLexerProperties.
|
||||||
|
- Added setFoldCompact(), foldCompact(), setStringsOverNewlineAllowed() and
|
||||||
|
stringsOverNewlineAllowed() to QsciLexerPython.
|
||||||
|
- Added setFoldComments(), foldComments(), setFoldCompact() and foldCompact()
|
||||||
|
to QsciLexerRuby.
|
||||||
|
- Added setFoldComments() and foldComments(), and removed setFoldCompact()
|
||||||
|
and foldCompact() from QsciLexerTCL.
|
||||||
|
- Added setFoldComments(), foldComments(), setFoldCompact(), foldCompact(),
|
||||||
|
setProcessComments(), processComments(), setProcessIf(), and processIf() to
|
||||||
|
QsciLexerTeX.
|
||||||
|
- Added QuotedIdentifier, setDottedWords(), dottedWords(), setFoldAtElse(),
|
||||||
|
foldAtElse(), setFoldOnlyBegin(), foldOnlyBegin(), setHashComments(),
|
||||||
|
hashComments(), setQuotedIdentifiers() and quotedIdentifiers() to
|
||||||
|
QsciLexerSQL.
|
||||||
|
- The Python bindings now allow optional arguments to be specified as keyword
|
||||||
|
arguments.
|
||||||
|
- The Python bindings will now build using the protected-is-public hack if
|
||||||
|
possible.
|
||||||
|
|
||||||
|
v2.4.6 23rd December 2010
|
||||||
|
- Added support for indicators to the high-level API, i.e. added the
|
||||||
|
IndicatorStyle enum, the clearIndicatorRange(), fillIndicatorRange(),
|
||||||
|
indicatorDefine(), indicatorDrawUnder(), setIndicatorDrawUnder() and
|
||||||
|
setIndicatorForegroundColor methods, and the indicatorClicked() and
|
||||||
|
indicatorReleased() signals to QsciScintilla.
|
||||||
|
- Added support for the Key style in QsciLexerProperties.
|
||||||
|
- Added an API file for Python v2.7.
|
||||||
|
- Added the --no-timestamp command line option to the Python bindings'
|
||||||
|
configure.py.
|
||||||
|
|
||||||
|
v2.4.5 31st August 2010
|
||||||
|
- A bug fix release.
|
||||||
|
|
||||||
|
v2.4.4 12th July 2010
|
||||||
|
- Added the canInsertFromMimeData(), fromMimeData() and toMimeData() methods
|
||||||
|
to QsciScintillaBase.
|
||||||
|
- QsciScintilla::markerDefine() now allows existing markers to be redefined.
|
||||||
|
|
||||||
|
v2.4.3 17th March 2010
|
||||||
|
- Added clearFolds() to QsciScintilla.
|
||||||
|
|
||||||
|
v2.4.2 20th January 2010
|
||||||
|
- Updated Spanish translations from Jaime Seuma.
|
||||||
|
- Fixed compilation problems with Qt v3 and Qt v4 prior to v4.5.
|
||||||
|
|
||||||
|
v2.4.1 14th January 2010
|
||||||
|
- Added the QsciLexerSpice and QsciLexerVerilog classes.
|
||||||
|
- Significant performance improvements when handling long lines.
|
||||||
|
- The Python bindings include automatically generated docstrings by default.
|
||||||
|
- Added an API file for Python v3.
|
||||||
|
|
||||||
|
v2.4 5th June 2009
|
||||||
|
- Based on Scintilla v1.78.
|
||||||
|
- Added the QsciLexerCustom, QsciStyle and QsciStyledText classes.
|
||||||
|
- Added annotate(), annotation(), clearAnnotations(), setAnnotationDisplay()
|
||||||
|
and annotationDisplay() to QsciScintilla.
|
||||||
|
- Added setMarginText(), clearMarginText(), setMarginType() and marginType()
|
||||||
|
to QsciScintilla.
|
||||||
|
- Added QsciLexer::lexerId() so that container lexers can be implemented.
|
||||||
|
- Added editor() and styleBitsNeeded() to QsciLexer.
|
||||||
|
- Added setDollarsAllowed() and dollarsAllowed() to QsciLexerCPP.
|
||||||
|
- Added setFoldScriptComments(), foldScriptComments(),
|
||||||
|
setFoldScriptHeredocs() and foldScriptHeredocs() to QsciLexerHTML.
|
||||||
|
- Added setSmartHighlighting() and smartHighlighting() to QsciLexerPascal.
|
||||||
|
(Note that the Scintilla Pascal lexer has changed so that any saved colour
|
||||||
|
and font settings will not be properly restored.)
|
||||||
|
- Added setFoldPackages(), foldPackages(), setFoldPODBlocks() and
|
||||||
|
foldPODBlocks() to QsciLexerPerl.
|
||||||
|
- Added setV2UnicodeAllowed(), v2UnicodeAllowed(), setV3BinaryOctalAllowed(),
|
||||||
|
v3BinaryOctalAllowed(), setV3BytesAllowed and v3BytesAllowed() to
|
||||||
|
QsciLexerPython.
|
||||||
|
- Added setScriptsStyled() and scriptsStyled() to QsciLexerXML.
|
||||||
|
- Added Spanish translations from Jaime Seuma.
|
||||||
|
|
||||||
|
v2.3.2 17th November 2008
|
||||||
|
- A bug fix release.
|
||||||
|
|
||||||
|
v2.3.1 6th November 2008
|
||||||
|
- Based on Scintilla v1.77.
|
||||||
|
- Added the read() and write() methods to QsciScintilla to allow a file to be
|
||||||
|
read and written while minimising the conversions.
|
||||||
|
- Added the positionFromLineIndex() and lineIndexFromPosition() methods to
|
||||||
|
QsciScintilla to convert between a Scintilla character address and a
|
||||||
|
QScintilla character address.
|
||||||
|
- Added QsciScintilla::wordAtPoint() to return the word at the given screen
|
||||||
|
coordinates.
|
||||||
|
- QSciScintilla::setSelection() now allows the carat to be left at either the
|
||||||
|
start or the end of the selection.
|
||||||
|
- 'with' is now treated as a keyword by the Python lexer.
|
||||||
|
|
||||||
|
v2.3 20th September 2008
|
||||||
|
- Based on Scintilla v1.76.
|
||||||
|
- The new QsciAbstractAPIs class allows applications to replace the default
|
||||||
|
implementation of the language APIs used for auto-completion lists and call
|
||||||
|
tips.
|
||||||
|
- Added QsciScintilla::apiContext() to allow applications to determine the
|
||||||
|
context used for auto-completion and call tips.
|
||||||
|
- Added the QsciLexerFortran, QsciLexerFortran77, QsciLexerPascal,
|
||||||
|
QsciLexerPostScript, QsciLexerTCL, QsciLexerXML and QsciLexerYAML classes.
|
||||||
|
- QsciScintilla::setFolding() will now accept an optional margin number.
|
||||||
|
|
||||||
|
v2.2 27th February 2008
|
||||||
|
- Based on Scintilla v1.75.
|
||||||
|
- A lexer's default colour, paper and font are now written to and read from
|
||||||
|
the settings.
|
||||||
|
- Windows64 is now supported.
|
||||||
|
- The signature of the QsciScintillaBase::SCN_MACRORECORD() signal has
|
||||||
|
changed slightly.
|
||||||
|
- Changed the licensing to match the current Qt licenses, including GPL v3.
|
||||||
|
|
||||||
|
v2.1 1st June 2007
|
||||||
|
- A slightly revised API, incompatible with QScintilla v2.0.
|
||||||
|
- Lexers now remember their style settings. A lexer no longer has to be the
|
||||||
|
current lexer when changing a style's color, end-of-line fill, font or
|
||||||
|
paper.
|
||||||
|
- The color(), eolFill(), font() and paper() methods of QsciLexer now return
|
||||||
|
the current values for a style rather than the default values.
|
||||||
|
- The setDefaultColor(), setDefaultFont() and setDefaultPaper() methods of
|
||||||
|
QsciLexer are no longer slots and no longer virtual.
|
||||||
|
- The defaultColor(), defaultFont() and defaultPaper() methods of QsciLexer
|
||||||
|
are no longer virtual.
|
||||||
|
- The color(), eolFill(), font() and paper() methods of all QsciLexer derived
|
||||||
|
classes (except for QsciLexer itself) have been renamed defaultColor(),
|
||||||
|
defaultEolFill(), defaultFont() and defaultPaper() respectively.
|
||||||
|
|
||||||
|
v2.0 26th May 2007
|
||||||
|
- A revised API, incompatible with QScintilla v1.
|
||||||
|
- Hugely improved autocompletion and call tips support.
|
||||||
|
- Supports both Qt v3 and Qt v4.
|
||||||
|
- Includes Python bindings.
|
||||||
50
third_party/qscintilla/Python/README
vendored
Normal file
50
third_party/qscintilla/Python/README
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
QScintilla - Python Bindings for the QScintilla Programmers Editor Widget
|
||||||
|
=========================================================================
|
||||||
|
|
||||||
|
QScintilla is a port to Qt of the Scintilla programmers editor widget. It
|
||||||
|
supports the traditional low-level Scintilla API and implements a high-level
|
||||||
|
API covering such things as auto-completion, code folding and lexer
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
These Python bindings implement a single extension module that sits on top of
|
||||||
|
PyQt5 and wraps both the low-level and high-level APIs.
|
||||||
|
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
QScintilla is copyright (c) Riverbank Computing Limited. Its homepage is
|
||||||
|
https://www.riverbankcomputing.com/software/qscintilla/.
|
||||||
|
|
||||||
|
Support may be obtained from the QScintilla mailing list at
|
||||||
|
https://www.riverbankcomputing.com/mailman/listinfo/qscintilla/.
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
QScintilla is released under the GPL v3 license and under a commercial license
|
||||||
|
that allows for the development of proprietary applications.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The documentation for the latest release can be found
|
||||||
|
`here <https://www.riverbankcomputing.com/static/Docs/QScintilla/>`__.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
The GPL version of QScintilla can be installed from PyPI::
|
||||||
|
|
||||||
|
pip install QScintilla
|
||||||
|
|
||||||
|
The wheels include a statically linked copy of the QScintilla C++ library.
|
||||||
|
|
||||||
|
``pip`` will also build and install the bindings from the sdist package but
|
||||||
|
Qt's ``qmake`` tool must be on ``PATH``.
|
||||||
|
|
||||||
|
The ``sip-install`` tool will also install the bindings from the sdist package
|
||||||
|
but will allow you to configure many aspects of the installation.
|
||||||
22
third_party/qscintilla/Python/config-tests/cfgtest_Qsci.cpp
vendored
Normal file
22
third_party/qscintilla/Python/config-tests/cfgtest_Qsci.cpp
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
#include <Qsci/qsciglobal.h>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
QFile outf(argv[1]);
|
||||||
|
|
||||||
|
if (!outf.open(QIODevice::WriteOnly|QIODevice::Truncate|QIODevice::Text))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
QTextStream out(&outf);
|
||||||
|
|
||||||
|
out << QSCINTILLA_VERSION << '\n';
|
||||||
|
out << QSCINTILLA_VERSION_STR << '\n';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
212
third_party/qscintilla/Python/project.py
vendored
Normal file
212
third_party/qscintilla/Python/project.py
vendored
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
# This is the build script for the QScintilla Python bindings.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
#
|
||||||
|
# This file is part of QScintilla.
|
||||||
|
#
|
||||||
|
# This file may be used under the terms of the GNU General Public License
|
||||||
|
# version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
# the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
# following information to ensure the GNU General Public License version 3.0
|
||||||
|
# requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
#
|
||||||
|
# If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
# then you may purchase a commercial license. For more information contact
|
||||||
|
# info@riverbankcomputing.com.
|
||||||
|
#
|
||||||
|
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pyqtbuild import PyQtBindings, PyQtProject
|
||||||
|
from sipbuild import Option
|
||||||
|
|
||||||
|
|
||||||
|
class QScintilla(PyQtProject):
|
||||||
|
""" The QScintilla project. """
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
""" Initialise the project. """
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.bindings_factories = [Qsci]
|
||||||
|
|
||||||
|
# If there is a 'src' subdirectory then we are part of an sdist rather
|
||||||
|
# than a full source distribution. If part of an sdist then the
|
||||||
|
# QScintilla source is compiled along with the bindings. Otherwise an
|
||||||
|
# external (ie. already built) QScintilla library is used (which may be
|
||||||
|
# static or dynamic).
|
||||||
|
self.qsci_external_lib = not os.path.isdir('src')
|
||||||
|
|
||||||
|
def apply_user_defaults(self, tool):
|
||||||
|
""" Set default values for user options that haven't been set yet. """
|
||||||
|
|
||||||
|
super().apply_user_defaults(tool)
|
||||||
|
|
||||||
|
if not self.qsci_external_lib:
|
||||||
|
# If a directory to install the .api files was given then add the
|
||||||
|
# bundled .api files as well.
|
||||||
|
if self.api_dir:
|
||||||
|
self.wheel_includes.append(
|
||||||
|
('qsci/api/python/*.api', self.api_dir))
|
||||||
|
|
||||||
|
if self.qsci_translations_dir:
|
||||||
|
self.wheel_includes.append(
|
||||||
|
('src/*.qm', self.qsci_translations_dir))
|
||||||
|
|
||||||
|
def get_options(self):
|
||||||
|
""" Return the list of configurable options. """
|
||||||
|
|
||||||
|
options = super().get_options()
|
||||||
|
|
||||||
|
# The directory within the wheel to install the translation files to.
|
||||||
|
options.append(
|
||||||
|
Option('qsci_translations_dir',
|
||||||
|
help="the QScintilla translation files will be installed in DIR",
|
||||||
|
metavar="DIR", tools=['wheel']))
|
||||||
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
|
||||||
|
class Qsci(PyQtBindings):
|
||||||
|
""" The Qsci bindings. """
|
||||||
|
|
||||||
|
def __init__(self, project):
|
||||||
|
""" Initialise the bindings. """
|
||||||
|
|
||||||
|
if project.qsci_external_lib:
|
||||||
|
qmake_CONFIG = ['qscintilla2']
|
||||||
|
else:
|
||||||
|
qmake_CONFIG = []
|
||||||
|
|
||||||
|
super().__init__(project, 'Qsci', qmake_CONFIG=qmake_CONFIG)
|
||||||
|
|
||||||
|
def apply_user_defaults(self, tool):
|
||||||
|
""" Set default values for user options that haven't been set yet. """
|
||||||
|
|
||||||
|
project = self.project
|
||||||
|
qt6 = (project.builder.qt_version >= 0x060000)
|
||||||
|
|
||||||
|
# Set the name of the .sip file now that we know the Qt version number.
|
||||||
|
self.sip_file = 'qscimod6.sip' if qt6 else 'qscimod5.sip'
|
||||||
|
|
||||||
|
if self.project.qsci_external_lib:
|
||||||
|
if self.qsci_features_dir is not None:
|
||||||
|
os.environ['QMAKEFEATURES'] = os.path.abspath(
|
||||||
|
self.qsci_features_dir)
|
||||||
|
|
||||||
|
if self.qsci_include_dir is not None:
|
||||||
|
self.include_dirs.append(
|
||||||
|
os.path.abspath(self.qsci_include_dir))
|
||||||
|
|
||||||
|
if self.qsci_library_dir is not None:
|
||||||
|
self.library_dirs.append(
|
||||||
|
os.path.abspath(self.qsci_library_dir))
|
||||||
|
else:
|
||||||
|
# We configure CONFIG and QT textually because it's too late to
|
||||||
|
# update qmake_CONFIG and qmake_QT.
|
||||||
|
self.builder_settings.append('QT += widgets')
|
||||||
|
|
||||||
|
if project.py_platform != 'ios':
|
||||||
|
self.builder_settings.append('QT += printsupport')
|
||||||
|
|
||||||
|
if project.py_platform in ('darwin', 'ios') and not qt6:
|
||||||
|
self.builder_settings.append('QT += macextras')
|
||||||
|
|
||||||
|
self.builder_settings.append(
|
||||||
|
'CONFIG += warn_off thread exceptions')
|
||||||
|
|
||||||
|
self.define_macros.extend(
|
||||||
|
['SCINTILLA_QT', 'SCI_LEXER',
|
||||||
|
'INCLUDE_DEPRECATED_FEATURES'])
|
||||||
|
|
||||||
|
self._add_internal_lib_sources()
|
||||||
|
|
||||||
|
super().apply_user_defaults(tool)
|
||||||
|
|
||||||
|
def get_options(self):
|
||||||
|
""" Return the list of configurable options. """
|
||||||
|
|
||||||
|
options = super().get_options()
|
||||||
|
|
||||||
|
if self.project.qsci_external_lib:
|
||||||
|
# The directory containing the features file.
|
||||||
|
options.append(
|
||||||
|
Option('qsci_features_dir',
|
||||||
|
help="the qscintilla2.prf features file is in DIR",
|
||||||
|
metavar="DIR"))
|
||||||
|
|
||||||
|
# The directory containing the include directory.
|
||||||
|
options.append(
|
||||||
|
Option('qsci_include_dir',
|
||||||
|
help="the Qsci include file directory is in DIR",
|
||||||
|
metavar="DIR"))
|
||||||
|
|
||||||
|
# The directory containing the library.
|
||||||
|
options.append(
|
||||||
|
Option('qsci_library_dir',
|
||||||
|
help="the QScintilla library is in DIR",
|
||||||
|
metavar="DIR"))
|
||||||
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
def handle_test_output(self, test_output):
|
||||||
|
""" Handle the output from the external test program and return True if
|
||||||
|
the bindings are buildable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
project = self.project
|
||||||
|
|
||||||
|
installed_version = int(test_output[0])
|
||||||
|
installed_version_str = test_output[1]
|
||||||
|
|
||||||
|
if project.version != installed_version:
|
||||||
|
project.progress(
|
||||||
|
"QScintilla v{0} is required but QScintilla v{1} is "
|
||||||
|
"installed.".format(project.version_str,
|
||||||
|
installed_version_str))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_buildable(self):
|
||||||
|
""" Return True if the bindings are buildable. """
|
||||||
|
|
||||||
|
# We need to check the compatibility of an external QScintilla library.
|
||||||
|
if self.project.qsci_external_lib:
|
||||||
|
return super().is_buildable()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _add_dir_sources(self, dname):
|
||||||
|
""" Add the headers and sources from a particular directory. """
|
||||||
|
|
||||||
|
for fn in os.listdir(dname):
|
||||||
|
# Skip the printer support on iOS.
|
||||||
|
if self.project.py_platform == 'ios' and fn.startswith('qsciprinter.'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if fn.endswith('.h'):
|
||||||
|
self.headers.append(os.path.join(dname, fn))
|
||||||
|
elif fn.endswith('.cpp'):
|
||||||
|
self.sources.append(os.path.join(dname, fn))
|
||||||
|
|
||||||
|
def _add_internal_lib_sources(self):
|
||||||
|
""" Add to the lists of include directories, header files and source
|
||||||
|
files to build the QScintilla library.
|
||||||
|
"""
|
||||||
|
|
||||||
|
include_dirs = ['src']
|
||||||
|
|
||||||
|
for dn in ('include', 'lexers', 'lexlib', 'src'):
|
||||||
|
include_dirs.append(os.path.join('scintilla', dn))
|
||||||
|
|
||||||
|
self._add_dir_sources(os.path.join('src', 'Qsci'))
|
||||||
|
|
||||||
|
for dn in include_dirs:
|
||||||
|
self._add_dir_sources(dn)
|
||||||
|
|
||||||
|
self.include_dirs.extend(include_dirs)
|
||||||
16
third_party/qscintilla/Python/pyproject-qt5.toml
vendored
Normal file
16
third_party/qscintilla/Python/pyproject-qt5.toml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Specify the build system.
|
||||||
|
[build-system]
|
||||||
|
requires = ["sip >=6.0.2, <7", "PyQt-builder >=1.6, <2"]
|
||||||
|
build-backend = "sipbuild.api"
|
||||||
|
|
||||||
|
# Specify the PEP 566 metadata for the project.
|
||||||
|
[tool.sip.metadata]
|
||||||
|
name = "QScintilla"
|
||||||
|
version = "2.14.1"
|
||||||
|
summary = "Python bindings for the QScintilla programmers editor widget"
|
||||||
|
home-page = "https://www.riverbankcomputing.com/software/qscintilla/"
|
||||||
|
author = "Riverbank Computing Limited"
|
||||||
|
author-email = "info@riverbankcomputing.com"
|
||||||
|
license = "GPL v3"
|
||||||
|
description-file = "README"
|
||||||
|
requires-dist = "PyQt5 (>=5.15.4)"
|
||||||
16
third_party/qscintilla/Python/pyproject-qt6.toml
vendored
Normal file
16
third_party/qscintilla/Python/pyproject-qt6.toml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Specify the build system.
|
||||||
|
[build-system]
|
||||||
|
requires = ["sip >=6.0.2, <7", "PyQt-builder >=1.6, <2"]
|
||||||
|
build-backend = "sipbuild.api"
|
||||||
|
|
||||||
|
# Specify the PEP 566 metadata for the project.
|
||||||
|
[tool.sip.metadata]
|
||||||
|
name = "PyQt6-QScintilla"
|
||||||
|
version = "2.14.1"
|
||||||
|
summary = "Python bindings for the QScintilla programmers editor widget"
|
||||||
|
home-page = "https://www.riverbankcomputing.com/software/qscintilla/"
|
||||||
|
author = "Riverbank Computing Limited"
|
||||||
|
author-email = "info@riverbankcomputing.com"
|
||||||
|
license = "GPL v3"
|
||||||
|
description-file = "README"
|
||||||
|
requires-dist = "PyQt6 (>=6.0.3)"
|
||||||
42
third_party/qscintilla/Python/sip/qsciabstractapis.sip
vendored
Normal file
42
third_party/qscintilla/Python/sip/qsciabstractapis.sip
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// This is the SIP interface definition for QsciAbstractAPIs.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciAbstractAPIs : QObject
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qsciabstractapis.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciAbstractAPIs(QsciLexer *lexer /TransferThis/);
|
||||||
|
virtual ~QsciAbstractAPIs();
|
||||||
|
|
||||||
|
QsciLexer *lexer() const;
|
||||||
|
|
||||||
|
virtual void updateAutoCompletionList(const QStringList &context,
|
||||||
|
QStringList &list /In, Out/) = 0;
|
||||||
|
virtual void autoCompletionSelected(const QString &selection);
|
||||||
|
|
||||||
|
virtual QStringList callTips(const QStringList &context, int commas,
|
||||||
|
QsciScintilla::CallTipsStyle style, QList<int> &shifts) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciAbstractAPIs(const QsciAbstractAPIs &);
|
||||||
|
};
|
||||||
58
third_party/qscintilla/Python/sip/qsciapis.sip
vendored
Normal file
58
third_party/qscintilla/Python/sip/qsciapis.sip
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// This is the SIP interface definition for QsciAPIs.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciAPIs : QsciAbstractAPIs
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qsciapis.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciAPIs(QsciLexer *lexer /TransferThis/);
|
||||||
|
virtual ~QsciAPIs();
|
||||||
|
|
||||||
|
void add(const QString &entry);
|
||||||
|
void clear();
|
||||||
|
bool load(const QString &fname);
|
||||||
|
void remove(const QString &entry);
|
||||||
|
void prepare();
|
||||||
|
void cancelPreparation();
|
||||||
|
QString defaultPreparedName() const;
|
||||||
|
bool isPrepared(const QString &filename = QString()) const;
|
||||||
|
bool loadPrepared(const QString &filename = QString());
|
||||||
|
bool savePrepared(const QString &filename = QString()) const;
|
||||||
|
virtual bool event(QEvent *e);
|
||||||
|
QStringList installedAPIFiles() const;
|
||||||
|
|
||||||
|
virtual void updateAutoCompletionList(const QStringList &context,
|
||||||
|
QStringList &list /In, Out/);
|
||||||
|
virtual void autoCompletionSelected(const QString &selection);
|
||||||
|
|
||||||
|
virtual QStringList callTips(const QStringList &context, int commas,
|
||||||
|
QsciScintilla::CallTipsStyle style, QList<int> &shifts);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void apiPreparationCancelled();
|
||||||
|
void apiPreparationStarted();
|
||||||
|
void apiPreparationFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciAPIs(const QsciAPIs &);
|
||||||
|
};
|
||||||
143
third_party/qscintilla/Python/sip/qscicommand.sip
vendored
Normal file
143
third_party/qscintilla/Python/sip/qscicommand.sip
vendored
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
// This is the SIP interface definition for QsciCommand.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciCommand
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscicommand.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Command {
|
||||||
|
LineDown,
|
||||||
|
LineDownExtend,
|
||||||
|
LineDownRectExtend,
|
||||||
|
LineScrollDown,
|
||||||
|
LineUp,
|
||||||
|
LineUpExtend,
|
||||||
|
LineUpRectExtend,
|
||||||
|
LineScrollUp,
|
||||||
|
ScrollToStart,
|
||||||
|
ScrollToEnd,
|
||||||
|
VerticalCentreCaret,
|
||||||
|
ParaDown,
|
||||||
|
ParaDownExtend,
|
||||||
|
ParaUp,
|
||||||
|
ParaUpExtend,
|
||||||
|
CharLeft,
|
||||||
|
CharLeftExtend,
|
||||||
|
CharLeftRectExtend,
|
||||||
|
CharRight,
|
||||||
|
CharRightExtend,
|
||||||
|
CharRightRectExtend,
|
||||||
|
WordLeft,
|
||||||
|
WordLeftExtend,
|
||||||
|
WordRight,
|
||||||
|
WordRightExtend,
|
||||||
|
WordLeftEnd,
|
||||||
|
WordLeftEndExtend,
|
||||||
|
WordRightEnd,
|
||||||
|
WordRightEndExtend,
|
||||||
|
WordPartLeft,
|
||||||
|
WordPartLeftExtend,
|
||||||
|
WordPartRight,
|
||||||
|
WordPartRightExtend,
|
||||||
|
Home,
|
||||||
|
HomeExtend,
|
||||||
|
HomeRectExtend,
|
||||||
|
HomeDisplay,
|
||||||
|
HomeDisplayExtend,
|
||||||
|
HomeWrap,
|
||||||
|
HomeWrapExtend,
|
||||||
|
VCHome,
|
||||||
|
VCHomeExtend,
|
||||||
|
VCHomeRectExtend,
|
||||||
|
VCHomeWrap,
|
||||||
|
VCHomeWrapExtend,
|
||||||
|
LineEnd,
|
||||||
|
LineEndExtend,
|
||||||
|
LineEndRectExtend,
|
||||||
|
LineEndDisplay,
|
||||||
|
LineEndDisplayExtend,
|
||||||
|
LineEndWrap,
|
||||||
|
LineEndWrapExtend,
|
||||||
|
DocumentStart,
|
||||||
|
DocumentStartExtend,
|
||||||
|
DocumentEnd,
|
||||||
|
DocumentEndExtend,
|
||||||
|
PageUp,
|
||||||
|
PageUpExtend,
|
||||||
|
PageUpRectExtend,
|
||||||
|
PageDown,
|
||||||
|
PageDownExtend,
|
||||||
|
PageDownRectExtend,
|
||||||
|
StutteredPageUp,
|
||||||
|
StutteredPageUpExtend,
|
||||||
|
StutteredPageDown,
|
||||||
|
StutteredPageDownExtend,
|
||||||
|
Delete,
|
||||||
|
DeleteBack,
|
||||||
|
DeleteBackNotLine,
|
||||||
|
DeleteWordLeft,
|
||||||
|
DeleteWordRight,
|
||||||
|
DeleteWordRightEnd,
|
||||||
|
DeleteLineLeft,
|
||||||
|
DeleteLineRight,
|
||||||
|
LineDelete,
|
||||||
|
LineCut,
|
||||||
|
LineCopy,
|
||||||
|
LineTranspose,
|
||||||
|
LineDuplicate,
|
||||||
|
SelectAll,
|
||||||
|
MoveSelectedLinesUp,
|
||||||
|
MoveSelectedLinesDown,
|
||||||
|
SelectionDuplicate,
|
||||||
|
SelectionLowerCase,
|
||||||
|
SelectionUpperCase,
|
||||||
|
SelectionCut,
|
||||||
|
SelectionCopy,
|
||||||
|
Paste,
|
||||||
|
EditToggleOvertype,
|
||||||
|
Newline,
|
||||||
|
Formfeed,
|
||||||
|
Tab,
|
||||||
|
Backtab,
|
||||||
|
Cancel,
|
||||||
|
Undo,
|
||||||
|
Redo,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
ReverseLines,
|
||||||
|
};
|
||||||
|
|
||||||
|
Command command() const;
|
||||||
|
void execute();
|
||||||
|
void setKey(int key);
|
||||||
|
void setAlternateKey(int altkey);
|
||||||
|
int key() const;
|
||||||
|
int alternateKey() const;
|
||||||
|
static bool validKey(int key);
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciCommand(QsciScintilla *qs, Command cmd, int key, int altkey,
|
||||||
|
const char *desc);
|
||||||
|
QsciCommand(const QsciCommand &);
|
||||||
|
};
|
||||||
44
third_party/qscintilla/Python/sip/qscicommandset.sip
vendored
Normal file
44
third_party/qscintilla/Python/sip/qscicommandset.sip
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// This is the SIP interface definition for the QsciCommandSet.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciCommandSet
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscicommandset.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool readSettings(QSettings &qs, const char *prefix = "/Scintilla");
|
||||||
|
bool writeSettings(QSettings &qs, const char *prefix = "/Scintilla");
|
||||||
|
|
||||||
|
QList<QsciCommand *> &commands();
|
||||||
|
|
||||||
|
void clearKeys();
|
||||||
|
void clearAlternateKeys();
|
||||||
|
|
||||||
|
QsciCommand *boundTo(int key) const;
|
||||||
|
QsciCommand *find(QsciCommand::Command command) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciCommandSet(QsciScintilla *qs);
|
||||||
|
~QsciCommandSet();
|
||||||
|
|
||||||
|
QsciCommandSet(const QsciCommandSet &);
|
||||||
|
};
|
||||||
32
third_party/qscintilla/Python/sip/qscidocument.sip
vendored
Normal file
32
third_party/qscintilla/Python/sip/qscidocument.sip
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// This is the SIP interface definition for QsciDocument.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciDocument
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscidocument.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciDocument();
|
||||||
|
virtual ~QsciDocument();
|
||||||
|
|
||||||
|
QsciDocument(const QsciDocument &);
|
||||||
|
};
|
||||||
90
third_party/qscintilla/Python/sip/qscilexer.sip
vendored
Normal file
90
third_party/qscintilla/Python/sip/qscilexer.sip
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexer.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexer : QObject
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexer.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexer(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexer();
|
||||||
|
|
||||||
|
virtual const char *language() const = 0;
|
||||||
|
virtual const char *lexer() const;
|
||||||
|
virtual int lexerId() const;
|
||||||
|
QsciAbstractAPIs *apis() const;
|
||||||
|
virtual const char *autoCompletionFillups() const /Encoding="None"/;
|
||||||
|
virtual QStringList autoCompletionWordSeparators() const;
|
||||||
|
int autoIndentStyle();
|
||||||
|
virtual const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
virtual int blockLookback() const;
|
||||||
|
virtual const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
virtual const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
virtual int braceStyle() const;
|
||||||
|
virtual bool caseSensitive() const;
|
||||||
|
virtual QColor color(int style) const;
|
||||||
|
virtual bool eolFill(int style) const;
|
||||||
|
virtual QFont font(int style) const;
|
||||||
|
virtual int indentationGuideView() const;
|
||||||
|
virtual const char *keywords(int set) const;
|
||||||
|
virtual QString description(int style) const = 0;
|
||||||
|
virtual QColor paper(int style) const;
|
||||||
|
QColor defaultColor() const;
|
||||||
|
virtual QColor defaultColor(int style) const;
|
||||||
|
virtual bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont() const;
|
||||||
|
virtual QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper() const;
|
||||||
|
virtual QColor defaultPaper(int style) const;
|
||||||
|
virtual int defaultStyle() const;
|
||||||
|
QsciScintilla *editor() const;
|
||||||
|
virtual void refreshProperties();
|
||||||
|
void setAPIs(QsciAbstractAPIs *apis);
|
||||||
|
void setDefaultColor(const QColor &c);
|
||||||
|
void setDefaultFont(const QFont &f);
|
||||||
|
void setDefaultPaper(const QColor &c);
|
||||||
|
virtual int styleBitsNeeded() const;
|
||||||
|
virtual const char *wordCharacters() const;
|
||||||
|
bool readSettings(QSettings &qs, const char *prefix = "/Scintilla");
|
||||||
|
bool writeSettings(QSettings &qs, const char *prefix = "/Scintilla") const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setAutoIndentStyle(int autoindentstyle);
|
||||||
|
virtual void setColor(const QColor &c, int style = -1);
|
||||||
|
virtual void setEolFill(bool eolfill, int style = -1);
|
||||||
|
virtual void setFont(const QFont &f, int style = -1);
|
||||||
|
virtual void setPaper(const QColor &c, int style = -1);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void colorChanged(const QColor &c, int style);
|
||||||
|
void eolFillChanged(bool eolfilled, int style);
|
||||||
|
void fontChanged(const QFont &f, int style);
|
||||||
|
void paperChanged(const QColor &c, int style);
|
||||||
|
void propertyChanged(const char *prop, const char *val);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
virtual bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexer(const QsciLexer &);
|
||||||
|
};
|
||||||
74
third_party/qscintilla/Python/sip/qscilexerasm.sip
vendored
Normal file
74
third_party/qscintilla/Python/sip/qscilexerasm.sip
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerAsm.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerAsm : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerasm.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Number,
|
||||||
|
DoubleQuotedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
CPUInstruction,
|
||||||
|
FPUInstruction,
|
||||||
|
Register,
|
||||||
|
Directive,
|
||||||
|
DirectiveOperand,
|
||||||
|
BlockComment,
|
||||||
|
SingleQuotedString,
|
||||||
|
UnclosedString,
|
||||||
|
ExtendedInstruction,
|
||||||
|
CommentDirective,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerAsm(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerAsm();
|
||||||
|
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
QChar commentDelimiter() const;
|
||||||
|
bool foldSyntaxBased() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setCommentDelimiter(QChar delimeter);
|
||||||
|
virtual void setFoldSyntaxBased(bool syntax_based);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerAsm(const QsciLexerAsm &);
|
||||||
|
};
|
||||||
73
third_party/qscintilla/Python/sip/qscilexeravs.sip
vendored
Normal file
73
third_party/qscintilla/Python/sip/qscilexeravs.sip
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerAVS.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerAVS : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexeravs.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
BlockComment,
|
||||||
|
NestedBlockComment,
|
||||||
|
LineComment,
|
||||||
|
Number,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
String,
|
||||||
|
TripleString,
|
||||||
|
Keyword,
|
||||||
|
Filter,
|
||||||
|
Plugin,
|
||||||
|
Function,
|
||||||
|
ClipProperty,
|
||||||
|
KeywordSet6
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerAVS(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerAVS();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerAVS(const QsciLexerAVS &);
|
||||||
|
};
|
||||||
74
third_party/qscintilla/Python/sip/qscilexerbash.sip
vendored
Normal file
74
third_party/qscintilla/Python/sip/qscilexerbash.sip
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerBash.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerBash : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerbash.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Error,
|
||||||
|
Comment,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
Scalar,
|
||||||
|
ParameterExpansion,
|
||||||
|
Backticks,
|
||||||
|
HereDocumentDelimiter,
|
||||||
|
SingleQuotedHereDocument
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerBash(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerBash();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerBash(const QsciLexerBash &);
|
||||||
|
};
|
||||||
56
third_party/qscintilla/Python/sip/qscilexerbatch.sip
vendored
Normal file
56
third_party/qscintilla/Python/sip/qscilexerbatch.sip
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerBatch.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerBatch : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerbatch.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Keyword,
|
||||||
|
Label,
|
||||||
|
HideCommandChar,
|
||||||
|
ExternalCommand,
|
||||||
|
Variable,
|
||||||
|
Operator
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerBatch(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerBatch();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
bool caseSensitive() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerBatch(const QsciLexerBatch &);
|
||||||
|
};
|
||||||
69
third_party/qscintilla/Python/sip/qscilexercmake.sip
vendored
Normal file
69
third_party/qscintilla/Python/sip/qscilexercmake.sip
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCMake.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCMake : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercmake.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
String,
|
||||||
|
StringLeftQuote,
|
||||||
|
StringRightQuote,
|
||||||
|
Function,
|
||||||
|
Variable,
|
||||||
|
Label,
|
||||||
|
KeywordSet3,
|
||||||
|
BlockWhile,
|
||||||
|
BlockForeach,
|
||||||
|
BlockIf,
|
||||||
|
BlockMacro,
|
||||||
|
StringVariable,
|
||||||
|
Number
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerCMake(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerCMake();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldAtElse() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldAtElse(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCMake(const QsciLexerCMake &);
|
||||||
|
};
|
||||||
90
third_party/qscintilla/Python/sip/qscilexercoffeescript.sip
vendored
Normal file
90
third_party/qscintilla/Python/sip/qscilexercoffeescript.sip
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCoffeeScript.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCoffeeScript : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercoffeescript.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
CommentDoc,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
UUID,
|
||||||
|
PreProcessor,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
UnclosedString,
|
||||||
|
VerbatimString,
|
||||||
|
Regex,
|
||||||
|
CommentLineDoc,
|
||||||
|
KeywordSet2,
|
||||||
|
CommentDocKeyword,
|
||||||
|
CommentDocKeywordError,
|
||||||
|
GlobalClass,
|
||||||
|
CommentBlock,
|
||||||
|
BlockRegex,
|
||||||
|
BlockRegexComment,
|
||||||
|
InstanceProperty,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerCoffeeScript(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerCoffeeScript();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool dollarsAllowed() const;
|
||||||
|
void setDollarsAllowed(bool allowed);
|
||||||
|
bool foldComments() const;
|
||||||
|
void setFoldComments(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool stylePreprocessor() const;
|
||||||
|
void setStylePreprocessor(bool style);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCoffeeScript(const QsciLexerCoffeeScript &);
|
||||||
|
};
|
||||||
138
third_party/qscintilla/Python/sip/qscilexercpp.sip
vendored
Normal file
138
third_party/qscintilla/Python/sip/qscilexercpp.sip
vendored
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCPP.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCPP : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercpp.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
InactiveDefault,
|
||||||
|
Comment,
|
||||||
|
InactiveComment,
|
||||||
|
CommentLine,
|
||||||
|
InactiveCommentLine,
|
||||||
|
CommentDoc,
|
||||||
|
InactiveCommentDoc,
|
||||||
|
Number,
|
||||||
|
InactiveNumber,
|
||||||
|
Keyword,
|
||||||
|
InactiveKeyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
InactiveDoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
InactiveSingleQuotedString,
|
||||||
|
UUID,
|
||||||
|
InactiveUUID,
|
||||||
|
PreProcessor,
|
||||||
|
InactivePreProcessor,
|
||||||
|
Operator,
|
||||||
|
InactiveOperator,
|
||||||
|
Identifier,
|
||||||
|
InactiveIdentifier,
|
||||||
|
UnclosedString,
|
||||||
|
InactiveUnclosedString,
|
||||||
|
VerbatimString,
|
||||||
|
InactiveVerbatimString,
|
||||||
|
Regex,
|
||||||
|
InactiveRegex,
|
||||||
|
CommentLineDoc,
|
||||||
|
InactiveCommentLineDoc,
|
||||||
|
KeywordSet2,
|
||||||
|
InactiveKeywordSet2,
|
||||||
|
CommentDocKeyword,
|
||||||
|
InactiveCommentDocKeyword,
|
||||||
|
CommentDocKeywordError,
|
||||||
|
InactiveCommentDocKeywordError,
|
||||||
|
GlobalClass,
|
||||||
|
InactiveGlobalClass,
|
||||||
|
RawString,
|
||||||
|
InactiveRawString,
|
||||||
|
TripleQuotedVerbatimString,
|
||||||
|
InactiveTripleQuotedVerbatimString,
|
||||||
|
HashQuotedString,
|
||||||
|
InactiveHashQuotedString,
|
||||||
|
PreProcessorComment,
|
||||||
|
InactivePreProcessorComment,
|
||||||
|
PreProcessorCommentLineDoc,
|
||||||
|
InactivePreProcessorCommentLineDoc,
|
||||||
|
UserLiteral,
|
||||||
|
InactiveUserLiteral,
|
||||||
|
TaskMarker,
|
||||||
|
InactiveTaskMarker,
|
||||||
|
EscapeSequence,
|
||||||
|
InactiveEscapeSequence,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerCPP(QObject *parent /TransferThis/ = 0,
|
||||||
|
bool caseInsensitiveKeywords = false);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldAtElse() const;
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldPreprocessor() const;
|
||||||
|
bool stylePreprocessor() const;
|
||||||
|
void setDollarsAllowed(bool allowed);
|
||||||
|
bool dollarsAllowed() const;
|
||||||
|
void setHighlightTripleQuotedStrings(bool enable);
|
||||||
|
bool highlightTripleQuotedStrings() const;
|
||||||
|
void setHighlightHashQuotedStrings(bool enable);
|
||||||
|
bool highlightHashQuotedStrings() const;
|
||||||
|
void setHighlightBackQuotedStrings(bool enabled);
|
||||||
|
bool highlightBackQuotedStrings() const;
|
||||||
|
void setHighlightEscapeSequences(bool enabled);
|
||||||
|
bool highlightEscapeSequences() const;
|
||||||
|
void setVerbatimStringEscapeSequencesAllowed(bool allowed);
|
||||||
|
bool verbatimStringEscapeSequencesAllowed() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldAtElse(bool fold);
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldPreprocessor(bool fold);
|
||||||
|
virtual void setStylePreprocessor(bool style);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCPP(const QsciLexerCPP &);
|
||||||
|
};
|
||||||
41
third_party/qscintilla/Python/sip/qscilexercsharp.sip
vendored
Normal file
41
third_party/qscintilla/Python/sip/qscilexercsharp.sip
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCSharp.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCSharp : QsciLexerCPP
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercsharp.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerCSharp(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerCSharp();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCSharp(const QsciLexerCSharp &);
|
||||||
|
};
|
||||||
88
third_party/qscintilla/Python/sip/qscilexercss.sip
vendored
Normal file
88
third_party/qscintilla/Python/sip/qscilexercss.sip
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCSS.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCSS : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercss.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Tag,
|
||||||
|
ClassSelector,
|
||||||
|
PseudoClass,
|
||||||
|
UnknownPseudoClass,
|
||||||
|
Operator,
|
||||||
|
CSS1Property,
|
||||||
|
UnknownProperty,
|
||||||
|
Value,
|
||||||
|
Comment,
|
||||||
|
IDSelector,
|
||||||
|
Important,
|
||||||
|
AtRule,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
CSS2Property,
|
||||||
|
Attribute,
|
||||||
|
CSS3Property,
|
||||||
|
PseudoElement,
|
||||||
|
ExtendedCSSProperty,
|
||||||
|
ExtendedPseudoClass,
|
||||||
|
ExtendedPseudoElement,
|
||||||
|
MediaRule,
|
||||||
|
Variable,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerCSS(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerCSS();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
void setHSSLanguage(bool enable);
|
||||||
|
bool HSSLanguage() const;
|
||||||
|
void setLessLanguage(bool enable);
|
||||||
|
bool LessLanguage() const;
|
||||||
|
void setSCSSLanguage(bool enable);
|
||||||
|
bool SCSSLanguage() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCSS(const QsciLexerCSS &);
|
||||||
|
};
|
||||||
42
third_party/qscintilla/Python/sip/qscilexercustom.sip
vendored
Normal file
42
third_party/qscintilla/Python/sip/qscilexercustom.sip
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerCustom.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerCustom : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexercustom.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerCustom(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerCustom();
|
||||||
|
|
||||||
|
virtual void setEditor(QsciScintilla *editor);
|
||||||
|
virtual int styleBitsNeeded() const;
|
||||||
|
|
||||||
|
void setStyling(int length, int style);
|
||||||
|
void setStyling(int length, const QsciStyle &style);
|
||||||
|
|
||||||
|
void startStyling(int pos, int styleBits = 0);
|
||||||
|
virtual void styleText(int start, int end) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerCustom(const QsciLexerCustom &);
|
||||||
|
};
|
||||||
88
third_party/qscintilla/Python/sip/qscilexerd.sip
vendored
Normal file
88
third_party/qscintilla/Python/sip/qscilexerd.sip
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerD.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerD : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerd.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
CommentDoc,
|
||||||
|
CommentNested,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
KeywordSecondary,
|
||||||
|
KeywordDoc,
|
||||||
|
Typedefs,
|
||||||
|
String,
|
||||||
|
UnclosedString,
|
||||||
|
Character,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
CommentLineDoc,
|
||||||
|
CommentDocKeyword,
|
||||||
|
CommentDocKeywordError,
|
||||||
|
BackquoteString,
|
||||||
|
RawString,
|
||||||
|
KeywordSet5,
|
||||||
|
KeywordSet6,
|
||||||
|
KeywordSet7,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerD(QObject *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldAtElse() const;
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldAtElse(bool fold);
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerD(const QsciLexerD &);
|
||||||
|
};
|
||||||
54
third_party/qscintilla/Python/sip/qscilexerdiff.sip
vendored
Normal file
54
third_party/qscintilla/Python/sip/qscilexerdiff.sip
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerDiff.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerDiff : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerdiff.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Command,
|
||||||
|
Header,
|
||||||
|
Position,
|
||||||
|
LineRemoved,
|
||||||
|
LineAdded,
|
||||||
|
LineChanged,
|
||||||
|
AddingPatchAdded,
|
||||||
|
RemovingPatchAdded,
|
||||||
|
AddingPatchRemoved,
|
||||||
|
RemovingPatchRemoved,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerDiff(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerDiff();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerDiff(const QsciLexerDiff &);
|
||||||
|
};
|
||||||
50
third_party/qscintilla/Python/sip/qscilexeredifact.sip
vendored
Normal file
50
third_party/qscintilla/Python/sip/qscilexeredifact.sip
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerEDIFACT.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerEDIFACT : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexeredifact.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
SegmentStart,
|
||||||
|
SegmentEnd,
|
||||||
|
ElementSeparator,
|
||||||
|
CompositeSeparator,
|
||||||
|
ReleaseSeparator,
|
||||||
|
UNASegmentHeader,
|
||||||
|
UNHSegmentHeader,
|
||||||
|
BadSegment
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerEDIFACT(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerEDIFACT();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerEDIFACT(const QsciLexerEDIFACT &);
|
||||||
|
};
|
||||||
36
third_party/qscintilla/Python/sip/qscilexerfortran.sip
vendored
Normal file
36
third_party/qscintilla/Python/sip/qscilexerfortran.sip
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerFortran.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerFortran : QsciLexerFortran77
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerfortran.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerFortran(QObject *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerFortran(const QsciLexerFortran &);
|
||||||
|
};
|
||||||
71
third_party/qscintilla/Python/sip/qscilexerfortran77.sip
vendored
Normal file
71
third_party/qscintilla/Python/sip/qscilexerfortran77.sip
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerFortran77.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerFortran77 : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerfortran77.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Number,
|
||||||
|
SingleQuotedString,
|
||||||
|
DoubleQuotedString,
|
||||||
|
UnclosedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
Keyword,
|
||||||
|
IntrinsicFunction,
|
||||||
|
ExtendedFunction,
|
||||||
|
PreProcessor,
|
||||||
|
DottedOperator,
|
||||||
|
Label,
|
||||||
|
Continuation,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerFortran77(QObject *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerFortran77(const QsciLexerFortran77 &);
|
||||||
|
};
|
||||||
58
third_party/qscintilla/Python/sip/qscilexerhex.sip
vendored
Normal file
58
third_party/qscintilla/Python/sip/qscilexerhex.sip
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerHex.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerHex : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerhex.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
RecordStart,
|
||||||
|
RecordType,
|
||||||
|
UnknownRecordType,
|
||||||
|
ByteCount,
|
||||||
|
IncorrectByteCount,
|
||||||
|
NoAddress,
|
||||||
|
DataAddress,
|
||||||
|
RecordCount,
|
||||||
|
StartAddress,
|
||||||
|
ExtendedAddress,
|
||||||
|
OddData,
|
||||||
|
EvenData,
|
||||||
|
UnknownData,
|
||||||
|
Checksum,
|
||||||
|
IncorrectChecksum,
|
||||||
|
TrailingGarbage,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerHex(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerHex();
|
||||||
|
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerHex(const QsciLexerHex &);
|
||||||
|
};
|
||||||
181
third_party/qscintilla/Python/sip/qscilexerhtml.sip
vendored
Normal file
181
third_party/qscintilla/Python/sip/qscilexerhtml.sip
vendored
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerHTML.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerHTML : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerhtml.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Tag,
|
||||||
|
UnknownTag,
|
||||||
|
Attribute,
|
||||||
|
UnknownAttribute,
|
||||||
|
HTMLNumber,
|
||||||
|
HTMLDoubleQuotedString,
|
||||||
|
HTMLSingleQuotedString,
|
||||||
|
OtherInTag,
|
||||||
|
HTMLComment,
|
||||||
|
Entity,
|
||||||
|
XMLTagEnd,
|
||||||
|
XMLStart,
|
||||||
|
XMLEnd,
|
||||||
|
Script,
|
||||||
|
ASPAtStart,
|
||||||
|
ASPStart,
|
||||||
|
CDATA,
|
||||||
|
PHPStart,
|
||||||
|
HTMLValue,
|
||||||
|
ASPXCComment,
|
||||||
|
SGMLDefault,
|
||||||
|
SGMLCommand,
|
||||||
|
SGMLParameter,
|
||||||
|
SGMLDoubleQuotedString,
|
||||||
|
SGMLSingleQuotedString,
|
||||||
|
SGMLError,
|
||||||
|
SGMLSpecial,
|
||||||
|
SGMLEntity,
|
||||||
|
SGMLComment,
|
||||||
|
SGMLParameterComment,
|
||||||
|
SGMLBlockDefault,
|
||||||
|
JavaScriptStart,
|
||||||
|
JavaScriptDefault,
|
||||||
|
JavaScriptComment,
|
||||||
|
JavaScriptCommentLine,
|
||||||
|
JavaScriptCommentDoc,
|
||||||
|
JavaScriptNumber,
|
||||||
|
JavaScriptWord,
|
||||||
|
JavaScriptKeyword,
|
||||||
|
JavaScriptDoubleQuotedString,
|
||||||
|
JavaScriptSingleQuotedString,
|
||||||
|
JavaScriptSymbol,
|
||||||
|
JavaScriptUnclosedString,
|
||||||
|
JavaScriptRegex,
|
||||||
|
ASPJavaScriptStart,
|
||||||
|
ASPJavaScriptDefault,
|
||||||
|
ASPJavaScriptComment,
|
||||||
|
ASPJavaScriptCommentLine,
|
||||||
|
ASPJavaScriptCommentDoc,
|
||||||
|
ASPJavaScriptNumber,
|
||||||
|
ASPJavaScriptWord,
|
||||||
|
ASPJavaScriptKeyword,
|
||||||
|
ASPJavaScriptDoubleQuotedString,
|
||||||
|
ASPJavaScriptSingleQuotedString,
|
||||||
|
ASPJavaScriptSymbol,
|
||||||
|
ASPJavaScriptUnclosedString,
|
||||||
|
ASPJavaScriptRegex,
|
||||||
|
VBScriptStart,
|
||||||
|
VBScriptDefault,
|
||||||
|
VBScriptComment,
|
||||||
|
VBScriptNumber,
|
||||||
|
VBScriptKeyword,
|
||||||
|
VBScriptString,
|
||||||
|
VBScriptIdentifier,
|
||||||
|
VBScriptUnclosedString,
|
||||||
|
ASPVBScriptStart,
|
||||||
|
ASPVBScriptDefault,
|
||||||
|
ASPVBScriptComment,
|
||||||
|
ASPVBScriptNumber,
|
||||||
|
ASPVBScriptKeyword,
|
||||||
|
ASPVBScriptString,
|
||||||
|
ASPVBScriptIdentifier,
|
||||||
|
ASPVBScriptUnclosedString,
|
||||||
|
PythonStart,
|
||||||
|
PythonDefault,
|
||||||
|
PythonComment,
|
||||||
|
PythonNumber,
|
||||||
|
PythonDoubleQuotedString,
|
||||||
|
PythonSingleQuotedString,
|
||||||
|
PythonKeyword,
|
||||||
|
PythonTripleSingleQuotedString,
|
||||||
|
PythonTripleDoubleQuotedString,
|
||||||
|
PythonClassName,
|
||||||
|
PythonFunctionMethodName,
|
||||||
|
PythonOperator,
|
||||||
|
PythonIdentifier,
|
||||||
|
ASPPythonStart,
|
||||||
|
ASPPythonDefault,
|
||||||
|
ASPPythonComment,
|
||||||
|
ASPPythonNumber,
|
||||||
|
ASPPythonDoubleQuotedString,
|
||||||
|
ASPPythonSingleQuotedString,
|
||||||
|
ASPPythonKeyword,
|
||||||
|
ASPPythonTripleSingleQuotedString,
|
||||||
|
ASPPythonTripleDoubleQuotedString,
|
||||||
|
ASPPythonClassName,
|
||||||
|
ASPPythonFunctionMethodName,
|
||||||
|
ASPPythonOperator,
|
||||||
|
ASPPythonIdentifier,
|
||||||
|
PHPDefault,
|
||||||
|
PHPDoubleQuotedString,
|
||||||
|
PHPSingleQuotedString,
|
||||||
|
PHPKeyword,
|
||||||
|
PHPNumber,
|
||||||
|
PHPVariable,
|
||||||
|
PHPComment,
|
||||||
|
PHPCommentLine,
|
||||||
|
PHPDoubleQuotedVariable,
|
||||||
|
PHPOperator
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerHTML(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerHTML();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
const char *autoCompletionFillups() const /Encoding="None"/;
|
||||||
|
bool caseSensitive() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool caseSensitiveTags() const;
|
||||||
|
void setDjangoTemplates(bool enable);
|
||||||
|
bool djangoTemplates() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldPreprocessor() const;
|
||||||
|
void setFoldScriptComments(bool fold);
|
||||||
|
bool foldScriptComments() const;
|
||||||
|
void setFoldScriptHeredocs(bool fold);
|
||||||
|
bool foldScriptHeredocs() const;
|
||||||
|
void setMakoTemplates(bool enable);
|
||||||
|
bool makoTemplates() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldPreprocessor(bool fold);
|
||||||
|
virtual void setCaseSensitiveTags(bool sens);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerHTML(const QsciLexerHTML &);
|
||||||
|
};
|
||||||
38
third_party/qscintilla/Python/sip/qscilexeridl.sip
vendored
Normal file
38
third_party/qscintilla/Python/sip/qscilexeridl.sip
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerIDL.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerIDL : QsciLexerCPP
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexeridl.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerIDL(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerIDL();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerIDL(const QsciLexerIDL &);
|
||||||
|
};
|
||||||
37
third_party/qscintilla/Python/sip/qscilexerintelhex.sip
vendored
Normal file
37
third_party/qscintilla/Python/sip/qscilexerintelhex.sip
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerIntelHex.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerIntelHex : QsciLexerHex
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerintelhex.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerIntelHex(QObject *parent = 0);
|
||||||
|
virtual ~QsciLexerIntelHex();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerIntelHex(const QsciLexerIntelHex &);
|
||||||
|
};
|
||||||
36
third_party/qscintilla/Python/sip/qscilexerjava.sip
vendored
Normal file
36
third_party/qscintilla/Python/sip/qscilexerjava.sip
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerJava.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerJava : QsciLexerCPP
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerjava.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerJava(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerJava();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerJava(const QsciLexerJava &);
|
||||||
|
};
|
||||||
41
third_party/qscintilla/Python/sip/qscilexerjavascript.sip
vendored
Normal file
41
third_party/qscintilla/Python/sip/qscilexerjavascript.sip
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerJavaScript.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerJavaScript : QsciLexerCPP
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerjavascript.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerJavaScript(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerJavaScript();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerJavaScript(const QsciLexerJavaScript &);
|
||||||
|
};
|
||||||
71
third_party/qscintilla/Python/sip/qscilexerjson.sip
vendored
Normal file
71
third_party/qscintilla/Python/sip/qscilexerjson.sip
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerJSON.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerJSON : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerjson.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
UnclosedString,
|
||||||
|
Property,
|
||||||
|
EscapeSequence,
|
||||||
|
CommentLine,
|
||||||
|
CommentBlock,
|
||||||
|
Operator,
|
||||||
|
IRI,
|
||||||
|
IRICompact,
|
||||||
|
Keyword,
|
||||||
|
KeywordLD,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerJSON(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerJSON();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
void setHighlightComments(bool highlight);
|
||||||
|
bool highlightComments() const;
|
||||||
|
void setHighlightEscapeSequences(bool highlight);
|
||||||
|
bool highlightEscapeSequences() const;
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs,const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs,const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerJSON(const QsciLexerJSON &);
|
||||||
|
};
|
||||||
79
third_party/qscintilla/Python/sip/qscilexerlua.sip
vendored
Normal file
79
third_party/qscintilla/Python/sip/qscilexerlua.sip
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerLua.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerLua : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerlua.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
LineComment,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
String,
|
||||||
|
Character,
|
||||||
|
LiteralString,
|
||||||
|
Preprocessor,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
UnclosedString,
|
||||||
|
BasicFunctions,
|
||||||
|
StringTableMathsFunctions,
|
||||||
|
CoroutinesIOSystemFacilities,
|
||||||
|
KeywordSet5,
|
||||||
|
KeywordSet6,
|
||||||
|
KeywordSet7,
|
||||||
|
KeywordSet8,
|
||||||
|
Label,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerLua(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerLua();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerLua(const QsciLexerLua &);
|
||||||
|
};
|
||||||
52
third_party/qscintilla/Python/sip/qscilexermakefile.sip
vendored
Normal file
52
third_party/qscintilla/Python/sip/qscilexermakefile.sip
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerMakefile.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerMakefile : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexermakefile.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Preprocessor,
|
||||||
|
Variable,
|
||||||
|
Operator,
|
||||||
|
Target,
|
||||||
|
Error
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerMakefile(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerMakefile();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerMakefile(const QsciLexerMakefile &);
|
||||||
|
};
|
||||||
65
third_party/qscintilla/Python/sip/qscilexermarkdown.sip
vendored
Normal file
65
third_party/qscintilla/Python/sip/qscilexermarkdown.sip
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerMarkdown.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerMarkdown : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexermarkdown.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Special,
|
||||||
|
StrongEmphasisAsterisks,
|
||||||
|
StrongEmphasisUnderscores,
|
||||||
|
EmphasisAsterisks,
|
||||||
|
EmphasisUnderscores,
|
||||||
|
Header1,
|
||||||
|
Header2,
|
||||||
|
Header3,
|
||||||
|
Header4,
|
||||||
|
Header5,
|
||||||
|
Header6,
|
||||||
|
Prechar,
|
||||||
|
UnorderedListItem,
|
||||||
|
OrderedListItem,
|
||||||
|
BlockQuote,
|
||||||
|
StrikeOut,
|
||||||
|
HorizontalRule,
|
||||||
|
Link,
|
||||||
|
CodeBackticks,
|
||||||
|
CodeDoubleBackticks,
|
||||||
|
CodeBlock,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerMarkdown(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerMarkdown();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerMarkdown(const QsciLexerMarkdown &);
|
||||||
|
};
|
||||||
36
third_party/qscintilla/Python/sip/qscilexermasm.sip
vendored
Normal file
36
third_party/qscintilla/Python/sip/qscilexermasm.sip
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerMASM.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerMASM : QsciLexerAsm
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexermasm.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerMASM(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerMASM();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerMASM(const QsciLexerMASM &);
|
||||||
|
};
|
||||||
52
third_party/qscintilla/Python/sip/qscilexermatlab.sip
vendored
Normal file
52
third_party/qscintilla/Python/sip/qscilexermatlab.sip
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerMatlab.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerMatlab : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexermatlab.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Command,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
SingleQuotedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
DoubleQuotedString
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerMatlab(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerMatlab();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerMatlab(const QsciLexerMatlab &);
|
||||||
|
};
|
||||||
36
third_party/qscintilla/Python/sip/qscilexernasm.sip
vendored
Normal file
36
third_party/qscintilla/Python/sip/qscilexernasm.sip
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerNASM.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerNASM : QsciLexerAsm
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexernasm.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerNASM(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerNASM();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerNASM(const QsciLexerNASM &);
|
||||||
|
};
|
||||||
37
third_party/qscintilla/Python/sip/qscilexeroctave.sip
vendored
Normal file
37
third_party/qscintilla/Python/sip/qscilexeroctave.sip
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerOctave.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerOctave : QsciLexerMatlab
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexeroctave.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerOctave(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerOctave();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerOctave(const QsciLexerOctave &);
|
||||||
|
};
|
||||||
82
third_party/qscintilla/Python/sip/qscilexerpascal.sip
vendored
Normal file
82
third_party/qscintilla/Python/sip/qscilexerpascal.sip
vendored
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPascal.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPascal : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerpascal.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Identifier,
|
||||||
|
Comment,
|
||||||
|
CommentParenthesis,
|
||||||
|
CommentLine,
|
||||||
|
PreProcessor,
|
||||||
|
PreProcessorParenthesis,
|
||||||
|
Number,
|
||||||
|
HexNumber,
|
||||||
|
Keyword,
|
||||||
|
SingleQuotedString,
|
||||||
|
UnclosedString,
|
||||||
|
Character,
|
||||||
|
Operator,
|
||||||
|
Asm,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPascal(QObject *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldPreprocessor() const;
|
||||||
|
|
||||||
|
void setSmartHighlighting(bool enabled);
|
||||||
|
bool smartHighlighting() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldPreprocessor(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPascal(const QsciLexerPascal &);
|
||||||
|
};
|
||||||
111
third_party/qscintilla/Python/sip/qscilexerperl.sip
vendored
Normal file
111
third_party/qscintilla/Python/sip/qscilexerperl.sip
vendored
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPerl.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPerl : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerperl.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Error,
|
||||||
|
Comment,
|
||||||
|
POD,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
Scalar,
|
||||||
|
Array,
|
||||||
|
Hash,
|
||||||
|
SymbolTable,
|
||||||
|
Regex,
|
||||||
|
Substitution,
|
||||||
|
Backticks,
|
||||||
|
DataSection,
|
||||||
|
HereDocumentDelimiter,
|
||||||
|
SingleQuotedHereDocument,
|
||||||
|
DoubleQuotedHereDocument,
|
||||||
|
BacktickHereDocument,
|
||||||
|
QuotedStringQ,
|
||||||
|
QuotedStringQQ,
|
||||||
|
QuotedStringQX,
|
||||||
|
QuotedStringQR,
|
||||||
|
QuotedStringQW,
|
||||||
|
PODVerbatim,
|
||||||
|
SubroutinePrototype,
|
||||||
|
FormatIdentifier,
|
||||||
|
FormatBody,
|
||||||
|
DoubleQuotedStringVar,
|
||||||
|
Translation,
|
||||||
|
RegexVar,
|
||||||
|
SubstitutionVar,
|
||||||
|
BackticksVar,
|
||||||
|
DoubleQuotedHereDocumentVar,
|
||||||
|
BacktickHereDocumentVar,
|
||||||
|
QuotedStringQQVar,
|
||||||
|
QuotedStringQXVar,
|
||||||
|
QuotedStringQRVar,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPerl(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerPerl();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
void setFoldAtElse(bool fold);
|
||||||
|
bool foldAtElse() const;
|
||||||
|
void setFoldPackages(bool fold);
|
||||||
|
bool foldPackages() const;
|
||||||
|
void setFoldPODBlocks(bool fold);
|
||||||
|
bool foldPODBlocks() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPerl(const QsciLexerPerl &);
|
||||||
|
};
|
||||||
69
third_party/qscintilla/Python/sip/qscilexerpo.sip
vendored
Normal file
69
third_party/qscintilla/Python/sip/qscilexerpo.sip
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPO.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPO : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerpo.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
MessageId,
|
||||||
|
MessageIdText,
|
||||||
|
MessageString,
|
||||||
|
MessageStringText,
|
||||||
|
MessageContext,
|
||||||
|
MessageContextText,
|
||||||
|
Fuzzy,
|
||||||
|
ProgrammerComment,
|
||||||
|
Reference,
|
||||||
|
Flags,
|
||||||
|
MessageIdTextEOL,
|
||||||
|
MessageStringTextEOL,
|
||||||
|
MessageContextTextEOL
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPO(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerPO();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPO(const QsciLexerPO &);
|
||||||
|
};
|
||||||
78
third_party/qscintilla/Python/sip/qscilexerpostscript.sip
vendored
Normal file
78
third_party/qscintilla/Python/sip/qscilexerpostscript.sip
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPostScript.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPostScript : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerpostscript.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
DSCComment,
|
||||||
|
DSCCommentValue,
|
||||||
|
Number,
|
||||||
|
Name,
|
||||||
|
Keyword,
|
||||||
|
Literal,
|
||||||
|
ImmediateEvalLiteral,
|
||||||
|
ArrayParenthesis,
|
||||||
|
DictionaryParenthesis,
|
||||||
|
ProcedureParenthesis,
|
||||||
|
Text,
|
||||||
|
HexString,
|
||||||
|
Base85String,
|
||||||
|
BadStringCharacter
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPostScript(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerPostScript();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool tokenize() const;
|
||||||
|
int level() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldAtElse() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setTokenize(bool tokenize);
|
||||||
|
virtual void setLevel(int level);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldAtElse(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPostScript(const QsciLexerPostScript &);
|
||||||
|
};
|
||||||
79
third_party/qscintilla/Python/sip/qscilexerpov.sip
vendored
Normal file
79
third_party/qscintilla/Python/sip/qscilexerpov.sip
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPOV.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPOV : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerpov.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
Number,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
String,
|
||||||
|
UnclosedString,
|
||||||
|
Directive,
|
||||||
|
BadDirective,
|
||||||
|
ObjectsCSGAppearance,
|
||||||
|
TypesModifiersItems,
|
||||||
|
PredefinedIdentifiers,
|
||||||
|
PredefinedFunctions,
|
||||||
|
KeywordSet6,
|
||||||
|
KeywordSet7,
|
||||||
|
KeywordSet8
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPOV(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerPOV();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldDirectives() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldDirectives(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPOV(const QsciLexerPOV &);
|
||||||
|
};
|
||||||
63
third_party/qscintilla/Python/sip/qscilexerproperties.sip
vendored
Normal file
63
third_party/qscintilla/Python/sip/qscilexerproperties.sip
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerProperties.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerProperties : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerproperties.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Section,
|
||||||
|
Assignment,
|
||||||
|
DefaultValue,
|
||||||
|
Key
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerProperties(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerProperties();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldCompact() const;
|
||||||
|
void setInitialSpaces(bool enable);
|
||||||
|
bool initialSpaces() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerProperties(const QsciLexerProperties &);
|
||||||
|
};
|
||||||
105
third_party/qscintilla/Python/sip/qscilexerpython.sip
vendored
Normal file
105
third_party/qscintilla/Python/sip/qscilexerpython.sip
vendored
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerPython.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerPython : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerpython.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Number,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
Keyword,
|
||||||
|
TripleSingleQuotedString,
|
||||||
|
TripleDoubleQuotedString,
|
||||||
|
ClassName,
|
||||||
|
FunctionMethodName,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
CommentBlock,
|
||||||
|
UnclosedString,
|
||||||
|
HighlightedIdentifier,
|
||||||
|
Decorator,
|
||||||
|
DoubleQuotedFString,
|
||||||
|
SingleQuotedFString,
|
||||||
|
TripleSingleQuotedFString,
|
||||||
|
TripleDoubleQuotedFString,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IndentationWarning {
|
||||||
|
NoWarning,
|
||||||
|
Inconsistent,
|
||||||
|
TabsAfterSpaces,
|
||||||
|
Spaces,
|
||||||
|
Tabs
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerPython(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerPython();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
QStringList autoCompletionWordSeparators() const;
|
||||||
|
int blockLookback() const;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
int indentationGuideView() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldQuotes() const;
|
||||||
|
QsciLexerPython::IndentationWarning indentationWarning() const;
|
||||||
|
void setHighlightSubidentifiers(bool enabled);
|
||||||
|
bool highlightSubidentifiers() const;
|
||||||
|
void setStringsOverNewlineAllowed(bool allowed);
|
||||||
|
bool stringsOverNewlineAllowed() const;
|
||||||
|
void setV2UnicodeAllowed(bool allowed);
|
||||||
|
bool v2UnicodeAllowed() const;
|
||||||
|
void setV3BinaryOctalAllowed(bool allowed);
|
||||||
|
bool v3BinaryOctalAllowed() const;
|
||||||
|
void setV3BytesAllowed(bool allowed);
|
||||||
|
bool v3BytesAllowed() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldQuotes(bool fold);
|
||||||
|
virtual void setIndentationWarning(QsciLexerPython::IndentationWarning warn);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerPython(const QsciLexerPython &);
|
||||||
|
};
|
||||||
91
third_party/qscintilla/Python/sip/qscilexerruby.sip
vendored
Normal file
91
third_party/qscintilla/Python/sip/qscilexerruby.sip
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerRuby.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerRuby : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerruby.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Error,
|
||||||
|
Comment,
|
||||||
|
POD,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
ClassName,
|
||||||
|
FunctionMethodName,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
Regex,
|
||||||
|
Global,
|
||||||
|
Symbol,
|
||||||
|
ModuleName,
|
||||||
|
InstanceVariable,
|
||||||
|
ClassVariable,
|
||||||
|
Backticks,
|
||||||
|
DataSection,
|
||||||
|
HereDocumentDelimiter,
|
||||||
|
HereDocument,
|
||||||
|
PercentStringq,
|
||||||
|
PercentStringQ,
|
||||||
|
PercentStringx,
|
||||||
|
PercentStringr,
|
||||||
|
PercentStringw,
|
||||||
|
DemotedKeyword,
|
||||||
|
Stdin,
|
||||||
|
Stdout,
|
||||||
|
Stderr
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerRuby(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerRuby();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
const char *blockEnd(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStart(int *style = 0) const /Encoding="None"/;
|
||||||
|
const char *blockStartKeyword(int *style = 0) const /Encoding="None"/;
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
void setFoldComments(bool fold);
|
||||||
|
bool foldComments() const;
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerRuby(const QsciLexerRuby &);
|
||||||
|
};
|
||||||
54
third_party/qscintilla/Python/sip/qscilexerspice.sip
vendored
Normal file
54
third_party/qscintilla/Python/sip/qscilexerspice.sip
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerSpice.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerSpice : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerspice.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Identifier,
|
||||||
|
Command,
|
||||||
|
Function,
|
||||||
|
Parameter,
|
||||||
|
Number,
|
||||||
|
Delimiter,
|
||||||
|
Value,
|
||||||
|
Comment
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerSpice(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerSpice();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerSpice(const QsciLexerSpice &);
|
||||||
|
};
|
||||||
93
third_party/qscintilla/Python/sip/qscilexersql.sip
vendored
Normal file
93
third_party/qscintilla/Python/sip/qscilexersql.sip
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerSQL.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerSQL : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexersql.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
CommentDoc,
|
||||||
|
Number,
|
||||||
|
Keyword,
|
||||||
|
DoubleQuotedString,
|
||||||
|
SingleQuotedString,
|
||||||
|
PlusKeyword,
|
||||||
|
PlusPrompt,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
PlusComment,
|
||||||
|
CommentLineHash,
|
||||||
|
CommentDocKeyword,
|
||||||
|
CommentDocKeywordError,
|
||||||
|
KeywordSet5,
|
||||||
|
KeywordSet6,
|
||||||
|
KeywordSet7,
|
||||||
|
KeywordSet8,
|
||||||
|
QuotedIdentifier,
|
||||||
|
QuotedOperator,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerSQL(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerSQL();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool backslashEscapes() const;
|
||||||
|
void setDottedWords(bool enable);
|
||||||
|
bool dottedWords() const;
|
||||||
|
void setFoldAtElse(bool fold);
|
||||||
|
bool foldAtElse() const;
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
void setFoldOnlyBegin(bool fold);
|
||||||
|
bool foldOnlyBegin() const;
|
||||||
|
void setHashComments(bool enable);
|
||||||
|
bool hashComments() const;
|
||||||
|
void setQuotedIdentifiers(bool enable);
|
||||||
|
bool quotedIdentifiers() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setBackslashEscapes(bool enable);
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerSQL(const QsciLexerSQL &);
|
||||||
|
};
|
||||||
37
third_party/qscintilla/Python/sip/qscilexersrec.sip
vendored
Normal file
37
third_party/qscintilla/Python/sip/qscilexersrec.sip
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerSRec.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerSRec : QsciLexerHex
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexersrec.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerSRec(QObject *parent = 0);
|
||||||
|
virtual ~QsciLexerSRec();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerSRec(const QsciLexerSRec &);
|
||||||
|
};
|
||||||
77
third_party/qscintilla/Python/sip/qscilexertcl.sip
vendored
Normal file
77
third_party/qscintilla/Python/sip/qscilexertcl.sip
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerTCL.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerTCL : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexertcl.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
Number,
|
||||||
|
QuotedKeyword,
|
||||||
|
QuotedString,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
Substitution,
|
||||||
|
SubstitutionBrace,
|
||||||
|
Modifier,
|
||||||
|
ExpandKeyword,
|
||||||
|
TCLKeyword,
|
||||||
|
TkKeyword,
|
||||||
|
ITCLKeyword,
|
||||||
|
TkCommand,
|
||||||
|
KeywordSet6,
|
||||||
|
KeywordSet7,
|
||||||
|
KeywordSet8,
|
||||||
|
KeywordSet9,
|
||||||
|
CommentBox,
|
||||||
|
CommentBlock
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerTCL(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerTCL();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
void setFoldComments(bool fold);
|
||||||
|
bool foldComments() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerTCL(const QsciLexerTCL &);
|
||||||
|
};
|
||||||
37
third_party/qscintilla/Python/sip/qscilexertekhex.sip
vendored
Normal file
37
third_party/qscintilla/Python/sip/qscilexertekhex.sip
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerTekHex.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerTekHex : QsciLexerHex
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexertekhex.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerTekHex(QObject *parent = 0);
|
||||||
|
virtual ~QsciLexerTekHex();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerTekHex(const QsciLexerTekHex &);
|
||||||
|
};
|
||||||
63
third_party/qscintilla/Python/sip/qscilexertex.sip
vendored
Normal file
63
third_party/qscintilla/Python/sip/qscilexertex.sip
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerTeX.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerTeX : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexertex.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Special,
|
||||||
|
Group,
|
||||||
|
Symbol,
|
||||||
|
Command,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerTeX(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerTeX();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
void setFoldComments(bool fold);
|
||||||
|
bool foldComments() const;
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
void setProcessComments(bool enable);
|
||||||
|
bool processComments() const;
|
||||||
|
void setProcessIf(bool enable);
|
||||||
|
bool processIf() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerTeX(const QsciLexerTeX &);
|
||||||
|
};
|
||||||
106
third_party/qscintilla/Python/sip/qscilexerverilog.sip
vendored
Normal file
106
third_party/qscintilla/Python/sip/qscilexerverilog.sip
vendored
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerVerilog.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerVerilog : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerverilog.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
InactiveDefault,
|
||||||
|
Comment,
|
||||||
|
InactiveComment,
|
||||||
|
CommentLine,
|
||||||
|
InactiveCommentLine,
|
||||||
|
CommentBang,
|
||||||
|
InactiveCommentBang,
|
||||||
|
Number,
|
||||||
|
InactiveNumber,
|
||||||
|
Keyword,
|
||||||
|
InactiveKeyword,
|
||||||
|
String,
|
||||||
|
InactiveString,
|
||||||
|
KeywordSet2,
|
||||||
|
InactiveKeywordSet2,
|
||||||
|
SystemTask,
|
||||||
|
InactiveSystemTask,
|
||||||
|
Preprocessor,
|
||||||
|
InactivePreprocessor,
|
||||||
|
Operator,
|
||||||
|
InactiveOperator,
|
||||||
|
Identifier,
|
||||||
|
InactiveIdentifier,
|
||||||
|
UnclosedString,
|
||||||
|
InactiveUnclosedString,
|
||||||
|
UserKeywordSet,
|
||||||
|
InactiveUserKeywordSet,
|
||||||
|
CommentKeyword,
|
||||||
|
InactiveCommentKeyword,
|
||||||
|
DeclareInputPort,
|
||||||
|
InactiveDeclareInputPort,
|
||||||
|
DeclareOutputPort,
|
||||||
|
InactiveDeclareOutputPort,
|
||||||
|
DeclareInputOutputPort,
|
||||||
|
InactiveDeclareInputOutputPort,
|
||||||
|
PortConnection,
|
||||||
|
InactivePortConnection,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerVerilog(QObject *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
|
||||||
|
void setFoldAtElse(bool fold);
|
||||||
|
bool foldAtElse() const;
|
||||||
|
|
||||||
|
void setFoldComments(bool fold);
|
||||||
|
bool foldComments() const;
|
||||||
|
|
||||||
|
void setFoldCompact(bool fold);
|
||||||
|
bool foldCompact() const;
|
||||||
|
|
||||||
|
void setFoldPreprocessor(bool fold);
|
||||||
|
bool foldPreprocessor() const;
|
||||||
|
|
||||||
|
void setFoldAtModule(bool fold);
|
||||||
|
bool foldAtModule() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerVerilog(const QsciLexerVerilog &);
|
||||||
|
};
|
||||||
81
third_party/qscintilla/Python/sip/qscilexervhdl.sip
vendored
Normal file
81
third_party/qscintilla/Python/sip/qscilexervhdl.sip
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerVHDL.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerVHDL : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexervhdl.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
CommentLine,
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
Operator,
|
||||||
|
Identifier,
|
||||||
|
UnclosedString,
|
||||||
|
Keyword,
|
||||||
|
StandardOperator,
|
||||||
|
Attribute,
|
||||||
|
StandardFunction,
|
||||||
|
StandardPackage,
|
||||||
|
StandardType,
|
||||||
|
KeywordSet7,
|
||||||
|
CommentBlock
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerVHDL(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerVHDL();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
int braceStyle() const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
bool foldCompact() const;
|
||||||
|
bool foldAtElse() const;
|
||||||
|
bool foldAtBegin() const;
|
||||||
|
bool foldAtParenthesis() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
virtual void setFoldCompact(bool fold);
|
||||||
|
virtual void setFoldAtElse(bool fold);
|
||||||
|
virtual void setFoldAtBegin(bool fold);
|
||||||
|
virtual void setFoldAtParenthesis(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerVHDL(const QsciLexerVHDL &);
|
||||||
|
};
|
||||||
49
third_party/qscintilla/Python/sip/qscilexerxml.sip
vendored
Normal file
49
third_party/qscintilla/Python/sip/qscilexerxml.sip
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerXML.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerXML : QsciLexerHTML
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexerxml.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciLexerXML(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerXML();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
void setScriptsStyled(bool styled);
|
||||||
|
bool scriptsStyled() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerXML(const QsciLexerXML &);
|
||||||
|
};
|
||||||
65
third_party/qscintilla/Python/sip/qscilexeryaml.sip
vendored
Normal file
65
third_party/qscintilla/Python/sip/qscilexeryaml.sip
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// This is the SIP interface definition for QsciLexerYAML.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciLexerYAML : QsciLexer
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscilexeryaml.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Default,
|
||||||
|
Comment,
|
||||||
|
Identifier,
|
||||||
|
Keyword,
|
||||||
|
Number,
|
||||||
|
Reference,
|
||||||
|
DocumentDelimiter,
|
||||||
|
TextBlockMarker,
|
||||||
|
SyntaxErrorMarker,
|
||||||
|
Operator
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciLexerYAML(QObject *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciLexerYAML();
|
||||||
|
|
||||||
|
const char *language() const;
|
||||||
|
const char *lexer() const;
|
||||||
|
QColor defaultColor(int style) const;
|
||||||
|
bool defaultEolFill(int style) const;
|
||||||
|
QFont defaultFont(int style) const;
|
||||||
|
QColor defaultPaper(int style) const;
|
||||||
|
const char *keywords(int set) const;
|
||||||
|
QString description(int style) const;
|
||||||
|
|
||||||
|
void refreshProperties();
|
||||||
|
bool foldComments() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setFoldComments(bool fold);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool readProperties(QSettings &qs, const QString &prefix);
|
||||||
|
bool writeProperties(QSettings &qs, const QString &prefix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciLexerYAML(const QsciLexerYAML &);
|
||||||
|
};
|
||||||
44
third_party/qscintilla/Python/sip/qscimacro.sip
vendored
Normal file
44
third_party/qscintilla/Python/sip/qscimacro.sip
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// This is the SIP interface definition for QsciMacro.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciMacro : QObject
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscimacro.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciMacro(QsciScintilla *parent /TransferThis/);
|
||||||
|
QsciMacro(const QString &asc, QsciScintilla *parent /TransferThis/);
|
||||||
|
|
||||||
|
virtual ~QsciMacro();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
bool load(const QString &asc);
|
||||||
|
QString save() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void play();
|
||||||
|
virtual void startRecording();
|
||||||
|
virtual void endRecording();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciMacro(const QsciMacro &);
|
||||||
|
};
|
||||||
23
third_party/qscintilla/Python/sip/qscimod5.sip
vendored
Normal file
23
third_party/qscintilla/Python/sip/qscimod5.sip
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// This is the SIP interface definition for the Qsci module of PyQt5.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
%Module(name=PyQt5.Qsci, keyword_arguments="Optional", use_limited_api=True)
|
||||||
|
|
||||||
|
%Include qscimodcommon.sip
|
||||||
23
third_party/qscintilla/Python/sip/qscimod6.sip
vendored
Normal file
23
third_party/qscintilla/Python/sip/qscimod6.sip
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// This is the SIP interface definition for the Qsci module of PyQt6.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
%Module(name=PyQt6.Qsci, keyword_arguments="Optional", use_limited_api=True)
|
||||||
|
|
||||||
|
%Include qscimodcommon.sip
|
||||||
112
third_party/qscintilla/Python/sip/qscimodcommon.sip
vendored
Normal file
112
third_party/qscintilla/Python/sip/qscimodcommon.sip
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
// This is the SIP interface definition for the parts of the Qsci module common
|
||||||
|
// to PyQt5 and PyQt6.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
%Copying
|
||||||
|
Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
|
||||||
|
This file is part of QScintilla.
|
||||||
|
|
||||||
|
This file may be used under the terms of the GNU General Public License
|
||||||
|
version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
following information to ensure the GNU General Public License version 3.0
|
||||||
|
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
|
||||||
|
If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
then you may purchase a commercial license. For more information contact
|
||||||
|
info@riverbankcomputing.com.
|
||||||
|
|
||||||
|
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
%Import QtCore/QtCoremod.sip
|
||||||
|
%Import QtGui/QtGuimod.sip
|
||||||
|
%Import QtWidgets/QtWidgetsmod.sip
|
||||||
|
|
||||||
|
%If (PyQt_Printer)
|
||||||
|
%Import QtPrintSupport/QtPrintSupportmod.sip
|
||||||
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
const int QSCINTILLA_VERSION;
|
||||||
|
const char *QSCINTILLA_VERSION_STR;
|
||||||
|
|
||||||
|
|
||||||
|
%Include qsciscintillabase.sip
|
||||||
|
%Include qsciscintilla.sip
|
||||||
|
%Include qsciabstractapis.sip
|
||||||
|
%Include qsciapis.sip
|
||||||
|
%Include qscicommand.sip
|
||||||
|
%Include qscicommandset.sip
|
||||||
|
%Include qscidocument.sip
|
||||||
|
%Include qscilexer.sip
|
||||||
|
%Include qscilexerasm.sip
|
||||||
|
%Include qscilexeravs.sip
|
||||||
|
%Include qscilexerbash.sip
|
||||||
|
%Include qscilexerbatch.sip
|
||||||
|
%Include qscilexercmake.sip
|
||||||
|
%Include qscilexercoffeescript.sip
|
||||||
|
%Include qscilexercpp.sip
|
||||||
|
%Include qscilexercsharp.sip
|
||||||
|
%Include qscilexercss.sip
|
||||||
|
%Include qscilexercustom.sip
|
||||||
|
%Include qscilexerd.sip
|
||||||
|
%Include qscilexerdiff.sip
|
||||||
|
%Include qscilexerfortran.sip
|
||||||
|
%Include qscilexerfortran77.sip
|
||||||
|
%Include qscilexerhex.sip
|
||||||
|
%Include qscilexerhtml.sip
|
||||||
|
%Include qscilexeridl.sip
|
||||||
|
%Include qscilexerintelhex.sip
|
||||||
|
%Include qscilexerjava.sip
|
||||||
|
%Include qscilexerjavascript.sip
|
||||||
|
%Include qscilexerjson.sip
|
||||||
|
%Include qscilexerlua.sip
|
||||||
|
%Include qscilexermakefile.sip
|
||||||
|
%Include qscilexermarkdown.sip
|
||||||
|
%Include qscilexermasm.sip
|
||||||
|
%Include qscilexermatlab.sip
|
||||||
|
%Include qscilexernasm.sip
|
||||||
|
%Include qscilexeroctave.sip
|
||||||
|
%Include qscilexerpascal.sip
|
||||||
|
%Include qscilexerperl.sip
|
||||||
|
%Include qscilexerpostscript.sip
|
||||||
|
%Include qscilexerpo.sip
|
||||||
|
%Include qscilexerpov.sip
|
||||||
|
%Include qscilexerproperties.sip
|
||||||
|
%Include qscilexerpython.sip
|
||||||
|
%Include qscilexerruby.sip
|
||||||
|
%Include qscilexerspice.sip
|
||||||
|
%Include qscilexersql.sip
|
||||||
|
%Include qscilexersrec.sip
|
||||||
|
%Include qscilexertcl.sip
|
||||||
|
%Include qscilexertekhex.sip
|
||||||
|
%Include qscilexertex.sip
|
||||||
|
%Include qscilexerverilog.sip
|
||||||
|
%Include qscilexervhdl.sip
|
||||||
|
%Include qscilexerxml.sip
|
||||||
|
%Include qscilexeryaml.sip
|
||||||
|
%Include qscimacro.sip
|
||||||
|
%Include qsciprinter.sip
|
||||||
|
%Include qscistyle.sip
|
||||||
|
%Include qscistyledtext.sip
|
||||||
47
third_party/qscintilla/Python/sip/qsciprinter.sip
vendored
Normal file
47
third_party/qscintilla/Python/sip/qsciprinter.sip
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// This is the SIP interface definition for QsciPrinter.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
%If (PyQt_Printer)
|
||||||
|
|
||||||
|
class QsciPrinter : QPrinter
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qsciprinter.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciPrinter(QPrinter::PrinterMode mode = QPrinter::ScreenResolution);
|
||||||
|
virtual ~QsciPrinter();
|
||||||
|
|
||||||
|
virtual void formatPage(QPainter &painter, bool drawing, QRect &area,
|
||||||
|
int pagenr);
|
||||||
|
int magnification() const;
|
||||||
|
virtual void setMagnification(int magnification);
|
||||||
|
virtual int printRange(QsciScintillaBase *qsb, QPainter &painter,
|
||||||
|
int from = -1, int to = -1);
|
||||||
|
virtual int printRange(QsciScintillaBase *qsb, int from = -1, int to = -1);
|
||||||
|
QsciScintilla::WrapMode wrapMode() const;
|
||||||
|
virtual void setWrapMode(QsciScintilla::WrapMode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciPrinter(const QsciPrinter &);
|
||||||
|
};
|
||||||
|
|
||||||
|
%End
|
||||||
557
third_party/qscintilla/Python/sip/qsciscintilla.sip
vendored
Normal file
557
third_party/qscintilla/Python/sip/qsciscintilla.sip
vendored
Normal file
@@ -0,0 +1,557 @@
|
|||||||
|
// This is the SIP interface definition for QsciScintilla.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciScintilla : QsciScintillaBase
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
AiMaintain,
|
||||||
|
AiOpening,
|
||||||
|
AiClosing
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AnnotationDisplay {
|
||||||
|
AnnotationHidden,
|
||||||
|
AnnotationStandard,
|
||||||
|
AnnotationBoxed,
|
||||||
|
AnnotationIndented,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AutoCompletionSource {
|
||||||
|
AcsNone,
|
||||||
|
AcsAll,
|
||||||
|
AcsDocument,
|
||||||
|
AcsAPIs
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AutoCompletionUseSingle {
|
||||||
|
AcusNever,
|
||||||
|
AcusExplicit,
|
||||||
|
AcusAlways
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BraceMatch {
|
||||||
|
NoBraceMatch,
|
||||||
|
StrictBraceMatch,
|
||||||
|
SloppyBraceMatch
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CallTipsPosition {
|
||||||
|
CallTipsBelowText,
|
||||||
|
CallTipsAboveText,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CallTipsStyle {
|
||||||
|
CallTipsNone,
|
||||||
|
CallTipsNoContext,
|
||||||
|
CallTipsNoAutoCompletionContext,
|
||||||
|
CallTipsContext
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EdgeMode {
|
||||||
|
EdgeNone,
|
||||||
|
EdgeLine,
|
||||||
|
EdgeBackground,
|
||||||
|
EdgeMultipleLines,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EolMode {
|
||||||
|
EolWindows,
|
||||||
|
EolUnix,
|
||||||
|
EolMac
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FoldStyle {
|
||||||
|
NoFoldStyle,
|
||||||
|
PlainFoldStyle,
|
||||||
|
CircledFoldStyle,
|
||||||
|
BoxedFoldStyle,
|
||||||
|
CircledTreeFoldStyle,
|
||||||
|
BoxedTreeFoldStyle
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IndicatorStyle {
|
||||||
|
PlainIndicator,
|
||||||
|
SquiggleIndicator,
|
||||||
|
TTIndicator,
|
||||||
|
DiagonalIndicator,
|
||||||
|
StrikeIndicator,
|
||||||
|
HiddenIndicator,
|
||||||
|
BoxIndicator,
|
||||||
|
RoundBoxIndicator,
|
||||||
|
StraightBoxIndicator,
|
||||||
|
FullBoxIndicator,
|
||||||
|
DashesIndicator,
|
||||||
|
DotsIndicator,
|
||||||
|
SquiggleLowIndicator,
|
||||||
|
DotBoxIndicator,
|
||||||
|
SquigglePixmapIndicator,
|
||||||
|
ThickCompositionIndicator,
|
||||||
|
ThinCompositionIndicator,
|
||||||
|
TextColorIndicator,
|
||||||
|
TriangleIndicator,
|
||||||
|
TriangleCharacterIndicator,
|
||||||
|
GradientIndicator,
|
||||||
|
CentreGradientIndicator,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MoNone,
|
||||||
|
MoSublineSelect,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MarginType {
|
||||||
|
SymbolMargin,
|
||||||
|
SymbolMarginDefaultForegroundColor,
|
||||||
|
SymbolMarginDefaultBackgroundColor,
|
||||||
|
NumberMargin,
|
||||||
|
TextMargin,
|
||||||
|
TextMarginRightJustified,
|
||||||
|
SymbolMarginColor,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MarkerSymbol {
|
||||||
|
Circle,
|
||||||
|
Rectangle,
|
||||||
|
RightTriangle,
|
||||||
|
SmallRectangle,
|
||||||
|
RightArrow,
|
||||||
|
Invisible,
|
||||||
|
DownTriangle,
|
||||||
|
Minus,
|
||||||
|
Plus,
|
||||||
|
VerticalLine,
|
||||||
|
BottomLeftCorner,
|
||||||
|
LeftSideSplitter,
|
||||||
|
BoxedPlus,
|
||||||
|
BoxedPlusConnected,
|
||||||
|
BoxedMinus,
|
||||||
|
BoxedMinusConnected,
|
||||||
|
RoundedBottomLeftCorner,
|
||||||
|
LeftSideRoundedSplitter,
|
||||||
|
CircledPlus,
|
||||||
|
CircledPlusConnected,
|
||||||
|
CircledMinus,
|
||||||
|
CircledMinusConnected,
|
||||||
|
Background,
|
||||||
|
ThreeDots,
|
||||||
|
ThreeRightArrows,
|
||||||
|
FullRectangle,
|
||||||
|
LeftRectangle,
|
||||||
|
Underline,
|
||||||
|
Bookmark
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TabDrawMode {
|
||||||
|
TabLongArrow,
|
||||||
|
TabStrikeOut,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WhitespaceVisibility {
|
||||||
|
WsInvisible,
|
||||||
|
WsVisible,
|
||||||
|
WsVisibleAfterIndent,
|
||||||
|
WsVisibleOnlyInIndent,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WrapMode {
|
||||||
|
WrapNone,
|
||||||
|
WrapWord,
|
||||||
|
WrapCharacter,
|
||||||
|
WrapWhitespace,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WrapVisualFlag {
|
||||||
|
WrapFlagNone,
|
||||||
|
WrapFlagByText,
|
||||||
|
WrapFlagByBorder,
|
||||||
|
WrapFlagInMargin,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WrapIndentMode {
|
||||||
|
WrapIndentFixed,
|
||||||
|
WrapIndentSame,
|
||||||
|
WrapIndentIndented,
|
||||||
|
WrapIndentDeeplyIndented,
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciScintilla(QWidget *parent /TransferThis/ = 0);
|
||||||
|
virtual ~QsciScintilla();
|
||||||
|
|
||||||
|
virtual QStringList apiContext(int pos, int &context_start,
|
||||||
|
int &last_word_start);
|
||||||
|
|
||||||
|
void annotate(int line, const QString &text, int style);
|
||||||
|
void annotate(int line, const QString &text, const QsciStyle &style);
|
||||||
|
void annotate(int line, const QsciStyledText &text);
|
||||||
|
void annotate(int line, const QList<QsciStyledText> &text);
|
||||||
|
QString annotation(int line) const;
|
||||||
|
AnnotationDisplay annotationDisplay() const;
|
||||||
|
void clearAnnotations(int line = -1);
|
||||||
|
|
||||||
|
bool autoCompletionCaseSensitivity() const;
|
||||||
|
bool autoCompletionFillupsEnabled() const;
|
||||||
|
bool autoCompletionReplaceWord() const;
|
||||||
|
bool autoCompletionShowSingle() const;
|
||||||
|
AutoCompletionSource autoCompletionSource() const;
|
||||||
|
int autoCompletionThreshold() const;
|
||||||
|
AutoCompletionUseSingle autoCompletionUseSingle() const;
|
||||||
|
bool autoIndent() const;
|
||||||
|
|
||||||
|
bool backspaceUnindents() const;
|
||||||
|
void beginUndoAction();
|
||||||
|
BraceMatch braceMatching() const;
|
||||||
|
QByteArray bytes(int start, int end) const;
|
||||||
|
|
||||||
|
CallTipsPosition callTipsPosition() const;
|
||||||
|
CallTipsStyle callTipsStyle() const;
|
||||||
|
int callTipsVisible() const;
|
||||||
|
void cancelFind();
|
||||||
|
void cancelList();
|
||||||
|
bool caseSensitive() const;
|
||||||
|
void clearRegisteredImages();
|
||||||
|
QColor color() const;
|
||||||
|
QList<int> contractedFolds() const;
|
||||||
|
void convertEols(EolMode mode);
|
||||||
|
QMenu *createStandardContextMenu() /Factory/;
|
||||||
|
|
||||||
|
QsciDocument document() const;
|
||||||
|
|
||||||
|
void endUndoAction();
|
||||||
|
QColor edgeColor() const;
|
||||||
|
int edgeColumn() const;
|
||||||
|
EdgeMode edgeMode() const;
|
||||||
|
EolMode eolMode() const;
|
||||||
|
bool eolVisibility() const;
|
||||||
|
|
||||||
|
int extraAscent() const;
|
||||||
|
int extraDescent() const;
|
||||||
|
|
||||||
|
virtual bool findFirst(const QString &expr, bool re, bool cs, bool wo,
|
||||||
|
bool wrap, bool forward = true, int line = -1, int index = -1,
|
||||||
|
bool show = true, bool posix = false, bool cxx11 = false);
|
||||||
|
virtual bool findFirstInSelection(const QString &expr, bool re, bool cs,
|
||||||
|
bool wo, bool forward = true, bool show = true,
|
||||||
|
bool posix = false, bool cxx11 = false);
|
||||||
|
virtual bool findNext();
|
||||||
|
bool findMatchingBrace(long &brace, long &other, BraceMatch mode);
|
||||||
|
int firstVisibleLine() const;
|
||||||
|
FoldStyle folding() const;
|
||||||
|
|
||||||
|
void getCursorPosition(int *line, int *index) const;
|
||||||
|
void getSelection(int *lineFrom, int *indexFrom, int *lineTo,
|
||||||
|
int *indexTo) const;
|
||||||
|
|
||||||
|
bool hasSelectedText() const;
|
||||||
|
|
||||||
|
int indentation(int line) const;
|
||||||
|
bool indentationGuides() const;
|
||||||
|
bool indentationsUseTabs() const;
|
||||||
|
int indentationWidth() const;
|
||||||
|
|
||||||
|
void clearIndicatorRange(int lineFrom, int indexFrom, int lineTo,
|
||||||
|
int indexTo, int indicatorNumber);
|
||||||
|
void fillIndicatorRange(int lineFrom, int indexFrom, int lineTo,
|
||||||
|
int indexTo, int indicatorNumber);
|
||||||
|
int indicatorDefine(IndicatorStyle style, int indicatorNumber = -1);
|
||||||
|
bool indicatorDrawUnder(int indicatorNumber) const;
|
||||||
|
|
||||||
|
bool isCallTipActive() const;
|
||||||
|
bool isListActive() const;
|
||||||
|
bool isModified() const;
|
||||||
|
bool isReadOnly() const;
|
||||||
|
bool isRedoAvailable() const;
|
||||||
|
bool isUndoAvailable() const;
|
||||||
|
bool isUtf8() const;
|
||||||
|
bool isWordCharacter(char ch) const;
|
||||||
|
|
||||||
|
int lineAt(const QPoint &pos) const;
|
||||||
|
void lineIndexFromPosition(int position, int *line, int *index) const;
|
||||||
|
int lineLength(int line) const;
|
||||||
|
int lines() const;
|
||||||
|
int length() const;
|
||||||
|
QsciLexer *lexer() const;
|
||||||
|
|
||||||
|
QColor marginBackgroundColor(int margin) const;
|
||||||
|
bool marginLineNumbers(int margin) const;
|
||||||
|
int marginMarkerMask(int margin) const;
|
||||||
|
int marginOptions() const;
|
||||||
|
bool marginSensitivity(int margin) const;
|
||||||
|
MarginType marginType(int margin) const;
|
||||||
|
int marginWidth(int margin) const;
|
||||||
|
int margins() const;
|
||||||
|
|
||||||
|
int markerDefine(MarkerSymbol sym, int markerNumber = -1);
|
||||||
|
int markerDefine(char ch, int markerNumber = -1);
|
||||||
|
int markerDefine(const QPixmap &pm, int markerNumber = -1);
|
||||||
|
int markerDefine(const QImage &im, int markerNumber = -1);
|
||||||
|
int markerAdd(int linenr, int markerNumber);
|
||||||
|
unsigned markersAtLine(int linenr) const;
|
||||||
|
void markerDelete(int linenr, int markerNumber = -1);
|
||||||
|
void markerDeleteAll(int markerNumber = -1);
|
||||||
|
void markerDeleteHandle(int mhandle);
|
||||||
|
int markerLine(int mhandle) const;
|
||||||
|
int markerFindNext(int linenr, unsigned mask) const;
|
||||||
|
int markerFindPrevious(int linenr, unsigned mask) const;
|
||||||
|
|
||||||
|
bool overwriteMode() const;
|
||||||
|
|
||||||
|
QColor paper() const;
|
||||||
|
int positionFromLineIndex(int line, int index) const;
|
||||||
|
|
||||||
|
bool read(QIODevice *io) /ReleaseGIL/;
|
||||||
|
virtual void recolor(int start = 0, int end = -1);
|
||||||
|
void registerImage(int id, const QPixmap &pm);
|
||||||
|
void registerImage(int id, const QImage &im);
|
||||||
|
virtual void replace(const QString &replaceStr);
|
||||||
|
void resetFoldMarginColors();
|
||||||
|
void resetHotspotBackgroundColor();
|
||||||
|
void resetHotspotForegroundColor();
|
||||||
|
|
||||||
|
int scrollWidth() const;
|
||||||
|
void setScrollWidth(int pixelWidth);
|
||||||
|
bool scrollWidthTracking() const;
|
||||||
|
void setScrollWidthTracking(bool enabled);
|
||||||
|
|
||||||
|
void setFoldMarginColors(const QColor &fore, const QColor &back);
|
||||||
|
|
||||||
|
void setAnnotationDisplay(AnnotationDisplay display);
|
||||||
|
|
||||||
|
void setAutoCompletionFillupsEnabled(bool enabled);
|
||||||
|
void setAutoCompletionFillups(const char *fillups);
|
||||||
|
void setAutoCompletionWordSeparators(const QStringList &separators);
|
||||||
|
|
||||||
|
void setCallTipsBackgroundColor(const QColor &col);
|
||||||
|
void setCallTipsForegroundColor(const QColor &col);
|
||||||
|
void setCallTipsHighlightColor(const QColor &col);
|
||||||
|
void setCallTipsPosition(CallTipsPosition position);
|
||||||
|
void setCallTipsStyle(CallTipsStyle style);
|
||||||
|
void setCallTipsVisible(int nr);
|
||||||
|
void setContractedFolds(const QList<int> &folds);
|
||||||
|
|
||||||
|
void setDocument(const QsciDocument &document);
|
||||||
|
|
||||||
|
void addEdgeColumn(int colnr, const QColor &col);
|
||||||
|
void clearEdgeColumns();
|
||||||
|
void setEdgeColor(const QColor &col);
|
||||||
|
void setEdgeColumn(int colnr);
|
||||||
|
void setEdgeMode(EdgeMode mode);
|
||||||
|
|
||||||
|
void setFirstVisibleLine(int linenr);
|
||||||
|
void setFont(const QFont &f);
|
||||||
|
|
||||||
|
void setHotspotBackgroundColor(const QColor &col);
|
||||||
|
void setHotspotForegroundColor(const QColor &col);
|
||||||
|
void setHotspotUnderline(bool enable);
|
||||||
|
void setHotspotWrap(bool enable);
|
||||||
|
|
||||||
|
void setIndicatorDrawUnder(bool under, int indicatorNumber = -1);
|
||||||
|
void setIndicatorForegroundColor(const QColor &col,
|
||||||
|
int indicatorNumber = -1);
|
||||||
|
void setIndicatorHoverForegroundColor(const QColor &col,
|
||||||
|
int indicatorNumber = -1);
|
||||||
|
void setIndicatorHoverStyle(IndicatorStyle style,
|
||||||
|
int indicatorNumber = -1);
|
||||||
|
void setIndicatorOutlineColor(const QColor &col, int indicatorNumber = -1);
|
||||||
|
|
||||||
|
void setMarginBackgroundColor(int margin, const QColor &col);
|
||||||
|
void setMarginOptions(int options);
|
||||||
|
void setMarginText(int line, const QString &text, int style);
|
||||||
|
void setMarginText(int line, const QString &text, const QsciStyle &style);
|
||||||
|
void setMarginText(int line, const QsciStyledText &text);
|
||||||
|
void setMarginText(int line, const QList<QsciStyledText> &text);
|
||||||
|
void setMarginType(int margin, MarginType type);
|
||||||
|
void clearMarginText(int line = -1);
|
||||||
|
void setMargins(int margins);
|
||||||
|
|
||||||
|
void setMarkerBackgroundColor(const QColor &col, int markerNumber = -1);
|
||||||
|
void setMarkerForegroundColor(const QColor &col, int markerNumber = -1);
|
||||||
|
|
||||||
|
void setMatchedBraceBackgroundColor(const QColor &col);
|
||||||
|
void setMatchedBraceForegroundColor(const QColor &col);
|
||||||
|
void setMatchedBraceIndicator(int indicatorNumber);
|
||||||
|
void resetMatchedBraceIndicator();
|
||||||
|
void setUnmatchedBraceBackgroundColor(const QColor &col);
|
||||||
|
void setUnmatchedBraceForegroundColor(const QColor &col);
|
||||||
|
void setUnmatchedBraceIndicator(int indicatorNumber);
|
||||||
|
void resetUnmatchedBraceIndicator();
|
||||||
|
|
||||||
|
void setWrapVisualFlags(WrapVisualFlag endFlag,
|
||||||
|
WrapVisualFlag startFlag = QsciScintilla::WrapFlagNone,
|
||||||
|
int indent = 0);
|
||||||
|
|
||||||
|
QString selectedText() const;
|
||||||
|
bool selectionToEol() const;
|
||||||
|
void setSelectionToEol(bool filled);
|
||||||
|
|
||||||
|
void setExtraAscent(int extra);
|
||||||
|
void setExtraDescent(int extra);
|
||||||
|
|
||||||
|
void setOverwriteMode(bool overwrite);
|
||||||
|
|
||||||
|
void setWhitespaceBackgroundColor(const QColor &col);
|
||||||
|
void setWhitespaceForegroundColor(const QColor &col);
|
||||||
|
void setWhitespaceSize(int size);
|
||||||
|
|
||||||
|
void setWrapIndentMode(WrapIndentMode mode);
|
||||||
|
void showUserList(int id, const QStringList &list);
|
||||||
|
QsciCommandSet *standardCommands() const;
|
||||||
|
|
||||||
|
void setTabDrawMode(TabDrawMode mode);
|
||||||
|
TabDrawMode tabDrawMode() const;
|
||||||
|
|
||||||
|
bool tabIndents() const;
|
||||||
|
int tabWidth() const;
|
||||||
|
QString text() const;
|
||||||
|
QString text(int line) const;
|
||||||
|
QString text(int start, int end) const;
|
||||||
|
int textHeight(int linenr) const;
|
||||||
|
|
||||||
|
int whitespaceSize() const;
|
||||||
|
WhitespaceVisibility whitespaceVisibility() const;
|
||||||
|
|
||||||
|
QString wordAtLineIndex(int line, int index) const;
|
||||||
|
QString wordAtPoint(const QPoint &point) const;
|
||||||
|
const char *wordCharacters() const;
|
||||||
|
WrapMode wrapMode() const;
|
||||||
|
WrapIndentMode wrapIndentMode() const;
|
||||||
|
bool write(QIODevice *io) const /ReleaseGIL/;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void append(const QString &text);
|
||||||
|
virtual void autoCompleteFromAll();
|
||||||
|
virtual void autoCompleteFromAPIs();
|
||||||
|
virtual void autoCompleteFromDocument();
|
||||||
|
virtual void callTip();
|
||||||
|
virtual void clear();
|
||||||
|
virtual void copy();
|
||||||
|
virtual void cut();
|
||||||
|
|
||||||
|
virtual void ensureCursorVisible();
|
||||||
|
virtual void ensureLineVisible(int line);
|
||||||
|
virtual void foldAll(bool children = false);
|
||||||
|
virtual void foldLine(int line);
|
||||||
|
virtual void indent(int line);
|
||||||
|
virtual void insert(const QString &text);
|
||||||
|
virtual void insertAt(const QString &text, int line, int index);
|
||||||
|
virtual void moveToMatchingBrace();
|
||||||
|
virtual void paste();
|
||||||
|
virtual void redo();
|
||||||
|
virtual void removeSelectedText();
|
||||||
|
virtual void replaceSelectedText(const QString &text);
|
||||||
|
virtual void resetSelectionBackgroundColor();
|
||||||
|
virtual void resetSelectionForegroundColor();
|
||||||
|
virtual void selectAll(bool select = true);
|
||||||
|
virtual void selectToMatchingBrace();
|
||||||
|
|
||||||
|
virtual void setAutoCompletionCaseSensitivity(bool cs);
|
||||||
|
virtual void setAutoCompletionReplaceWord(bool replace);
|
||||||
|
virtual void setAutoCompletionShowSingle(bool single);
|
||||||
|
virtual void setAutoCompletionSource(AutoCompletionSource source);
|
||||||
|
virtual void setAutoCompletionThreshold(int thresh);
|
||||||
|
virtual void setAutoCompletionUseSingle(AutoCompletionUseSingle single);
|
||||||
|
virtual void setAutoIndent(bool autoindent);
|
||||||
|
virtual void setBraceMatching(BraceMatch bm);
|
||||||
|
virtual void setBackspaceUnindents(bool unindent);
|
||||||
|
virtual void setCaretForegroundColor(const QColor &col);
|
||||||
|
virtual void setCaretLineBackgroundColor(const QColor &col);
|
||||||
|
virtual void setCaretLineFrameWidth(int width);
|
||||||
|
virtual void setCaretLineVisible(bool enable);
|
||||||
|
virtual void setCaretWidth(int width);
|
||||||
|
virtual void setColor(const QColor &col);
|
||||||
|
virtual void setCursorPosition(int line, int index);
|
||||||
|
virtual void setEolMode(EolMode mode);
|
||||||
|
virtual void setEolVisibility(bool visible);
|
||||||
|
virtual void setFolding(FoldStyle fold, int margin=2);
|
||||||
|
void clearFolds();
|
||||||
|
|
||||||
|
virtual void setIndentation(int line, int indentation);
|
||||||
|
virtual void setIndentationGuides(bool enable);
|
||||||
|
virtual void setIndentationGuidesBackgroundColor(const QColor &col);
|
||||||
|
virtual void setIndentationGuidesForegroundColor(const QColor &col);
|
||||||
|
virtual void setIndentationsUseTabs(bool tabs);
|
||||||
|
virtual void setIndentationWidth(int width);
|
||||||
|
|
||||||
|
virtual void setLexer(QsciLexer *lexer = 0);
|
||||||
|
|
||||||
|
virtual void setMarginsBackgroundColor(const QColor &col);
|
||||||
|
virtual void setMarginsFont(const QFont &f);
|
||||||
|
virtual void setMarginsForegroundColor(const QColor &col);
|
||||||
|
|
||||||
|
virtual void setMarginLineNumbers(int margin, bool lnrs);
|
||||||
|
virtual void setMarginMarkerMask(int margin, int mask);
|
||||||
|
virtual void setMarginSensitivity(int margin, bool sens);
|
||||||
|
virtual void setMarginWidth(int margin, int width);
|
||||||
|
virtual void setMarginWidth(int margin, const QString &s);
|
||||||
|
|
||||||
|
virtual void setModified(bool m);
|
||||||
|
virtual void setPaper(const QColor &c);
|
||||||
|
virtual void setReadOnly(bool ro);
|
||||||
|
virtual void setSelection(int lineFrom, int indexFrom, int lineTo,
|
||||||
|
int indexTo);
|
||||||
|
virtual void setSelectionBackgroundColor(const QColor &col);
|
||||||
|
virtual void setSelectionForegroundColor(const QColor &col);
|
||||||
|
virtual void setTabIndents(bool indent);
|
||||||
|
virtual void setTabWidth(int width);
|
||||||
|
virtual void setText(const QString &text);
|
||||||
|
virtual void setUtf8(bool cp);
|
||||||
|
virtual void setWhitespaceVisibility(WhitespaceVisibility mode);
|
||||||
|
virtual void setWrapMode(WrapMode mode);
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void unindent(int line);
|
||||||
|
|
||||||
|
virtual void zoomIn(int range);
|
||||||
|
virtual void zoomIn();
|
||||||
|
virtual void zoomOut(int range);
|
||||||
|
virtual void zoomOut();
|
||||||
|
virtual void zoomTo(int size);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void cursorPositionChanged(int line, int index);
|
||||||
|
void copyAvailable(bool yes);
|
||||||
|
|
||||||
|
void indicatorClicked(int line, int index, Qt::KeyboardModifiers state);
|
||||||
|
void indicatorReleased(int line, int index, Qt::KeyboardModifiers state);
|
||||||
|
|
||||||
|
void linesChanged();
|
||||||
|
|
||||||
|
void marginClicked(int margin, int line, Qt::KeyboardModifiers state);
|
||||||
|
void marginRightClicked(int margin, int line, Qt::KeyboardModifiers state);
|
||||||
|
|
||||||
|
void modificationAttempted();
|
||||||
|
void modificationChanged(bool m);
|
||||||
|
void selectionChanged();
|
||||||
|
void textChanged();
|
||||||
|
void userListActivated(int id, const QString &string);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool event(QEvent *event);
|
||||||
|
virtual void changeEvent(QEvent *event);
|
||||||
|
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||||
|
virtual void wheelEvent(QWheelEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QsciScintilla(const QsciScintilla &);
|
||||||
|
};
|
||||||
1611
third_party/qscintilla/Python/sip/qsciscintillabase.sip
vendored
Normal file
1611
third_party/qscintilla/Python/sip/qsciscintillabase.sip
vendored
Normal file
File diff suppressed because it is too large
Load Diff
69
third_party/qscintilla/Python/sip/qscistyle.sip
vendored
Normal file
69
third_party/qscintilla/Python/sip/qscistyle.sip
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// This is the SIP interface definition for QsciStyle.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciStyle
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscistyle.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum TextCase {
|
||||||
|
OriginalCase,
|
||||||
|
UpperCase,
|
||||||
|
LowerCase
|
||||||
|
};
|
||||||
|
|
||||||
|
QsciStyle(int style = -1);
|
||||||
|
QsciStyle(int style, const QString &description, const QColor &color,
|
||||||
|
const QColor &paper, const QFont &font, bool eolFill = false);
|
||||||
|
|
||||||
|
void setStyle(int style);
|
||||||
|
int style() const;
|
||||||
|
|
||||||
|
void setDescription(const QString &description);
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
void setColor(const QColor &color);
|
||||||
|
QColor color() const;
|
||||||
|
|
||||||
|
void setPaper(const QColor &paper);
|
||||||
|
QColor paper() const;
|
||||||
|
|
||||||
|
void setFont(const QFont &font);
|
||||||
|
QFont font() const;
|
||||||
|
|
||||||
|
void setEolFill(bool fill);
|
||||||
|
bool eolFill() const;
|
||||||
|
|
||||||
|
void setTextCase(TextCase text_case);
|
||||||
|
TextCase textCase() const;
|
||||||
|
|
||||||
|
void setVisible(bool visible);
|
||||||
|
bool visible() const;
|
||||||
|
|
||||||
|
void setChangeable(bool changeable);
|
||||||
|
bool changeable() const;
|
||||||
|
|
||||||
|
void setHotspot(bool hotspot);
|
||||||
|
bool hotspot() const;
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
};
|
||||||
33
third_party/qscintilla/Python/sip/qscistyledtext.sip
vendored
Normal file
33
third_party/qscintilla/Python/sip/qscistyledtext.sip
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// This is the SIP interface definition for QsciStyledText.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||||
|
//
|
||||||
|
// This file is part of QScintilla.
|
||||||
|
//
|
||||||
|
// This file may be used under the terms of the GNU General Public License
|
||||||
|
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||||
|
// the file LICENSE included in the packaging of this file. Please review the
|
||||||
|
// following information to ensure the GNU General Public License version 3.0
|
||||||
|
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
//
|
||||||
|
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||||
|
// then you may purchase a commercial license. For more information contact
|
||||||
|
// info@riverbankcomputing.com.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
class QsciStyledText
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <Qsci/qscistyledtext.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
QsciStyledText(const QString &text, int style);
|
||||||
|
QsciStyledText(const QString &text, const QsciStyle &style);
|
||||||
|
|
||||||
|
const QString &text();
|
||||||
|
int style() const;
|
||||||
|
};
|
||||||
22
third_party/qscintilla/designer/designer.pro
vendored
Normal file
22
third_party/qscintilla/designer/designer.pro
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# This is the qmake file for the QScintilla plugin for Qt Designer.
|
||||||
|
|
||||||
|
|
||||||
|
TEMPLATE = lib
|
||||||
|
TARGET = qscintillaplugin
|
||||||
|
|
||||||
|
# Comment this in to build a dynamic library supporting multiple architectures
|
||||||
|
# on macOS.
|
||||||
|
#QMAKE_APPLE_DEVICE_ARCHS = x86_64 arm64
|
||||||
|
|
||||||
|
CONFIG += plugin qscintilla2
|
||||||
|
|
||||||
|
QT += designer
|
||||||
|
|
||||||
|
# Work around QTBUG-39300.
|
||||||
|
CONFIG -= android_install
|
||||||
|
|
||||||
|
HEADERS = qscintillaplugin.h
|
||||||
|
SOURCES = qscintillaplugin.cpp
|
||||||
|
|
||||||
|
target.path = $$[QT_INSTALL_PLUGINS]/designer
|
||||||
|
INSTALLS += target
|
||||||
167
third_party/qscintilla/designer/qscintillaplugin.cpp
vendored
Normal file
167
third_party/qscintilla/designer/qscintillaplugin.cpp
vendored
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
// This implements the QScintilla plugin for Qt Designer.
|
||||||
|
|
||||||
|
|
||||||
|
#include "qscintillaplugin.h"
|
||||||
|
|
||||||
|
#include <QtPlugin>
|
||||||
|
|
||||||
|
#include <Qsci/qsciscintilla.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char *qscintilla_pixmap[] = {
|
||||||
|
"22 22 35 1",
|
||||||
|
"m c #000000",
|
||||||
|
"n c #000033",
|
||||||
|
"p c #003300",
|
||||||
|
"r c #003333",
|
||||||
|
"v c #330000",
|
||||||
|
"o c #330033",
|
||||||
|
"l c #333300",
|
||||||
|
"h c #333333",
|
||||||
|
"c c #333366",
|
||||||
|
"d c #336666",
|
||||||
|
"u c #336699",
|
||||||
|
"E c #3366cc",
|
||||||
|
"k c #663333",
|
||||||
|
"i c #663366",
|
||||||
|
"b c #666666",
|
||||||
|
"e c #666699",
|
||||||
|
"A c #6666cc",
|
||||||
|
"G c #669966",
|
||||||
|
"f c #669999",
|
||||||
|
"j c #6699cc",
|
||||||
|
"y c #6699ff",
|
||||||
|
"t c #996666",
|
||||||
|
"a c #999999",
|
||||||
|
"g c #9999cc",
|
||||||
|
"s c #9999ff",
|
||||||
|
"C c #99cc99",
|
||||||
|
"x c #99cccc",
|
||||||
|
"w c #99ccff",
|
||||||
|
"F c #cc99ff",
|
||||||
|
"q c #cccccc",
|
||||||
|
"# c #ccccff",
|
||||||
|
"B c #ccffcc",
|
||||||
|
"z c #ccffff",
|
||||||
|
"D c #ffffcc",
|
||||||
|
". c none",
|
||||||
|
"........#abcda........",
|
||||||
|
"......abefghdidcf.....",
|
||||||
|
".....cadhfaehjheck....",
|
||||||
|
"....leh.m.ncbehjddo...",
|
||||||
|
"...depn.hqhqhr#mccch..",
|
||||||
|
"..bb.hcaeh.hqersjhjcd.",
|
||||||
|
".tcm.uqn.hc.uvwxhuygha",
|
||||||
|
".feh.n.hb.hhzemcwhmuAm",
|
||||||
|
"Bgehghqqme.eo#wlnysbnj",
|
||||||
|
"awhdAzn.engjepswhmuyuj",
|
||||||
|
"bCh#m.de.jpqwbmcwemlcz",
|
||||||
|
"hcb#xh.nd#qrbswfehwzbm",
|
||||||
|
"bd#d.A#zor#qmgbzwgjgws",
|
||||||
|
"ajbcuqhqzchwwbemewchmr",
|
||||||
|
"Dcn#cwmhgwehgsxbmhEjAc",
|
||||||
|
".uanauFrhbgeahAAbcbuhh",
|
||||||
|
".bohdAegcccfbbebuucmhe",
|
||||||
|
"..briuauAediddeclchhh.",
|
||||||
|
"...hcbhjccdecbceccch..",
|
||||||
|
"....nhcmeccdccephcp...",
|
||||||
|
".....crbhchhhrhhck....",
|
||||||
|
"......tcmdhohhcnG....."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QScintillaPlugin::QScintillaPlugin(QObject *parent)
|
||||||
|
: QObject(parent), initialized(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScintillaPlugin::~QScintillaPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QScintillaPlugin::initialize(QDesignerFormEditorInterface * /* core */)
|
||||||
|
{
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QScintillaPlugin::isInitialized() const
|
||||||
|
{
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget *QScintillaPlugin::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
return new QsciScintilla(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::name() const
|
||||||
|
{
|
||||||
|
return "QsciScintilla";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::group() const
|
||||||
|
{
|
||||||
|
return "Input Widgets";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QIcon QScintillaPlugin::icon() const
|
||||||
|
{
|
||||||
|
return QIcon(QPixmap(qscintilla_pixmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::toolTip() const
|
||||||
|
{
|
||||||
|
return "QScintilla Programmer's Editor";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::whatsThis() const
|
||||||
|
{
|
||||||
|
return "A port to Qt of the Scintilla programmer's editor";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QScintillaPlugin::isContainer() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::domXml() const
|
||||||
|
{
|
||||||
|
return "<widget class=\"QsciScintilla\" name=\"textEdit\">\n"
|
||||||
|
" <property name=\"geometry\">\n"
|
||||||
|
" <rect>\n"
|
||||||
|
" <x>0</x>\n"
|
||||||
|
" <y>0</y>\n"
|
||||||
|
" <width>400</width>\n"
|
||||||
|
" <height>200</height>\n"
|
||||||
|
" </rect>\n"
|
||||||
|
" </property>\n"
|
||||||
|
" <property name=\"toolTip\" >\n"
|
||||||
|
" <string></string>\n"
|
||||||
|
" </property>\n"
|
||||||
|
" <property name=\"whatsThis\" >\n"
|
||||||
|
" <string></string>\n"
|
||||||
|
" </property>\n"
|
||||||
|
"</widget>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QScintillaPlugin::includeFile() const
|
||||||
|
{
|
||||||
|
return "Qsci/qsciscintilla.h";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
Q_EXPORT_PLUGIN2(qscintillaplugin, QScintillaPlugin)
|
||||||
|
#endif
|
||||||
38
third_party/qscintilla/designer/qscintillaplugin.h
vendored
Normal file
38
third_party/qscintilla/designer/qscintillaplugin.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// This defines the QScintilla plugin for Qt Designer.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _QSCINTILLAPLUGIN_H
|
||||||
|
#define _QSCINTILLAPLUGIN_H
|
||||||
|
|
||||||
|
#include <QtDesigner>
|
||||||
|
|
||||||
|
|
||||||
|
class QScintillaPlugin : public QObject, public QDesignerCustomWidgetInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
|
||||||
|
#endif
|
||||||
|
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QScintillaPlugin(QObject *parent = 0);
|
||||||
|
virtual ~QScintillaPlugin();
|
||||||
|
|
||||||
|
bool isContainer() const;
|
||||||
|
bool isInitialized() const;
|
||||||
|
QIcon icon() const;
|
||||||
|
QString domXml() const;
|
||||||
|
QString group() const;
|
||||||
|
QString includeFile() const;
|
||||||
|
QString name() const;
|
||||||
|
QString toolTip() const;
|
||||||
|
QString whatsThis() const;
|
||||||
|
QWidget *createWidget(QWidget *parent);
|
||||||
|
void initialize(QDesignerFormEditorInterface *core);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
204
third_party/qscintilla/doc/README.doc
vendored
Normal file
204
third_party/qscintilla/doc/README.doc
vendored
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
/*! \mainpage QScintilla - a Port to Qt v5 and Qt v6 of Scintilla
|
||||||
|
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
|
||||||
|
<a href="http://www.riverbankcomputing.com/software/qscintilla/">QScintilla</a>
|
||||||
|
is a port to Qt of the <a href="http://www.scintilla.org/">Scintilla</a>
|
||||||
|
editing component.
|
||||||
|
|
||||||
|
As well as features found in standard text editing components, Scintilla
|
||||||
|
includes features especially useful when editing and debugging source code:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>syntax styling with support for over 70 languages
|
||||||
|
<li>error indicators
|
||||||
|
<li>code completion
|
||||||
|
<li>call tips
|
||||||
|
<li>code folding
|
||||||
|
<li>margins can contain markers like those used in debuggers to indicate
|
||||||
|
breakpoints and the current line.
|
||||||
|
<li>recordable macros
|
||||||
|
<li>multiple views
|
||||||
|
<li>printing.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
QScintilla is a port or Scintilla to the Qt GUI toolkit from
|
||||||
|
<a href="http://www.qt.io">The Qt Company</a> and runs on any operating system
|
||||||
|
supported by Qt (eg. Windows, Linux, macOS, iOS and Android). QScintilla works
|
||||||
|
with Qt v5 and v6.
|
||||||
|
|
||||||
|
QScintilla also includes language bindings for
|
||||||
|
<a href="https://www.python.org">Python</a>. These require that
|
||||||
|
<a href="https://www.riverbankcomputing.com/software/pyqt/">PyQt</a> v5 or v6
|
||||||
|
is also installed.
|
||||||
|
|
||||||
|
This version of QScintilla is based on Scintilla v3.10.1.
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Licensing</h2>
|
||||||
|
|
||||||
|
QScintilla is available under the
|
||||||
|
<a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License v3</a>
|
||||||
|
and the Riverbank Commercial License.
|
||||||
|
|
||||||
|
The commercial license allows closed source applications using QScintilla to be
|
||||||
|
developed and distributed. At the moment the commercial version of QScintilla
|
||||||
|
is bundled with, but packaged separately from, the commercial version of
|
||||||
|
<a href="http://www.riverbankcomputing.com/software/pyqt/">PyQt</a>.
|
||||||
|
|
||||||
|
The Scintilla code within QScintilla is released under the following license:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
License for Scintilla and SciTE
|
||||||
|
|
||||||
|
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
|
||||||
|
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose and without fee is hereby granted,
|
||||||
|
provided that the above copyright notice appear in all copies and that
|
||||||
|
both that copyright notice and this permission notice appear in
|
||||||
|
supporting documentation.
|
||||||
|
|
||||||
|
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||||
|
OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Installation</h2>
|
||||||
|
|
||||||
|
As supplied QScintilla will be built as a shared library/DLL and installed in
|
||||||
|
the same directories as the Qt libraries and include files.
|
||||||
|
|
||||||
|
If you wish to build a static version of the library then pass
|
||||||
|
<tt>CONFIG+=staticlib</tt> on the <tt>qmake</tt> command line.
|
||||||
|
|
||||||
|
On macOS, if you wish to build a dynamic version of the library that supports
|
||||||
|
both <tt>x86_64</tt> and <tt>arm64</tt> architectures then edit the file
|
||||||
|
<tt>qscintilla.pro</tt> in the <tt>src</tt> directory and comment in the
|
||||||
|
definition of <tt>QMAKE_APPLE_DEVICE_ARCHS</tt>. Similar changes can be made
|
||||||
|
to the <tt>.pro</tt> files for the Designer plugin and the example application.
|
||||||
|
|
||||||
|
If you want to make more significant changes to the configuration then edit the
|
||||||
|
file <tt>qscintilla.pro</tt> in the <tt>src</tt> directory.
|
||||||
|
|
||||||
|
If you do make changes, specifically to the names of the installation
|
||||||
|
directories or the name of the library, then you may also need to update the
|
||||||
|
<tt>src/features/qscintilla2.prf</tt> file.
|
||||||
|
|
||||||
|
See your <tt>qmake</tt> documentation for more details.
|
||||||
|
|
||||||
|
To build and install QScintilla, run:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cd src
|
||||||
|
qmake
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
If you have multiple versions of Qt installed then make sure you use the
|
||||||
|
correct version of <tt>qmake</tt>.
|
||||||
|
|
||||||
|
The underlying Scintilla code may support additional compile-time options.
|
||||||
|
These can be configured by passing appropriate arguments to <tt>qmake</tt>.
|
||||||
|
For example, if you have an old C++ compiler that does not have a working
|
||||||
|
<tt>std::regex</tt> then invoke <tt>qmake</tt> as follows:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
qmake DEFINES+=NO_CXX11_REGEX=1
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Installation on Windows</h3>
|
||||||
|
|
||||||
|
Before compiling QScintilla on Windows you should remove the <tt>Qsci</tt>
|
||||||
|
directory containing the QScintilla header files from any previous
|
||||||
|
installation. This is because the <tt>Makefile</tt> generated by
|
||||||
|
<tt>qmake</tt> will find these older header files instead of the new ones.
|
||||||
|
|
||||||
|
Depending on the compiler you are using you may need to run <tt>nmake</tt>
|
||||||
|
rather than <tt>make</tt>.
|
||||||
|
|
||||||
|
If you have built a Windows DLL then you probably also want to run:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
copy %%QTDIR%\\lib\\qscintilla2.dll %%QTDIR%\\bin
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Integration with <tt>qmake</tt></h2>
|
||||||
|
|
||||||
|
To configure <tt>qmake</tt> to find your QScintilla installation, add the
|
||||||
|
following line to your application's <tt>.pro</tt> file:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
CONFIG += qscintilla2
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Qt Designer Plugin</h2>
|
||||||
|
|
||||||
|
QScintilla includes an optional plugin for Qt Designer that allows QScintilla
|
||||||
|
instances to be included in GUI designs just like any other Qt widget.
|
||||||
|
|
||||||
|
To build the plugin on all platforms, make sure QScintilla is installed and
|
||||||
|
then run (as root or administrator):
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cd designer
|
||||||
|
qmake
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
On Windows (and depending on the compiler you are using) you may need to run
|
||||||
|
<tt>nmake</tt> rather than <tt>make</tt>.
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Example Application</h2>
|
||||||
|
|
||||||
|
The example application provided is a port of the standard Qt
|
||||||
|
<tt>application</tt> example with the QsciScintilla class being used instead of
|
||||||
|
Qt's QTextEdit class.
|
||||||
|
|
||||||
|
The example does not demonstrate all of the extra features of QScintilla.
|
||||||
|
|
||||||
|
To build the example, run:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cd example
|
||||||
|
qmake
|
||||||
|
make
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
On Windows (and depending on the compiler you are using) you may need to run
|
||||||
|
<tt>nmake</tt> rather than <tt>make</tt>.
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Python Bindings</h2>
|
||||||
|
|
||||||
|
The Python bindings are in the <tt>Python</tt> sub-directory. You must have
|
||||||
|
either PyQt5 or PyQt6 already installed and PyQt-builder. QScintilla must also
|
||||||
|
already be built and installed.
|
||||||
|
|
||||||
|
The <tt>Python</tt> sub-directory contains a <tt>pyproject-qt5.toml</tt> file
|
||||||
|
and a <tt>pyproject-qt6.toml</tt> file. If you are building for PyQt5 and Qt
|
||||||
|
v5 then you must copy the <tt>pyproject-qt5.toml</tt> file to
|
||||||
|
<tt>pyproject.toml</tt>. If instead you are building for PyQt6 and Qt v6 then
|
||||||
|
you must copy the <tt>pyproject-qt6.toml</tt> file to <tt>pyproject.toml</tt>.
|
||||||
|
|
||||||
|
To build and install the bindings, run:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cd Python
|
||||||
|
sip-install
|
||||||
|
</pre>
|
||||||
|
*/
|
||||||
246
third_party/qscintilla/doc/Scintilla/Design.html
vendored
Normal file
246
third_party/qscintilla/doc/Scintilla/Design.html
vendored
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta name="generator" content="HTML Tidy, see www.w3.org" />
|
||||||
|
<meta name="generator" content="SciTE" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>
|
||||||
|
Scintilla and SciTE
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
|
<table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla
|
||||||
|
Component Design</font></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h2>
|
||||||
|
Top level structure
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
Scintilla consists of three major layers of C++ code
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Portability Library
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Core Code
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Platform Events and API
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
The primary purpose of this structure is to separate the platform dependent code from the
|
||||||
|
platform independent core code. This makes it easier to port Scintilla to a new platform and
|
||||||
|
ensures that most readers of the code do not have to deal with platform details. To minimise
|
||||||
|
portability problems and avoid code bloat, a conservative subset of C++ is used in Scintilla
|
||||||
|
with no exception handling, run time type information or use of the standard C++
|
||||||
|
library and with limited use of templates.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The currently supported platforms, Windows, GTK+/Linux, Cocoa and wxWidgets are fairly similar in
|
||||||
|
many ways.
|
||||||
|
Each has windows, menus and bitmaps. These features generally work in similar ways so each
|
||||||
|
has a way to move a window or draw a red line. Sometimes one platform requires a sequence of
|
||||||
|
calls rather than a single call. At other times, the differences are more profound. Reading
|
||||||
|
the Windows clipboard occurs synchronously but reading the GTK+ clipboard requires a request
|
||||||
|
call that will be asynchronously answered with a message containing the clipboard data.
|
||||||
|
The wxWidgets platform is available from the <a href="http://wxwidgets.org/">wxWidgets site</a>
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<h3>
|
||||||
|
Portability Library
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
This is a fairly small and thin layer over the platform's native capabilities.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The portability library is defined in Platform.h and is implemented once for each platform.
|
||||||
|
PlatWin.cxx defines the Windows variants of the methods and PlatGTK.cxx the GTK+ variants.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Several of the classes here hold platform specific object identifiers and act as proxies to
|
||||||
|
these platform objects. Most client code can thus manipulate the platform objects without
|
||||||
|
caring which is the current platform. Sometimes client code needs access to the underlying
|
||||||
|
object identifiers and this is provided by the GetID method. The underlying types of the
|
||||||
|
platform specific identifiers are typedefed to common names to allow them to be transferred
|
||||||
|
around in client code where needed.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Point, PRectangle
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
These are simple classes provided to hold the commonly used geometric primitives. A
|
||||||
|
PRectangle follows the Mac / Windows convention of not including its bottom and right sides
|
||||||
|
instead of including all its sides as is normal in GTK+. It is not called Rectangle as this may be
|
||||||
|
the name of a macro on Windows.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
ColourDesired
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
This is a simple class holding an expected colour. It is internally represented as a single
|
||||||
|
32 bit integer in BGR format with 8 bits per colour, but also provides a convenient API to fetch
|
||||||
|
each component separately.
|
||||||
|
As a platform might not be able to represent the exact desired colour if it doesn't have 24 bit
|
||||||
|
depth available, it might not actually represent the exact desired colour but select a best fit
|
||||||
|
that it can actually render.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Font
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Font holds a platform specific font identifier - HFONT for Windows, PangoFontDescription* for GTK+. It
|
||||||
|
does not own the identifier and so will not delete the platform font object in its
|
||||||
|
destructor. Client code should call Destroy at appropriate times.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Surface
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Surface is an abstraction over each platform's concept of somewhere that graphical drawing
|
||||||
|
operations can be done. It may wrap an already created drawing place such as a window or be
|
||||||
|
used to create a bitmap that can be drawn into and later copied onto another surface. On
|
||||||
|
Windows it wraps a HDC and possibly a HBITMAP. On GTK+ it wraps a cairo_surface_t*.
|
||||||
|
Other platform specific objects are created (and correctly destroyed) whenever
|
||||||
|
required to perform drawing actions.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Drawing operations provided include drawing filled and unfilled polygons, lines, rectangles,
|
||||||
|
ellipses and text. The height and width of text as well as other details can be measured.
|
||||||
|
Operations can be clipped to a rectangle. Most of the calls are stateless with all parameters
|
||||||
|
being passed at each call. The exception to this is line drawing which is performed by
|
||||||
|
calling MoveTo and then LineTo.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Window
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Window acts as a proxy to a platform window allowing operations such as showing, moving,
|
||||||
|
redrawing, and destroying to be performed. It contains a platform specific window identifier
|
||||||
|
- HWND for Windows, GtkWidget* for GTK+.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
ListBox
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
ListBox is a subclass of Window and acts as a proxy to a platform listbox adding methods for
|
||||||
|
operations such as adding, retrieving, and selecting items.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Menu
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Menu is a small helper class for constructing popup menus. It contains the platform specific
|
||||||
|
menu identifier - HMENU for Windows, GtkMenu* for GTK+. Most of the work in
|
||||||
|
constructing menus requires access to platform events and so is done in the Platform Events
|
||||||
|
and API layer.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Platform
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
The Platform class is used to access the facilities of the platform. System wide parameters
|
||||||
|
such as double click speed and chrome colour are available from Platform. Utility functions
|
||||||
|
such as DebugPrintf are also available from Platform.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Core Code
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
The bulk of Scintilla's code is platform independent. This is made up of the CellBuffer,
|
||||||
|
ContractionState, Document, Editor, Indicator, LineMarker, Style, ViewStyle, KeyMap,
|
||||||
|
ScintillaBase, CallTip,
|
||||||
|
and AutoComplete primary classes.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
CellBuffer
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
A CellBuffer holds text and styling information, the undo stack, the assignment of line
|
||||||
|
markers to lines, and the fold structure.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
A cell contains a character byte and its associated style byte. The current state of the
|
||||||
|
cell buffer is the sequence of cells that make up the text and a sequence of line information
|
||||||
|
containing the starting position of each line and any markers assigned to each line.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The undo stack holds a sequence of actions on the cell buffer. Each action is one of a text
|
||||||
|
insertion, a text deletion or an undo start action. The start actions are used to group
|
||||||
|
sequences of text insertions and deletions together so they can be undone together. To
|
||||||
|
perform an undo operation, each insertion or deletion is undone in reverse sequence.
|
||||||
|
Similarly, redo reapplies each action to the buffer in sequence. Whenever a character is
|
||||||
|
inserted in the buffer either directly through a call such as InsertString or through undo or
|
||||||
|
redo, its styling byte is initially set to zero. Client code is responsible for styling each
|
||||||
|
character whenever convenient. Styling information is not stored in undo actions.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Document
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
A document contains a CellBuffer and deals with some higher level abstractions such as
|
||||||
|
words, DBCS character sequences and line end character sequences. It is responsible for
|
||||||
|
managing the styling process and for notifying other objects when changes occur to the
|
||||||
|
document.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
Editor
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
The Editor object is central to Scintilla. It is responsible for displaying a document and
|
||||||
|
responding to user actions and requests from the container. It uses ContractionState, Indicator,
|
||||||
|
LineMarker, Style, and ViewStyle objects to display the document and a KeyMap class to
|
||||||
|
map key presses to functions.
|
||||||
|
The visibility of each line is kept in the ContractionState which is also responsible for mapping
|
||||||
|
from display lines to documents lines and vice versa.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
There may be multiple Editor objects attached to one Document object. Changes to a
|
||||||
|
document are broadcast to the editors through the DocWatcher mechanism.
|
||||||
|
</p>
|
||||||
|
<h4>
|
||||||
|
ScintillaBase
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
ScintillaBase is a subclass of Editor and adds extra windowing features including display of
|
||||||
|
calltips, autocompletion lists and context menus. These features use CallTip and AutoComplete
|
||||||
|
objects. This class is optional so a lightweight implementation of Scintilla may bypass it if
|
||||||
|
the added functionality is not required.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Platform Events and API
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Each platform uses different mechanisms for receiving events. On Windows, events are
|
||||||
|
received through messages and COM. On GTK+, callback functions are used.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For each platform, a class is derived from ScintillaBase (and thus from Editor). This is
|
||||||
|
ScintillaWin on Windows and ScintillaGTK on GTK+. These classes are responsible for
|
||||||
|
connecting to the platforms event mechanism and also to implement some virtual methods in
|
||||||
|
Editor and ScintillaBase which are different on the platforms. For example, this layer has to
|
||||||
|
support this difference between the synchronous Windows clipboard and the asynchronous GTK+
|
||||||
|
clipboard.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The external API is defined in this layer as each platform has different preferred styles of
|
||||||
|
API - messages on Windows and function calls on GTK+. This also allows multiple APIs to be
|
||||||
|
defined on a platform. The currently available API on GTK+ is similar to the Windows API and
|
||||||
|
does not follow platform conventions well. A second API could be implemented here that did
|
||||||
|
follow platform conventions.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
57
third_party/qscintilla/doc/Scintilla/Icons.html
vendored
Normal file
57
third_party/qscintilla/doc/Scintilla/Icons.html
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta name="generator" content="HTML Tidy, see www.w3.org" />
|
||||||
|
<meta name="generator" content="SciTE" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>
|
||||||
|
Scintilla icons
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
|
<table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla
|
||||||
|
and SciTE</font></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h2>
|
||||||
|
Icons
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
These images may be used under the same license as Scintilla.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Drawn by Iago Rubio, Philippe Lhoste, and Neil Hodgson.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="http://prdownloads.sourceforge.net/scintilla/icons1.zip?download">zip format</a> (70K)
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>For autocompletion lists</td>
|
||||||
|
<td colspan="3">For margin markers</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>12x12</td>
|
||||||
|
<td>16x16</td>
|
||||||
|
<td>24x24</td>
|
||||||
|
<td>32x32</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><img src="12.png" /></td>
|
||||||
|
<td valign="top"><img src="16.png" /></td>
|
||||||
|
<td valign="top"><img src="24.png" /></td>
|
||||||
|
<td valign="top"><img src="32.png" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2608
third_party/qscintilla/doc/Scintilla/LPegLexer.html
vendored
Normal file
2608
third_party/qscintilla/doc/Scintilla/LPegLexer.html
vendored
Normal file
File diff suppressed because it is too large
Load Diff
226
third_party/qscintilla/doc/Scintilla/Lexer.txt
vendored
Normal file
226
third_party/qscintilla/doc/Scintilla/Lexer.txt
vendored
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
How to write a scintilla lexer
|
||||||
|
|
||||||
|
A lexer for a particular language determines how a specified range of
|
||||||
|
text shall be colored. Writing a lexer is relatively straightforward
|
||||||
|
because the lexer need only color given text. The harder job of
|
||||||
|
determining how much text actually needs to be colored is handled by
|
||||||
|
Scintilla itself, that is, the lexer's caller.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
|
||||||
|
The lexer for language LLL has the following prototype:
|
||||||
|
|
||||||
|
static void ColouriseLLLDoc (
|
||||||
|
unsigned int startPos, int length,
|
||||||
|
int initStyle,
|
||||||
|
WordList *keywordlists[],
|
||||||
|
Accessor &styler);
|
||||||
|
|
||||||
|
The styler parameter is an Accessor object. The lexer must use this
|
||||||
|
object to access the text to be colored. The lexer gets the character
|
||||||
|
at position i using styler.SafeGetCharAt(i);
|
||||||
|
|
||||||
|
The startPos and length parameters indicate the range of text to be
|
||||||
|
recolored; the lexer must determine the proper color for all characters
|
||||||
|
in positions startPos through startPos+length.
|
||||||
|
|
||||||
|
The initStyle parameter indicates the initial state, that is, the state
|
||||||
|
at the character before startPos. States also indicate the coloring to
|
||||||
|
be used for a particular range of text.
|
||||||
|
|
||||||
|
Note: the character at StartPos is assumed to start a line, so if a
|
||||||
|
newline terminates the initStyle state the lexer should enter its
|
||||||
|
default state (or whatever state should follow initStyle).
|
||||||
|
|
||||||
|
The keywordlists parameter specifies the keywords that the lexer must
|
||||||
|
recognize. A WordList class object contains methods that simplify
|
||||||
|
the recognition of keywords. Present lexers use a helper function
|
||||||
|
called classifyWordLLL to recognize keywords. These functions show how
|
||||||
|
to use the keywordlists parameter to recognize keywords. This
|
||||||
|
documentation will not discuss keywords further.
|
||||||
|
|
||||||
|
|
||||||
|
The lexer code
|
||||||
|
|
||||||
|
The task of a lexer can be summarized briefly: for each range r of
|
||||||
|
characters that are to be colored the same, the lexer should call
|
||||||
|
|
||||||
|
styler.ColourTo(i, state)
|
||||||
|
|
||||||
|
where i is the position of the last character of the range r. The lexer
|
||||||
|
should set the state variable to the coloring state of the character at
|
||||||
|
position i and continue until the entire text has been colored.
|
||||||
|
|
||||||
|
Note 1: the styler (Accessor) object remembers the i parameter in the
|
||||||
|
previous calls to styler.ColourTo, so the single i parameter suffices to
|
||||||
|
indicate a range of characters.
|
||||||
|
|
||||||
|
Note 2: As a side effect of calling styler.ColourTo(i,state), the
|
||||||
|
coloring states of all characters in the range are remembered so that
|
||||||
|
Scintilla may set the initStyle parameter correctly on future calls to
|
||||||
|
the
|
||||||
|
lexer.
|
||||||
|
|
||||||
|
|
||||||
|
Lexer organization
|
||||||
|
|
||||||
|
There are at least two ways to organize the code of each lexer. Present
|
||||||
|
lexers use what might be called a "character-based" approach: the outer
|
||||||
|
loop iterates over characters, like this:
|
||||||
|
|
||||||
|
lengthDoc = startPos + length ;
|
||||||
|
for (unsigned int i = startPos; i < lengthDoc; i++) {
|
||||||
|
chNext = styler.SafeGetCharAt(i + 1);
|
||||||
|
<< handle special cases >>
|
||||||
|
switch(state) {
|
||||||
|
// Handlers examine only ch and chNext.
|
||||||
|
// Handlers call styler.ColorTo(i,state) if the state changes.
|
||||||
|
case state_1: << handle ch in state 1 >>
|
||||||
|
case state_2: << handle ch in state 2 >>
|
||||||
|
...
|
||||||
|
case state_n: << handle ch in state n >>
|
||||||
|
}
|
||||||
|
chPrev = ch;
|
||||||
|
}
|
||||||
|
styler.ColourTo(lengthDoc - 1, state);
|
||||||
|
|
||||||
|
|
||||||
|
An alternative would be to use a "state-based" approach. The outer loop
|
||||||
|
would iterate over states, like this:
|
||||||
|
|
||||||
|
lengthDoc = startPos+lenth ;
|
||||||
|
for ( unsigned int i = startPos ;; ) {
|
||||||
|
char ch = styler.SafeGetCharAt(i);
|
||||||
|
int new_state = 0 ;
|
||||||
|
switch ( state ) {
|
||||||
|
// scanners set new_state if they set the next state.
|
||||||
|
case state_1: << scan to the end of state 1 >> break ;
|
||||||
|
case state_2: << scan to the end of state 2 >> break ;
|
||||||
|
case default_state:
|
||||||
|
<< scan to the next non-default state and set new_state >>
|
||||||
|
}
|
||||||
|
styler.ColourTo(i, state);
|
||||||
|
if ( i >= lengthDoc ) break ;
|
||||||
|
if ( ! new_state ) {
|
||||||
|
ch = styler.SafeGetCharAt(i);
|
||||||
|
<< set state based on ch in the default state >>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
styler.ColourTo(lengthDoc - 1, state);
|
||||||
|
|
||||||
|
This approach might seem to be more natural. State scanners are simpler
|
||||||
|
than character scanners because less needs to be done. For example,
|
||||||
|
there is no need to test for the start of a C string inside the scanner
|
||||||
|
for a C comment. Also this way makes it natural to define routines that
|
||||||
|
could be used by more than one scanner; for example, a scanToEndOfLine
|
||||||
|
routine.
|
||||||
|
|
||||||
|
However, the special cases handled in the main loop in the
|
||||||
|
character-based approach would have to be handled by each state scanner,
|
||||||
|
so both approaches have advantages. These special cases are discussed
|
||||||
|
below.
|
||||||
|
|
||||||
|
Special case: Lead characters
|
||||||
|
|
||||||
|
Lead bytes are part of DBCS processing for languages such as Japanese
|
||||||
|
using an encoding such as Shift-JIS. In these encodings, extended
|
||||||
|
(16-bit) characters are encoded as a lead byte followed by a trail byte.
|
||||||
|
|
||||||
|
Lead bytes are rarely of any lexical significance, normally only being
|
||||||
|
allowed within strings and comments. In such contexts, lexers should
|
||||||
|
ignore ch if styler.IsLeadByte(ch) returns TRUE.
|
||||||
|
|
||||||
|
Note: UTF-8 is simpler than Shift-JIS, so no special handling is
|
||||||
|
applied for it. All UTF-8 extended characters are >= 128 and none are
|
||||||
|
lexically significant in programming languages which, so far, use only
|
||||||
|
characters in ASCII for operators, comment markers, etc.
|
||||||
|
|
||||||
|
|
||||||
|
Special case: Folding
|
||||||
|
|
||||||
|
Folding may be performed in the lexer function. It is better to use a
|
||||||
|
separate folder function as that avoids some troublesome interaction
|
||||||
|
between styling and folding. The folder function will be run after the
|
||||||
|
lexer function if folding is enabled. The rest of this section explains
|
||||||
|
how to perform folding within the lexer function.
|
||||||
|
|
||||||
|
During initialization, lexers that support folding set
|
||||||
|
|
||||||
|
bool fold = styler.GetPropertyInt("fold");
|
||||||
|
|
||||||
|
If folding is enabled in the editor, fold will be TRUE and the lexer
|
||||||
|
should call:
|
||||||
|
|
||||||
|
styler.SetLevel(line, level);
|
||||||
|
|
||||||
|
at the end of each line and just before exiting.
|
||||||
|
|
||||||
|
The line parameter is simply the count of the number of newlines seen.
|
||||||
|
It's initial value is styler.GetLine(startPos) and it is incremented
|
||||||
|
(after calling styler.SetLevel) whenever a newline is seen.
|
||||||
|
|
||||||
|
The level parameter is the desired indentation level in the low 12 bits,
|
||||||
|
along with flag bits in the upper four bits. The indentation level
|
||||||
|
depends on the language. For C++, it is incremented when the lexer sees
|
||||||
|
a '{' and decremented when the lexer sees a '}' (outside of strings and
|
||||||
|
comments, of course).
|
||||||
|
|
||||||
|
The following flag bits, defined in Scintilla.h, may be set or cleared
|
||||||
|
in the flags parameter. The SC_FOLDLEVELWHITEFLAG flag is set if the
|
||||||
|
lexer considers that the line contains nothing but whitespace. The
|
||||||
|
SC_FOLDLEVELHEADERFLAG flag indicates that the line is a fold point.
|
||||||
|
This normally means that the next line has a greater level than present
|
||||||
|
line. However, the lexer may have some other basis for determining a
|
||||||
|
fold point. For example, a lexer might create a header line for the
|
||||||
|
first line of a function definition rather than the last.
|
||||||
|
|
||||||
|
The SC_FOLDLEVELNUMBERMASK mask denotes the level number in the low 12
|
||||||
|
bits of the level param. This mask may be used to isolate either flags
|
||||||
|
or level numbers.
|
||||||
|
|
||||||
|
For example, the C++ lexer contains the following code when a newline is
|
||||||
|
seen:
|
||||||
|
|
||||||
|
if (fold) {
|
||||||
|
int lev = levelPrev;
|
||||||
|
|
||||||
|
// Set the "all whitespace" bit if the line is blank.
|
||||||
|
if (visChars == 0)
|
||||||
|
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||||
|
|
||||||
|
// Set the "header" bit if needed.
|
||||||
|
if ((levelCurrent > levelPrev) && (visChars > 0))
|
||||||
|
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||||
|
styler.SetLevel(lineCurrent, lev);
|
||||||
|
|
||||||
|
// reinitialize the folding vars describing the present line.
|
||||||
|
lineCurrent++;
|
||||||
|
visChars = 0; // Number of non-whitespace characters on the line.
|
||||||
|
levelPrev = levelCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
The following code appears in the C++ lexer just before exit:
|
||||||
|
|
||||||
|
// Fill in the real level of the next line, keeping the current flags
|
||||||
|
// as they will be filled in later.
|
||||||
|
if (fold) {
|
||||||
|
// Mask off the level number, leaving only the previous flags.
|
||||||
|
int flagsNext = styler.LevelAt(lineCurrent);
|
||||||
|
flagsNext &= ~SC_FOLDLEVELNUMBERMASK;
|
||||||
|
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Don't worry about performance
|
||||||
|
|
||||||
|
The writer of a lexer may safely ignore performance considerations: the
|
||||||
|
cost of redrawing the screen is several orders of magnitude greater than
|
||||||
|
the cost of function calls, etc. Moreover, Scintilla performs all the
|
||||||
|
important optimizations; Scintilla ensures that a lexer will be called
|
||||||
|
only to recolor text that actually needs to be recolored. Finally, it
|
||||||
|
is not necessary to avoid extra calls to styler.ColourTo: the sytler
|
||||||
|
object buffers calls to ColourTo to avoid multiple updates of the
|
||||||
|
screen.
|
||||||
|
|
||||||
|
Page contributed by Edward K. Ream
|
||||||
70
third_party/qscintilla/doc/Scintilla/Privacy.html
vendored
Normal file
70
third_party/qscintilla/doc/Scintilla/Privacy.html
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta name="generator" content="SciTE" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>
|
||||||
|
Privacy Policy
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
|
<table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla
|
||||||
|
and SciTE</font></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h2>
|
||||||
|
Privacy Policy for scintilla.org
|
||||||
|
</h2>
|
||||||
|
<h3>
|
||||||
|
Information Collected
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Logs are collected to allow analysis of which pages are viewed.
|
||||||
|
The advertisements collect viewing information through Google Analytics which is
|
||||||
|
used by Google and advertisers.
|
||||||
|
No personally identifiable information is collected by scintilla.org.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
External Links
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Other web sites are linked to from this site.
|
||||||
|
These web sites have their own privacy policies which may differ significantly to those of scintilla.org.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Cookies
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
A cookie is a text file placed on the hard drive of a computer by some web pages which is used to remember
|
||||||
|
when a particular user returns to that site.
|
||||||
|
The advertisements shown on the main pages may use cookies.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Contact
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
This web site is the responsibility of Neil Hodgson.
|
||||||
|
Most queries about the site contents should go to one of the mailing lists mentioned on the main pages.
|
||||||
|
Queries about the privacy policy may be sent to neilh @ scintilla.org.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
Changes to this Policy
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
This policy may change. If it does then this page will be updated and the date at the bottom will change.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This policy was last updated 2 June 2015.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user