Compare commits

...

3 Commits

  1. 56
      win_text_editor/assets/config/uft_macro_list.yaml
  2. 2
      win_text_editor/assets/config/words_classes.yaml
  3. 79
      win_text_editor/lib/main copy.dart
  4. 12
      win_text_editor/lib/menus/app_menu.dart
  5. 5
      win_text_editor/lib/menus/menu_actions.dart
  6. 2
      win_text_editor/lib/menus/menu_constants.dart
  7. 8
      win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart
  8. 9
      win_text_editor/lib/modules/call_function/models/call_function.dart
  9. 12
      win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart
  10. 25
      win_text_editor/lib/modules/code_creater/controllers/code_creater_controller.dart
  11. 240
      win_text_editor/lib/modules/code_creater/widgets/code_creater_view.dart
  12. 6
      win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart
  13. 6
      win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart
  14. 6
      win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart
  15. 6
      win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart
  16. 6
      win_text_editor/lib/modules/demo/controllers/demo_controller.dart
  17. 8
      win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart
  18. 17
      win_text_editor/lib/modules/memory_table/models/memory_table.dart
  19. 15
      win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart
  20. 5
      win_text_editor/lib/modules/module_router.dart
  21. 33
      win_text_editor/lib/modules/outline/models/code_partner.dart
  22. 3
      win_text_editor/lib/modules/outline/models/outline_node.dart
  23. 6
      win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart
  24. 8
      win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart
  25. 17
      win_text_editor/lib/modules/uft_component/models/uft_component.dart
  26. 16
      win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart
  27. 6
      win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart
  28. 3
      win_text_editor/lib/shared/base/base_content_controller.dart
  29. 82
      win_text_editor/lib/shared/components/code_generation_components.dart
  30. 91
      win_text_editor/lib/shared/components/tree_view.dart
  31. 22
      win_text_editor/lib/test.dart
  32. 20
      win_text_editor/pubspec.lock
  33. 2
      win_text_editor/pubspec.yaml

56
win_text_editor/assets/config/uft_macro_list.yaml

