Browse Source

新建

master
hejl 2 months ago
parent
commit
70dae0124a
  1. 1
      CppServerProject
  2. 22
      cpp_server/.vscode/c_cpp_properties.json
  3. 9
      cpp_server/.vscode/settings.json
  4. 35
      cpp_server/CMakeLists.txt
  5. 1
      cpp_server/RuntimeCompiledCPlusPlus
  6. 7
      cpp_server/cmake/FindRCCPP.cmake
  7. 21
      cpp_server/src/controllers/UserController.cpp
  8. 22
      cpp_server/src/controllers/UserController.h
  9. 48
      cpp_server/src/main.cpp
  10. 2
      win_text_editor/lib/modules/template_parser/controllers/filter_controller.dart
  11. 2
      win_text_editor/lib/modules/template_parser/controllers/grid_view_controller.dart
  12. 2
      win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart
  13. 2
      win_text_editor/lib/modules/template_parser/controllers/tree_view_controller.dart
  14. 2
      win_text_editor/lib/modules/template_parser/widgets/grid_view.dart
  15. 2
      win_text_editor/lib/modules/template_parser/widgets/tree_view.dart
  16. 68
      win_text_editor/lib/modules/uft_file/controllers/tree_view_controller.dart
  17. 136
      win_text_editor/lib/modules/uft_file/controllers/uft_file_controller.dart
  18. 89
      win_text_editor/lib/modules/uft_file/widgets/tree_view.dart
  19. 67
      win_text_editor/lib/modules/uft_file/widgets/uft_file_view.dart
  20. 0
      win_text_editor/lib/shared/models/template_node.dart

1
CppServerProject

@ -0,0 +1 @@ @@ -0,0 +1 @@
Subproject commit 73cb76986ce1748eaee5ee6aee9c34a835d52fd5

22
cpp_server/.vscode/c_cpp_properties.json vendored

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"D:/aigc/vcpkg/installed/x64-windows/include/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.18362.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}

