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