@ -4,11 +4,11 @@ templates: @@ -4,11 +4,11 @@ templates:
body: |
<M>[获取记录][{{tableName}}({{keyName}})][
{{#keyFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/keyFields}}
][
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
[继续执行]
@ -16,7 +16,7 @@ templates: @@ -16,7 +16,7 @@ templates:
{
[报错返回][ERR_???][{{#keyFields}}{{name}} = @{{name}}{{^isLast}}, {{/isLast}}{{/keyFields}}]
}else{
//balabala
}
@ -27,7 +27,7 @@ templates: @@ -27,7 +27,7 @@ templates:
body: |
<C>[插入记录][{{tableName}}][
{{#fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/fields}}
]
[索引冲突]
@ -42,13 +42,13 @@ templates: @@ -42,13 +42,13 @@ templates:
[修改记录][{{tableName}}][
{{#fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/fields}}
]
<F>[修改索引字段][{{tableName}}][
{{#keyFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/keyFields}}
]
}
@ -57,7 +57,7 @@ templates: @@ -57,7 +57,7 @@ templates:
body: |
<M>[获取记录][{{tableName}}({{keyName}})][
{{#keyFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/keyFields}}
]
[继续执行]
@ -65,13 +65,13 @@ templates: @@ -65,13 +65,13 @@ templates:
{
[修改记录][{{tableName}}][
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
<F>[修改索引字段][{{tableName}}][
{{#keyFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/keyFields}}
]
}
@ -80,7 +80,7 @@ templates: @@ -80,7 +80,7 @@ templates:
body: |
<M>[获取记录][{{tableName}}({{keyName}})][
{{#keyFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/keyFields}}
]
[继续执行]
@ -93,11 +93,11 @@ templates: @@ -93,11 +93,11 @@ templates:
body: |
[遍历记录开始][{{tableName}}({{selectIndexOrKey.name}})][
{{#selectIndexOrKey.fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/selectIndexOrKey.fields}}
][
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
{
@ -109,7 +109,7 @@ templates: @@ -109,7 +109,7 @@ templates:
body: |
[插入组件][{{name}}][0][
{{#fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/fields}}
]
@ -117,7 +117,7 @@ templates: @@ -117,7 +117,7 @@ templates:
body: |
[修改组件][{{name}}][@num][
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
@ -127,12 +127,12 @@ templates: @@ -127,12 +127,12 @@ templates:
[获取组件][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][{{^hasIndex}}[@num][{{/hasIndex}}
{{#hasIndex}}
{{#index.fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/index.fields}}
][
{{/hasIndex}}
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
@ -142,12 +142,12 @@ templates: @@ -142,12 +142,12 @@ templates:
[遍历组件开始][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][
{{#hasIndex}}
{{#index.fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/index.fields}}
{{/hasIndex}}
][
{{#selectedFields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/selectedFields}}
]
{
@ -162,7 +162,7 @@ templates: @@ -162,7 +162,7 @@ templates:
body: |
[插入组件][{{name}}][
{{#fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}}
{{/fields}}
]
@ -177,7 +177,7 @@ templates: @@ -177,7 +177,7 @@ templates:
{{/hasIndex}}
][
{{#fields}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}}, {{/isLast}}
{{/fields}}
]
{
@ -187,18 +187,18 @@ templates: @@ -187,18 +187,18 @@ templates:
普通调用:
body: |
<M>[{{chineseName}}][
<Z>[{{chineseName}}][
{{#input}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}}
{{/input}}
][
{{#output}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}},{{/isLast}}
{{/output}}
]
[处理失败]
{
[获取错误信息][@error_no][@error_info][@error_pathinfo]
[错误信息获取]
//TODO:处理异常
[继续执行]
@ -211,18 +211,18 @@ templates: @@ -211,18 +211,18 @@ templates:
事务调用:
body: |
[事务处理开始]
<M>[{{chineseName}}][
<Z>[{{chineseName}}][
{{#input}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}}
{{/input}}
][
{{#output}}
{{name}} = @{{name}} {{^isLast}}, {{/isLast}}
{{name}} = @{{name}}{{^isLast}},{{/isLast}}
{{/output}}
]
[处理失败]
{
[获取错误信息][@error_no][@error_info][@error_pathinfo]
[错误信息获取]
//TODO:处理异常
[事务回滚]
[继续执行]

2
win_text_editor/assets/config/words_classes.yaml

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
outline_name_black_list:
- 历史,日志,名称,比例,数量,金额,次数,属性,对应,分类,姓名,单位,总数,行使,子项,占比,记录,列表,目标,字段,字符串,动作,方式
- 历史,日志,名称,比例,数量,金额,次数,属性,对应,分类,姓名,单位,总数,行使,子项,占比,记录,列表,目标,字段,字符串,动作,方式,类型,类别

79
win_text_editor/lib/main copy.dart

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
void main2() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: DragIconDemo());
}
}
class DragIconDemo extends StatefulWidget {
@override
_DragIconDemoState createState() => _DragIconDemoState();
}
class _DragIconDemoState extends State<DragIconDemo> {
// 12
int iconContainer = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('图标拖拽示例')),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//
buildContainer(
containerNumber: 1,
child: iconContainer == 1 ? buildDraggableIcon() : null,
),
//
buildContainer(
containerNumber: 2,
child: iconContainer == 2 ? buildDraggableIcon() : null,
),
],
),
);
}
//
Widget buildDraggableIcon() {
return Draggable<int>(
data: iconContainer, //
feedback: const Icon(Icons.star, size: 50, color: Colors.amber),
childWhenDragging: const Opacity(
opacity: 0.5,
child: Icon(Icons.star, size: 50, color: Colors.amber),
),
child: const Icon(Icons.star, size: 50, color: Colors.amber),
);
}
//
Widget buildContainer({required int containerNumber, Widget? child}) {
return DragTarget<int>(
builder: (context, candidateData, rejectedData) {
return Container(
width: 150,
height: 150,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(10),
),
child: Center(child: child),
);
},
onWillAcceptWithDetails: (data) => true, //
onAcceptWithDetails: (data) {
setState(() {
iconContainer = containerNumber; //
});
},
);
}
}

12
win_text_editor/lib/menus/app_menu.dart

@ -53,7 +53,7 @@ class AppMenu extends StatelessWidget { @@ -53,7 +53,7 @@ class AppMenu extends StatelessWidget {
const PopupMenuDivider(),
const PopupMenuItem<String>(
value: MenuConstants.demo,
child: ListTile(leading: Icon(Icons.code), title: Text('Demo')),
child: ListTile(leading: Icon(Icons.view_agenda), title: Text('Demo')),
),
];
}
@ -72,11 +72,11 @@ class AppMenu extends StatelessWidget { @@ -72,11 +72,11 @@ class AppMenu extends StatelessWidget {
value: MenuConstants.callFunction,
child: ListTile(leading: Icon(Icons.functions), title: Text('功能号调用')),
),
// const PopupMenuDivider(),
// const PopupMenuItem<String>(
// value: MenuConstants.outline,
// child: ListTile(leading: Icon(Icons.outlined_flag_rounded), title: Text('大纲')),
// ),
const PopupMenuDivider(),
const PopupMenuItem<String>(
value: MenuConstants.codeCreater,
child: ListTile(leading: Icon(Icons.code), title: Text('代码生成器')),
),
];
}

5
win_text_editor/lib/menus/menu_actions.dart

@ -22,6 +22,7 @@ class MenuActions { @@ -22,6 +22,7 @@ class MenuActions {
MenuConstants.callFunction: _callFunction,
MenuConstants.demo: _demo,
MenuConstants.outline: _outline,
MenuConstants.codeCreater: _codeCreater,
MenuConstants.exit: _exitApplication,
};
@ -84,6 +85,10 @@ class MenuActions { @@ -84,6 +85,10 @@ class MenuActions {
await _openOrActivateTab(context, "Demo", RouterKey.demo, Icons.code);
}
static Future<void> _codeCreater(BuildContext context) async {
await _openOrActivateTab(context, "代码生成器", RouterKey.codeCreater, Icons.code);
}
static Future<void> _outline(BuildContext context) async {
await _openOrActivateTab(context, "大纲", RouterKey.outline, Icons.outlined_flag_rounded);
}

2
win_text_editor/lib/menus/menu_constants.dart

@ -46,4 +46,6 @@ class MenuConstants { @@ -46,4 +46,6 @@ class MenuConstants {
//
static const String about = 'about';
static const String help = 'help';
static const String codeCreater = 'code_creater';
}

8
win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart

@ -4,6 +4,8 @@ import 'package:win_text_editor/framework/controllers/logger.dart'; @@ -4,6 +4,8 @@ import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/framework/services/macro_template_service.dart';
import 'package:win_text_editor/modules/call_function/models/call_function.dart';
import 'package:win_text_editor/modules/call_function/services/call_function_service.dart';
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/uft_std_fields/field_data_source.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
@ -122,4 +124,10 @@ class CallFunctionController extends BaseContentController { @@ -122,4 +124,10 @@ class CallFunctionController extends BaseContentController {
void onOpenFolder(String folderPath) {
//
}
@override
void onDropOutlineNode(OutlineNode node) {
modle.codePartners.add(CodePartner.fromOutlineNode(node));
notifyListeners();
}
}

9
win_text_editor/lib/modules/call_function/models/call_function.dart

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/modules/uft_component/models/uft_component.dart';
import 'package:win_text_editor/shared/models/std_filed.dart';
@ -10,6 +11,7 @@ class CallFunction { @@ -10,6 +11,7 @@ class CallFunction {
final List<Field> outputParameters;
List<UftComponent>? componentList;
String? factorParam;
final List<CodePartner> codePartners = [];
CallFunction({
required this.functionType,
@ -36,6 +38,13 @@ class CallFunction { @@ -36,6 +38,13 @@ class CallFunction {
'chineseName': field.chineseName,
'type': field.type,
'isLast': inputParameters.indexOf(field) == inputParameters.length - 1,
'partnerName':
codePartners
.firstWhere(
(partner) => partner.fields.any((f) => f == field.name),
orElse: () => CodePartner(name: null, fields: []),
)
.name,
},
)
.toList(),

12
win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart

@ -7,11 +7,7 @@ class CallFunctionRightSide extends StatefulWidget { @@ -7,11 +7,7 @@ class CallFunctionRightSide extends StatefulWidget {
final CallFunctionController controller;
final TextEditingController codeController;
const CallFunctionRightSide({
super.key,
required this.controller,
required this.codeController,
});
const CallFunctionRightSide({super.key, required this.controller, required this.codeController});
@override
State<CallFunctionRightSide> createState() => _CallFunctionRightSideState();
@ -35,11 +31,10 @@ class _CallFunctionRightSideState extends State<CallFunctionRightSide> { @@ -35,11 +31,10 @@ class _CallFunctionRightSideState extends State<CallFunctionRightSide> {
void _updateDisplay() {
if (_selectedOperation != null) {
widget.codeController.text =
widget.controller.genCodeString([_selectedOperation!]) ?? '';
widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? '';
} else {
widget.codeController.text = '';
}
}
}
void _selectOperation(String? operation) {
@ -56,6 +51,7 @@ class _CallFunctionRightSideState extends State<CallFunctionRightSide> { @@ -56,6 +51,7 @@ class _CallFunctionRightSideState extends State<CallFunctionRightSide> {
return CodeGenerationSection(
title: '生成代码',
codeController: widget.codeController,
onNodeDropped: (node) => widget.controller.onDropOutlineNode(node),
child: OperationRadioSection(
operations: operations,
selectedOperation: _selectedOperation,

25
win_text_editor/lib/modules/code_creater/controllers/code_creater_controller.dart

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
class CodeCreaterController extends BaseContentController {
List<OutlineNode> members = [];
@override
void onOpenFile(String filePath, {dynamic appendArg}) {
// TODO: implement onOpenFile
}
@override
void onOpenFolder(String folderPath) {
// TODO: implement onOpenFolder
}
@override
void onDropOutlineNode(OutlineNode node) {
members.add(node);
notifyListeners();
}
genCodeString(List<String> list) {}
}

240
win_text_editor/lib/modules/code_creater/widgets/code_creater_view.dart

@ -0,0 +1,240 @@ @@ -0,0 +1,240 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:pluto_grid/pluto_grid.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/framework/controllers/tab_items_controller.dart';
import 'package:win_text_editor/modules/code_creater/controllers/code_creater_controller.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/components/code_generation_components.dart';
import 'package:win_text_editor/shared/components/my_pluto_column.dart';
import 'package:win_text_editor/shared/components/my_pluto_configuration.dart';
class CodeCreaterView extends StatefulWidget {
final String tabId;
const CodeCreaterView({super.key, required this.tabId});
@override
State<CodeCreaterView> createState() => _CodeCreaterViewState();
}
class _CodeCreaterViewState extends State<CodeCreaterView> {
late final CodeCreaterController _controller;
bool _isControllerFromTabManager = false;
PlutoGridStateManager? _stateManager;
final List<String> operations = ['逻辑服务', '逻辑函数', '原子服务', '原子函数'];
final TextEditingController _codeController = TextEditingController();
String? _selectedOperation = '原子函数';
get tabManager => Provider.of<TabItemsController>(context, listen: false);
final ScrollController _scrollController = ScrollController();
//
double _calculateTableWidth() {
const columnSpacing = 16.0;
double totalWidth = 0;
for (var column in _buildColumns()) {
totalWidth += column.width + columnSpacing;
}
return totalWidth + 100; //
}
@override
void initState() {
super.initState();
final controllerFromManager = tabManager.getController(widget.tabId);
if (controllerFromManager != null) {
_controller = controllerFromManager;
_isControllerFromTabManager = true;
} else {
_controller = CodeCreaterController();
_isControllerFromTabManager = false;
tabManager.registerController(widget.tabId, _controller);
}
_controller.addListener(_handleControllerUpdate); //
}
void _handleControllerUpdate() {
setState(() {}); // UI
}
@override
void dispose() {
_controller.removeListener(_handleControllerUpdate); //
_scrollController.dispose(); //
if (!_isControllerFromTabManager) {
_controller.dispose();
}
_codeController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
// PlutoGrid (40%)
Expanded(
flex: 4,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
PointerDeviceKind.trackpad,
},
),
child: Scrollbar(
controller: _scrollController, //
thickness: 12.0,
thumbVisibility: true,
interactive: true, // Windows必须设置为true
child: SingleChildScrollView(
controller: _scrollController, // 使
scrollDirection: Axis.horizontal,
child: SizedBox(
width: _calculateTableWidth(), //
child: PlutoGrid(
key: ValueKey('pluto_grid_${_controller.members.length}'),
configuration: MyPlutoGridConfiguration(),
columns: _buildColumns(),
mode: PlutoGridMode.normal,
rows: _controller.members.isEmpty ? [] : _buildRows(_controller),
noRowsWidget: const Center(child: Text('无大纲节点')),
onLoaded: (PlutoGridOnLoadedEvent event) {
_stateManager ??= event.stateManager;
},
),
),
),
),
),
),
),
// CodeGenerationSection (60%)
Expanded(
flex: 6,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: CodeGenerationSection(
title: '生成代码',
codeController: _codeController,
onNodeDropped: (node) => _controller.onDropOutlineNode(node),
child: OperationRadioSection(
operations: operations,
selectedOperation: _selectedOperation,
onOperationSelected: _selectOperation,
),
),
),
),
],
);
}
List<PlutoColumn> _buildColumns() {
return [
MyPlutoColumn(title: '#', field: 'rowNum', width: 40),
MyPlutoColumn(title: '成员', field: 'content', type: PlutoColumnType.text(), width: 300),
MyPlutoColumn(title: '选择类型', field: 'type', editable: true, width: 200),
MyPlutoColumn(
title: '操作',
field: 'action',
width: 150,
renderer: (rendererContext) {
final result = rendererContext.row.cells['action']!.value as OutlineNode;
final index = rendererContext.row.cells['rowNum']!.value - 1;
final canMoveUp = index > 0;
final canMoveDown = index < _controller.members.length - 1;
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(
Icons.arrow_upward,
size: 12,
color: canMoveUp ? Colors.blue : Colors.grey,
),
onPressed:
canMoveUp ? () => _moveMember(context, rendererContext.row, result, -1) : null,
),
IconButton(
icon: Icon(
Icons.arrow_downward,
size: 12,
color: canMoveDown ? Colors.blue : Colors.grey,
),
onPressed:
canMoveDown ? () => _moveMember(context, rendererContext.row, result, 1) : null,
),
IconButton(
icon: const Icon(Icons.delete_forever, size: 12, color: Colors.red),
onPressed: () => _deleteMember(context, rendererContext.row, result),
),
],
);
},
),
];
}
void _moveMember(BuildContext context, PlutoRow row, OutlineNode result, int direction) {
final index = row.cells['rowNum']!.value - 1;
final newIndex = index + direction;
if (newIndex >= 0 && newIndex < _controller.members.length) {
setState(() {
final member = _controller.members.removeAt(index);
_controller.members.insert(newIndex, member);
_controller.notifyListeners(); //
});
}
}
List<PlutoRow> _buildRows(CodeCreaterController controller) {
return [
...controller.members.asMap().entries.map((entry) {
final index = entry.key;
final member = entry.value;
return PlutoRow(
key: ValueKey('${member.hashCode}_$index'), // key确保唯一性
cells: {
'rowNum': PlutoCell(value: index + 1),
'content': PlutoCell(value: member.title),
'type': PlutoCell(value: member.value),
'action': PlutoCell(value: member),
},
);
}),
];
}
void _selectOperation(String? operation) {
setState(() {
_selectedOperation = operation;
_updateDisplay();
});
}
void _updateDisplay() {
if (_selectedOperation != null) {
_codeController.text = _controller.genCodeString([_selectedOperation!]) ?? '';
} else {
_codeController.text = '';
}
}
void _deleteMember(BuildContext context, PlutoRow row, OutlineNode result) {}
}

6
win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart

@ -9,6 +9,7 @@ import 'package:win_text_editor/modules/content_search/models/search_mode.dart'; @@ -9,6 +9,7 @@ import 'package:win_text_editor/modules/content_search/models/search_mode.dart';
import 'package:win_text_editor/modules/content_search/models/search_result.dart';
import 'package:win_text_editor/modules/content_search/services/count_search_service.dart';
import 'package:win_text_editor/modules/content_search/services/locate_search_service.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import '../services/custom_search_service.dart';
@ -254,4 +255,9 @@ class ContentSearchController extends BaseContentController { @@ -254,4 +255,9 @@ class ContentSearchController extends BaseContentController {
void onOpenFolder(String folderPath) {
searchDirectory = folderPath;
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

6
win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart

@ -2,6 +2,7 @@ import 'dart:io'; @@ -2,6 +2,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
class DataCompareController extends BaseContentController {
@ -249,4 +250,9 @@ class DataCompareController extends BaseContentController { @@ -249,4 +250,9 @@ class DataCompareController extends BaseContentController {
void onOpenFolder(String folderPath) {
// TODO: implement onOpenFolder
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

6
win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart

@ -3,6 +3,7 @@ import 'package:win_text_editor/framework/controllers/logger.dart'; @@ -3,6 +3,7 @@ import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/data_extract/models/search_result.dart';
import 'package:win_text_editor/modules/data_extract/models/xml_rule.dart';
import 'package:win_text_editor/modules/data_extract/services/xml_extract_service.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
class DataExtractController extends BaseContentController {
@ -90,4 +91,9 @@ class DataExtractController extends BaseContentController { @@ -90,4 +91,9 @@ class DataExtractController extends BaseContentController {
}
void cancelExtraction() {}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

6
win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/data_format/services/mustache_service.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import 'grid_view_controller.dart';
@ -107,4 +108,9 @@ class DataFormatController extends BaseContentController { @@ -107,4 +108,9 @@ class DataFormatController extends BaseContentController {
gridController.dispose();
super.dispose();
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

6
win_text_editor/lib/modules/demo/controllers/demo_controller.dart

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
class DemoController extends BaseContentController {
@ -10,4 +11,9 @@ class DemoController extends BaseContentController { @@ -10,4 +11,9 @@ class DemoController extends BaseContentController {
void onOpenFolder(String folderPath) {
// TODO: implement onOpenFolder
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

8
win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/framework/services/macro_template_service.dart';
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/shared/models/std_filed.dart';
import 'package:win_text_editor/shared/uft_std_fields/field_data_source.dart';
import 'package:win_text_editor/modules/memory_table/controllers/index_data_source.dart';
@ -131,4 +133,10 @@ class MemoryTableController extends BaseContentController { @@ -131,4 +133,10 @@ class MemoryTableController extends BaseContentController {
void dispose() {
super.dispose();
}
@override
void onDropOutlineNode(OutlineNode node) {
_memoryTable.codePartners.add(CodePartner.fromOutlineNode(node));
notifyListeners();
}
}

17
win_text_editor/lib/modules/memory_table/models/memory_table.dart

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/shared/base/selectable_item.dart';
import 'package:win_text_editor/shared/models/std_filed.dart';
@ -10,7 +11,6 @@ class Index implements SelectableItem { @@ -10,7 +11,6 @@ class Index implements SelectableItem {
final String rule;
@override
bool isSelected;
String get id => indexName;
List<String> get fields => indexFields.split(',').map((e) => e.trim()).toList();
@ -20,6 +20,7 @@ class MemoryTable { @@ -20,6 +20,7 @@ class MemoryTable {
final String tableName;
final List<Field> columns;
final List<Index> indexes;
final List<CodePartner> codePartners = [];
MemoryTable({required this.tableName, required this.columns, required this.indexes});
@ -79,6 +80,13 @@ class MemoryTable { @@ -79,6 +80,13 @@ class MemoryTable {
'chineseName': field.chineseName,
'type': field.type,
'isLast': columns.indexOf(field) == columns.length - 1,
'partnerName':
codePartners
.firstWhere(
(partner) => partner.fields.any((f) => f == field.name),
orElse: () => CodePartner(name: null, fields: []),
)
.name,
},
)
.toList(),
@ -91,6 +99,13 @@ class MemoryTable { @@ -91,6 +99,13 @@ class MemoryTable {
'chineseName': field.chineseName,
'type': field.type,
'isLast': selectFields.indexOf(field) == selectFields.length - 1,
'partnerName':
codePartners
.firstWhere(
(partner) => partner.fields.any((f) => f == field.name),
orElse: () => CodePartner(name: null, fields: []),
)
.name,
},
)
.toList(),

15
win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
// memory_table_right_side.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart';
import 'package:win_text_editor/shared/components/code_generation_components.dart';
@ -8,11 +7,7 @@ class MemoryTableRightSide extends StatefulWidget { @@ -8,11 +7,7 @@ class MemoryTableRightSide extends StatefulWidget {
final MemoryTableController controller;
final TextEditingController codeController;
const MemoryTableRightSide({
super.key,
required this.controller,
required this.codeController,
});
const MemoryTableRightSide({super.key, required this.controller, required this.codeController});
@override
State<MemoryTableRightSide> createState() => _MemoryTableRightSideState();
@ -36,8 +31,7 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> { @@ -36,8 +31,7 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
void _updateDisplay() {
if (_selectedOperation != null) {
widget.codeController.text =
widget.controller.genCodeString([_selectedOperation!]) ?? '';
widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? '';
} else {
widget.codeController.text = '';
}
@ -52,13 +46,12 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> { @@ -52,13 +46,12 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
@override
Widget build(BuildContext context) {
final operations = [
'获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录'
];
final operations = ['获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录'];
return CodeGenerationSection(
title: '生成代码',
codeController: widget.codeController,
onNodeDropped: (node) => widget.controller.onDropOutlineNode(node),
child: OperationRadioSection(
operations: operations,
selectedOperation: _selectedOperation,

5
win_text_editor/lib/modules/module_router.dart

@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; @@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:win_text_editor/framework/models/tab_model.dart';
import 'package:win_text_editor/modules/call_function/controllers/call_function_controller.dart';
import 'package:win_text_editor/modules/call_function/widgets/call_function_view.dart';
import 'package:win_text_editor/modules/code_creater/controllers/code_creater_controller.dart';
import 'package:win_text_editor/modules/code_creater/widgets/code_creater_view.dart';
import 'package:win_text_editor/modules/data_compare/controllers/data_compare_controller.dart';
import 'package:win_text_editor/modules/data_compare/widgets/data_compare_view.dart';
import 'package:win_text_editor/modules/data_extract/controllers/data_extract_controller.dart';
@ -36,6 +38,7 @@ class RouterKey { @@ -36,6 +38,7 @@ class RouterKey {
static const String callFunction = 'call_function';
static const String outline = 'outline';
static const String demo = 'demo';
static const String codeCreater = 'code_creater';
}
class ModuleRouter {
@ -51,6 +54,7 @@ class ModuleRouter { @@ -51,6 +54,7 @@ class ModuleRouter {
RouterKey.uftComponent: (tab) => UftComponentController(),
RouterKey.callFunction: (tab) => CallFunctionController(),
RouterKey.demo: (tab) => DemoController(),
RouterKey.codeCreater: (tab) => CodeCreaterController(),
};
// UI组件
@ -65,6 +69,7 @@ class ModuleRouter { @@ -65,6 +69,7 @@ class ModuleRouter {
RouterKey.uftComponent: (tab, controller) => UftComponentView(tabId: tab.id),
RouterKey.callFunction: (tab, controller) => CallFunctionView(tabId: tab.id),
RouterKey.demo: (tab, controller) => DemoView(tabId: tab.id),
RouterKey.codeCreater: (tab, controller) => CodeCreaterView(tabId: tab.id),
};
static BaseContentController? createControllerForTab(AppTab tab) {

33
win_text_editor/lib/modules/outline/models/code_partner.dart

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
import 'package:path/path.dart' as path;
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/modules/outline/services/component_service.dart';
import 'package:win_text_editor/modules/outline/services/uft_object_service.dart';
class CodePartner {
final String? name;
final List<String> fields;
CodePartner({required this.name, required this.fields});
factory CodePartner.fromOutlineNode(OutlineNode node) {
String? name;
List<String> fields = [];
switch (node.value) {
case "UFTTable":
final List<String>? values = UftObjectService.uftObjectMap[node.title];
if (values != null && values.isNotEmpty) {
name = path.basenameWithoutExtension(values[0]);
fields.addAll(values.sublist(1));
}
break;
case "Component":
name = node.name;
final List<String>? values = ComponentService.componentFieldMap[node.name];
if (values != null && values.isNotEmpty) {
fields.addAll(values.sublist(1));
}
break;
}
return CodePartner(name: name, fields: fields);
}
}

3
win_text_editor/lib/modules/outline/models/outline_node.dart

@ -21,6 +21,7 @@ class OutlineNode implements TreeNode { @@ -21,6 +21,7 @@ class OutlineNode implements TreeNode {
bool isExpanded;
final int frequency;
@override
late String id;
final String value;
@ -39,7 +40,7 @@ class OutlineNode implements TreeNode { @@ -39,7 +40,7 @@ class OutlineNode implements TreeNode {
List<OutlineNode>? children,
this.title = "",
}) : _children = children ?? [] {
id = DateTime.now().microsecondsSinceEpoch.toRadixString(36);
id = DateTime.now().microsecondsSinceEpoch.toRadixString(36) + value.hashCode.toRadixString(36);
}
OutlineNode copyWith({bool? isExpanded, List<OutlineNode>? children}) {

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

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
import 'package:file_picker/file_picker.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/outline/models/outline_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;
@ -385,4 +386,9 @@ class TemplateParserController extends BaseContentController { @@ -385,4 +386,9 @@ class TemplateParserController extends BaseContentController {
gridController.dispose();
super.dispose();
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

8
win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/framework/services/macro_template_service.dart';
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/modules/uft_component/controllers/component_source.dart';
import 'package:win_text_editor/modules/uft_component/models/uft_component.dart';
import 'package:win_text_editor/modules/uft_component/services/uft_component_service.dart';
@ -125,4 +127,10 @@ class UftComponentController extends BaseContentController { @@ -125,4 +127,10 @@ class UftComponentController extends BaseContentController {
notifyListeners();
}
}
@override
void onDropOutlineNode(OutlineNode node) {
_currentUftComponent.codePartners.add(CodePartner.fromOutlineNode(node));
notifyListeners();
}
}

17
win_text_editor/lib/modules/uft_component/models/uft_component.dart

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
import 'package:win_text_editor/modules/memory_table/models/memory_table.dart';
import 'package:win_text_editor/modules/outline/models/code_partner.dart';
import 'package:win_text_editor/shared/base/selectable_item.dart';
import 'package:win_text_editor/shared/models/std_filed.dart';
@ -11,6 +12,8 @@ class UftComponent implements SelectableItem { @@ -11,6 +12,8 @@ class UftComponent implements SelectableItem {
@override
bool isSelected;
final List<CodePartner> codePartners = [];
UftComponent({
required this.id,
required this.name,
@ -37,6 +40,13 @@ class UftComponent implements SelectableItem { @@ -37,6 +40,13 @@ class UftComponent implements SelectableItem {
'chineseName': field.chineseName,
'type': field.type,
'isLast': fields.indexOf(field) == fields.length - 1,
'partnerName':
codePartners
.firstWhere(
(partner) => partner.fields.any((f) => f == field.name),
orElse: () => CodePartner(name: null, fields: []),
)
.name,
},
)
.toList(),
@ -49,6 +59,13 @@ class UftComponent implements SelectableItem { @@ -49,6 +59,13 @@ class UftComponent implements SelectableItem {
'chineseName': field.chineseName,
'type': field.type,
'isLast': selectFields.indexOf(field) == selectFields.length - 1,
'partnerName':
codePartners
.firstWhere(
(partner) => partner.fields.any((f) => f == field.name),
orElse: () => CodePartner(name: null, fields: []),
)
.name,
},
)
.toList(),

16
win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart

@ -7,11 +7,7 @@ class UftComponentRightSide extends StatefulWidget { @@ -7,11 +7,7 @@ class UftComponentRightSide extends StatefulWidget {
final UftComponentController controller;
final TextEditingController codeController;
const UftComponentRightSide({
super.key,
required this.controller,
required this.codeController,
});
const UftComponentRightSide({super.key, required this.controller, required this.codeController});
@override
State<UftComponentRightSide> createState() => _UftComponentRightSideState();
@ -35,11 +31,10 @@ class _UftComponentRightSideState extends State<UftComponentRightSide> { @@ -35,11 +31,10 @@ class _UftComponentRightSideState extends State<UftComponentRightSide> {
void _updateDisplay() {
if (_selectedOperation != null) {
widget.codeController.text =
widget.controller.genCodeString([_selectedOperation!]) ?? '';
widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? '';
} else {
widget.codeController.text = '';
}
}
}
void _selectOperation(String? operation) {
@ -51,13 +46,12 @@ class _UftComponentRightSideState extends State<UftComponentRightSide> { @@ -51,13 +46,12 @@ class _UftComponentRightSideState extends State<UftComponentRightSide> {
@override
Widget build(BuildContext context) {
final operations = [
'插入组件', '修改组件', '获取组件', '遍历组件', '组件大小', '尾部插入组件'
];
final operations = ['插入组件', '修改组件', '获取组件', '遍历组件', '组件大小', '尾部插入组件'];
return CodeGenerationSection(
title: '生成代码',
codeController: widget.codeController,
onNodeDropped: (node) => widget.controller.onDropOutlineNode(node),
child: OperationRadioSection(
operations: operations,
selectedOperation: _selectedOperation,

6
win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart

@ -3,6 +3,7 @@ import 'dart:async'; @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
import 'package:win_text_editor/modules/xml_search/models/search_result.dart';
import 'package:win_text_editor/modules/xml_search/services/xml_search_service.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
@ -159,4 +160,9 @@ class XmlSearchController extends BaseContentController { @@ -159,4 +160,9 @@ class XmlSearchController extends BaseContentController {
notifyListeners();
}
}
@override
void onDropOutlineNode(OutlineNode node) {
// TODO: implement onDropOutlineNode
}
}

3
win_text_editor/lib/shared/base/base_content_controller.dart

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
abstract class BaseContentController with ChangeNotifier {
void onOpenFolder(String folderPath);
void onOpenFile(String filePath, {dynamic appendArg});
void onDropOutlineNode(OutlineNode node);
}

82
win_text_editor/lib/shared/components/code_generation_components.dart

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
// shared/components/code_generation_components.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:win_text_editor/modules/outline/models/outline_node.dart';
class CodeGenerationRadioItem extends StatelessWidget {
final String label;
@ -34,42 +35,58 @@ class CodeGenerationSection extends StatelessWidget { @@ -34,42 +35,58 @@ class CodeGenerationSection extends StatelessWidget {
final String title;
final Widget child;
final TextEditingController codeController;
final Function(OutlineNode)? onNodeDropped; //
final bool droppable; //
const CodeGenerationSection({
super.key,
required this.title,
required this.child,
required this.codeController,
this.onNodeDropped,
this.droppable = true, //
});
@override
Widget build(BuildContext context) {
return Column(
children: [
child,
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.content_copy, size: 20),
tooltip: '复制代码',
onPressed: () {
if (codeController.text.isNotEmpty) {
Clipboard.setData(ClipboardData(text: codeController.text));
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('已复制到剪贴板')));
}
},
return DragTarget<OutlineNode>(
onWillAcceptWithDetails: (data) {
//
return _checkIsDroppable(data.data);
},
onAcceptWithDetails: (detail) {
//
onNodeDropped?.call(detail.data);
},
builder: (context, candidateData, rejectedData) {
return Column(
children: [
child,
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.content_copy, size: 20),
tooltip: '复制代码',
onPressed: () {
if (codeController.text.isNotEmpty) {
Clipboard.setData(ClipboardData(text: codeController.text));
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('已复制到剪贴板')));
}
},
),
],
),
],
),
),
Flexible(child: _buildCodeEditor(codeController)),
],
),
Flexible(child: _buildCodeEditor(codeController)),
],
);
},
);
}
@ -96,6 +113,21 @@ class CodeGenerationSection extends StatelessWidget { @@ -96,6 +113,21 @@ class CodeGenerationSection extends StatelessWidget {
),
);
}
bool _checkIsDroppable(OutlineNode outlineNode) {
if (outlineNode.depth < 3) {
return false;
}
switch (outlineNode.value) {
case "UFTTable":
case "Business":
case "Atom":
case "Component":
return true; //
default:
return false; //
}
}
}
class OperationRadioSection extends StatelessWidget {

91
win_text_editor/lib/shared/components/tree_view.dart

@ -23,6 +23,8 @@ class TreeViewConfig { @@ -23,6 +23,8 @@ class TreeViewConfig {
final Map<String, IconData> icons;
final bool showRefreshButton;
final IconData refreshIcon;
final bool draggable; //
final bool droppable; //
const TreeViewConfig({
this.lazyLoad = false,
@ -34,6 +36,8 @@ class TreeViewConfig { @@ -34,6 +36,8 @@ class TreeViewConfig {
this.icons = const {},
this.showRefreshButton = false,
this.refreshIcon = Icons.refresh,
this.draggable = false,
this.droppable = false,
});
}
@ -98,26 +102,75 @@ class _TreeViewState extends State<TreeView> { @@ -98,26 +102,75 @@ class _TreeViewState extends State<TreeView> {
Widget build(BuildContext context) {
return Stack(
children: [
ListView.builder(
controller: _effectiveController,
physics: const ClampingScrollPhysics(),
itemCount: _countVisibleNodes(widget.nodes),
itemBuilder: (context, index) {
final node = _getVisibleNode(widget.nodes, index);
final isSelected = _selectedIds.contains(node.id);
DragTarget<TreeNode>(
onWillAcceptWithDetails: (data) {
//
if (!widget.config.droppable) return false;
return true;
},
onAcceptWithDetails: (draggedNode) {
//
//
debugPrint('Dropped ${draggedNode.data.name}');
},
builder: (context, candidateData, rejectedData) {
return ListView.builder(
controller: _effectiveController,
physics: const ClampingScrollPhysics(),
itemCount: _countVisibleNodes(widget.nodes),
itemBuilder: (context, index) {
final node = _getVisibleNode(widget.nodes, index);
final isSelected = _selectedIds.contains(node.id);
return widget.nodeBuilder != null
? widget.nodeBuilder!(context, node, isSelected, () => _handleNodeTap(node))
: TreeNodeWidget(
key: ValueKey(node.id),
node: node,
config: widget.config,
isSelected: isSelected,
isChecked: _checkedIds.contains(node.id),
onTap: () => _handleNodeTap(node),
onDoubleTap: () => widget.onNodeDoubleTap?.call(node),
onCheckChanged: (value) => _handleNodeCheckChanged(node, value),
);
return widget.nodeBuilder != null
? widget.nodeBuilder!(context, node, isSelected, () => _handleNodeTap(node))
: Draggable<TreeNode>(
data: node,
feedback: Material(
child: Container(
width: 200,
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(4),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: Text(node.title),
),
),
childWhenDragging: Opacity(
opacity: 0.5,
child: TreeNodeWidget(
key: ValueKey(node.id),
node: node,
config: widget.config,
isSelected: isSelected,
isChecked: _checkedIds.contains(node.id),
onTap: () => _handleNodeTap(node),
onDoubleTap: () => widget.onNodeDoubleTap?.call(node),
onCheckChanged: (value) => _handleNodeCheckChanged(node, value),
),
),
child: TreeNodeWidget(
key: ValueKey(node.id),
node: node,
config: widget.config,
isSelected: isSelected,
isChecked: _checkedIds.contains(node.id),
onTap: () => _handleNodeTap(node),
onDoubleTap: () => widget.onNodeDoubleTap?.call(node),
onCheckChanged: (value) => _handleNodeCheckChanged(node, value),
),
);
},
);
},
),

22
win_text_editor/lib/test.dart

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
import 'package:mustache_template/mustache.dart';
void main() {
final template = Template('''
{{#value}}Value exists: {{value}},{{/value}}
others...
''');
print(template.renderString({'value': '有内容'}));
// 1key
print(template.renderString({'value': ''}));
// : "No value provided"
// 2 null
print(template.renderString({'value': null}));
// : "No value provided"
//
// print(template.renderString({'value': ''})); //
// print(template.renderString({'value': 'Hello'})); //
}

20
win_text_editor/pubspec.lock

@ -141,10 +141,10 @@ packages: @@ -141,10 +141,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "77f8e81d22d2a07d0dee2c62e1dda71dc1da73bf43bb2d45af09727406167964"
sha256: ef9908739bdd9c476353d6adff72e88fd00c625f5b959ae23f7567bd5137db0a
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.1.9"
version: "10.2.0"
flutter:
dependency: "direct main"
description: flutter
@ -187,6 +187,14 @@ packages: @@ -187,6 +187,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_treeview:
dependency: "direct main"
description:
name: flutter_treeview
sha256: ce7a66452e02877700890cb674773ea0af28d914192acfb5bf55a50ce35b5819
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.7+1"
flutter_web_plugins:
dependency: transitive
description: flutter
@ -408,6 +416,14 @@ packages: @@ -408,6 +416,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.5"
quiver:
dependency: "direct main"
description:
name: quiver
sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.2.2"
rxdart:
dependency: transitive
description:

2
win_text_editor/pubspec.yaml

@ -29,6 +29,8 @@ dependencies: @@ -29,6 +29,8 @@ dependencies:
yaml: ^3.1.1
pluto_grid: ^8.0.0
jieba_flutter: ^0.2.0
flutter_treeview: ^1.0.7+1
quiver: ^3.2.2
dev_dependencies:
flutter_test:

Loading…
Cancel
Save