9
cpp_server/.vscode/settings.json vendored

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
{
"cmake.configureOnOpen": true,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.generator": "Visual Studio 16 2019 Win64",
"C_Cpp.default.cppStandard": "c++11",
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "D:/aigc/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}

35
cpp_server/CMakeLists.txt

@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
cmake_minimum_required(VERSION 3.15)
project(MyDrogonProject)
# C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#
find_package(Drogon CONFIG REQUIRED)
# RCC++
add_subdirectory(RuntimeCompiledCPlusPlus)
#
set(RUNTIME_COMPILED_SOURCES
src/controllers/UserController.cpp
)
#
add_executable(${PROJECT_NAME}
src/main.cpp
${RUNTIME_COMPILED_SOURCES}
)
# RCC++
runtime_compile_setup(
TARGET ${PROJECT_NAME}
SOURCES ${RUNTIME_COMPILED_SOURCES}
)
#
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)
# Swagger UI
file(COPY swagger DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

1
cpp_server/RuntimeCompiledCPlusPlus

@ -1 +0,0 @@ @@ -1 +0,0 @@
Subproject commit a93b46d32052f16f2f0e647ef180ac92afa88764

7
cpp_server/cmake/FindRCCPP.cmake

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
# RCC++
find_path(RCCPP_INCLUDE_DIR RuntimeObjectSystem.h
PATHS ${CMAKE_SOURCE_DIR}/RuntimeCompiledCPlusPlus/RuntimeObjectSystem
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RCCPP DEFAULT_MSG RCCPP_INCLUDE_DIR)

21
cpp_server/src/controllers/UserController.cpp

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
#include "UserController.h"
RCCPP_RUNTIME_TYPE_REGISTRATION(UserController)
/**
* @brief
* @route GET /api/v1/users
* @response 200 JSON
*/
void UserController::asyncHandleHttpRequest(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback)
{
Json::Value ret;
ret["status"] = "ok";
ret["message"] = "Hello from RCC++!";
ret["data"] = Json::arrayValue;
auto resp = drogon::HttpResponse::newHttpJsonResponse(ret);
callback(resp);
}

22
cpp_server/src/controllers/UserController.h

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
#pragma once
#include "RuntimeCompiledCPlusPlus/RuntimeObjectSystem/RuntimeObjectSystem.h"
#include <drogon/HttpSimpleController.h>
class UserController : public RCCpp::IObject,
public drogon::HttpSimpleController<UserController>
{
public:
UserController() { RCCpp::Construct(); }
virtual ~UserController() { RCCpp::Destruct(); }
RCCPP_RUNTIME_TYPE_DECLARATION(UserController)
void asyncHandleHttpRequest(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
PATH_ADD("/api/v1/users", drogon::Get);
PATH_LIST_END
};

48
cpp_server/src/main.cpp

@ -1,48 +0,0 @@ @@ -1,48 +0,0 @@
#include <drogon/drogon.h>
#include "RuntimeCompiledCPlusPlus/RuntimeObjectSystem/RuntimeObjectSystem.h"
#include "controllers/UserController.h"
class SystemTable : public RCCpp::ISystemTable
{
public:
virtual void Log(RCCpp::LogSystem::LogType type, const char *pText) override
{
if (type == RCCpp::LogSystem::ERROR)
LOG_ERROR << pText;
else
LOG_INFO << pText;
}
};
int main()
{
// 初始化RCC++
SystemTable systemTable;
RCCpp::RuntimeObjectSystem runtimeObjectSystem;
runtimeObjectSystem.Initialise(&systemTable, nullptr);
// 设置Swagger
drogon::app().registerController(std::make_shared<drogon::SwaggerController>());
// 加载热重载控制器
runtimeObjectSystem.GetObjectFactorySystem()->LoadObjectFactory(
"UserController", true);
// 设置文档路径
drogon::app().setDocumentRoot("./swagger");
drogon::app().setDocumentRoot("/api/v1/docs");
// 启动日志
LOG_INFO << "Server running on http://127.0.0.1:8848";
LOG_INFO << "Swagger UI: http://127.0.0.1:8848/api/v1/docs";
LOG_INFO << "Hot reload enabled - modify controller files to see changes";
// 主循环
drogon::app()
.addListener("0.0.0.0", 8848)
.setThreadNum(4)
.run();
runtimeObjectSystem.CleanObjectFiles();
return 0;
}

2
win_text_editor/lib/modules/template_parser/controllers/filter_controller.dart

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
// filter_controller.dart
import 'package:flutter/foundation.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import '../../../shared/base/safe_notifier.dart';
class FilterController extends SafeNotifier {

2
win_text_editor/lib/modules/template_parser/controllers/grid_view_controller.dart

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
// grid_view_controller.dart
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import '../../../shared/base/safe_notifier.dart';
class GridViewController extends SafeNotifier {

2
win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import 'package:file_picker/file_picker.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import 'package:xml/xml.dart' as xml;
import 'dart:io';

2
win_text_editor/lib/modules/template_parser/controllers/tree_view_controller.dart

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
// tree_view_controller.dart
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import '../../../shared/base/safe_notifier.dart';
class TreeViewController extends SafeNotifier {

2
win_text_editor/lib/modules/template_parser/widgets/grid_view.dart

@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:win_text_editor/modules/template_parser/controllers/grid_view_controller.dart';
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';

2
win_text_editor/lib/modules/template_parser/widgets/tree_view.dart

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/modules/template_parser/controllers/tree_view_controller.dart';
import 'package:win_text_editor/modules/template_parser/models/template_node.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import 'package:win_text_editor/shared/components/tree_view.dart';
class TemplateTreeView extends StatelessWidget {

68
win_text_editor/lib/modules/uft_file/controllers/tree_view_controller.dart

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
// tree_view_controller.dart
import 'package:win_text_editor/shared/models/template_node.dart';
import '../../../shared/base/safe_notifier.dart';
class TreeViewController extends SafeNotifier {
//
List<TemplateNode> _treeNodes = [];
TemplateNode? _selectedNode;
String? _currentParentPath;
List<TemplateNode> get treeNodes => _treeNodes;
TemplateNode? get selectedNode => _selectedNode;
//
void updateTreeNodes(List<TemplateNode> nodes) {
_treeNodes = nodes;
safeNotify();
}
void selectTreeNode(TemplateNode node) {
_selectedNode = node;
safeNotify();
}
// ,
void toggleNodeCheck(TemplateNode node) {
final parentPath = node.path.substring(0, node.path.lastIndexOf('/'));
if (_currentParentPath != null && _currentParentPath != parentPath) {
clearAllChecked();
}
node.isChecked = !node.isChecked;
_currentParentPath = parentPath;
safeNotify();
}
void clearAllChecked() {
void traverse(TemplateNode node) {
node.isChecked = false;
for (var child in node.children) {
traverse(child);
}
}
for (var node in _treeNodes) {
traverse(node);
}
}
List<String> get selectedNodeNames {
List<String> selectedNodeNames = [];
void traverse(TemplateNode node) {
if (node.isChecked) {
selectedNodeNames.add(node.name);
}
for (var child in node.children) {
traverse(child);
}
}
for (var node in _treeNodes) {
traverse(node);
}
return selectedNodeNames;
}
}

136
win_text_editor/lib/modules/uft_file/controllers/uft_file_controller.dart

@ -1,13 +1,145 @@ @@ -1,13 +1,145 @@
import 'package:file_picker/file_picker.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import 'package:xml/xml.dart' as xml;
import 'dart:io';
import 'tree_view_controller.dart';
class UftFileController extends BaseContentController {
final TreeViewController treeController;
String _filePath = '';
String? _errorMessage;
String get filePath => _filePath;
String? get errorMessage => _errorMessage;
//-------------------
UftFileController() : treeController = TreeViewController() {
_setupCrossControllerCommunication();
}
//
void _setupCrossControllerCommunication() {}
//---------------------
//widget调用入口
Future<void> pickFile() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['xml', '*'],
);
if (result != null) {
_filePath = result.files.single.path!;
notifyListeners(); // Consumer
await _loadTemplateData();
}
}
//
Future<void> setFilePath(String path) async {
_filePath = path;
notifyListeners(); // Consumer
await _loadTemplateData();
}
//xml文件
Future<void> _loadTemplateData() async {
try {
_errorMessage = null;
final file = File(_filePath);
final content = await file.readAsString();
final document = xml.XmlDocument.parse(content);
//
//
treeController.updateTreeNodes(
_buildTreeNodes(document.rootElement, document.rootElement.localName, depth: 0),
);
//
} catch (e) {
_errorMessage = 'Failed to load XML: ${e.toString()}';
Logger().error('XML加载错误$_errorMessage');
}
}
//-----------------------------
//
List<TemplateNode> _buildTreeNodes(
xml.XmlElement element,
String path, {
required int depth,
int repreatCount = 1,
}) {
final node = TemplateNode(
path: path,
name: element.qualifiedName,
children: [],
depth: depth,
isExpanded: depth < 5, //
isRepeated: repreatCount > 1,
repreatCount: repreatCount,
);
//
if (element.attributes.isNotEmpty) {
node.children.addAll(
element.attributes.map(
(attr) => TemplateNode(
path: '$path/@${attr.name.local}',
name: '@${attr.qualifiedName}',
children: [],
depth: depth + 1,
isAttribute: true,
),
),
);
}
//
final childElements = element.children.whereType<xml.XmlElement>();
final groupedChildren = <String, List<xml.XmlElement>>{};
//
for (var child in childElements) {
groupedChildren.putIfAbsent(child.name.local, () => []).add(child);
}
//
groupedChildren.forEach((name, elements) {
String path0 = '$path/${elements.first.name.local}';
if (elements.length == 1) {
//
node.children.addAll(_buildTreeNodes(elements.first, path0, depth: depth + 1));
} else {
//
node.children.addAll(
_buildTreeNodes(elements.first, path0, depth: depth + 1, repreatCount: elements.length),
);
}
});
return [node];
}
//
//-------------
@override
void onOpenFile(String filePath) {
// TODO: implement onOpenFile
setFilePath(filePath);
}
@override
void onOpenFolder(String folderPath) {
// TODO: implement onOpenFolder
//
}
@override
void dispose() {
treeController.dispose();
super.dispose();
}
}

89
win_text_editor/lib/modules/uft_file/widgets/tree_view.dart

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/modules/uft_file/controllers/tree_view_controller.dart';
import 'package:win_text_editor/shared/models/template_node.dart';
import 'package:win_text_editor/shared/components/tree_view.dart';
class FileTreeView extends StatelessWidget {
const FileTreeView({super.key});
@override
Widget build(BuildContext context) {
return Consumer<TreeViewController>(
builder: (context, controller, _) {
if (controller.treeNodes.isEmpty) {
return const Center(child: Text('No XML data available'));
}
return TreeView(
nodes: controller.treeNodes,
config: const TreeViewConfig(
showIcons: true,
singleSelect: true,
selectedColor: Colors.lightBlueAccent,
icons: {'element': Icons.label_outline, 'attribute': Icons.code},
),
onNodeTap: (node) {
controller.selectTreeNode;
},
nodeBuilder: (context, node, isSelected, onTap) {
return _buildTreeNode(node, isSelected, onTap, controller);
},
);
},
);
}
Widget _buildTreeNode(
TreeNode node,
bool isSelected,
VoidCallback onTap,
TreeViewController controller,
) {
final templateNode = node as TemplateNode;
final isAttribute = node.isAttribute;
final isActuallySelected = controller.selectedNode?.id == templateNode.id;
return Container(
color: isActuallySelected ? Colors.lightBlueAccent.withOpacity(0.2) : Colors.transparent,
child: Padding(
padding: EdgeInsets.only(left: 12.0 * node.depth),
child: ListTile(
dense: true,
leading: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (templateNode.children.isEmpty) //
Checkbox(
value: templateNode.isChecked,
onChanged: (value) {
if (value != null) {
controller.toggleNodeCheck(templateNode);
}
},
),
isAttribute
? const Icon(Icons.code, size: 16, color: Colors.grey)
: const Icon(Icons.label_outline, size: 18, color: Colors.blue),
],
),
title: Text(
isAttribute ? templateNode.name.substring(1) : templateNode.name,
style: TextStyle(
color: isAttribute ? Colors.grey[600] : Colors.black,
fontWeight: isAttribute ? FontWeight.normal : FontWeight.w500,
),
),
trailing:
templateNode.isRepeated
? Text(
"(${templateNode.repreatCount.toString()})",
style: const TextStyle(color: Colors.grey),
)
: null,
onTap: onTap,
),
),
);
}
}

67
win_text_editor/lib/modules/uft_file/widgets/uft_file_view.dart

@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/framework/controllers/tab_items_controller.dart';
import 'package:win_text_editor/modules/uft_file/controllers/uft_file_controller.dart';
import 'package:win_text_editor/modules/uft_file/widgets/tree_view.dart';
class UftFileView extends StatefulWidget {
final String tabId;
@ -13,6 +14,7 @@ class UftFileView extends StatefulWidget { @@ -13,6 +14,7 @@ class UftFileView extends StatefulWidget {
class _UftFileViewState extends State<UftFileView> {
late final UftFileController _controller;
bool _isControllerFromTabManager = false;
get tabManager => Provider.of<TabItemsController>(context, listen: false);
@ -42,6 +44,69 @@ class _UftFileViewState extends State<UftFileView> { @@ -42,6 +44,69 @@ class _UftFileViewState extends State<UftFileView> {
@override
Widget build(BuildContext context) {
return const Center(child: Text('demo'));
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _controller),
ChangeNotifierProvider.value(value: _controller.treeController),
],
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
_buildFilePathInput(),
const SizedBox(height: 8),
Expanded(child: _buildMainContent()),
],
),
),
);
}
Widget _buildFilePathInput() {
return Consumer<UftFileController>(
builder: (context, controller, _) {
return TextField(
decoration: InputDecoration(
labelText: 'UFT File',
hintText: 'UFT File (包括服务、原子层代码文件)',
suffixIcon: IconButton(
icon: const Icon(Icons.folder_open),
onPressed: controller.pickFile,
),
border: const OutlineInputBorder(),
errorText: controller.errorMessage,
),
controller: TextEditingController(text: controller.filePath),
readOnly: true,
);
},
);
}
Widget _buildMainContent() {
return Consumer<UftFileController>(
builder: (context, controller, _) {
if (controller.errorMessage != null) {
return Center(child: Text(controller.errorMessage!));
}
return Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: const Column(
children: [
Expanded(flex: 2, child: Card(child: FileTreeView())),
SizedBox(height: 8),
Expanded(flex: 4, child: Card(child: Text("UFT File Content1"))),
],
),
),
const SizedBox(width: 8),
const Expanded(child: Card(child: Text("UFT File Content2"))),
],
);
},
);
}
}

0
win_text_editor/lib/modules/template_parser/models/template_node.dart → win_text_editor/lib/shared/models/template_node.dart

Loading…
Cancel
Save