Browse Source

内存表已切换为单选,其他切换单选之前

master
hejl 4 weeks ago
parent
commit
aa98e21707
  1. 2
      win_text_editor/lib/modules/call_function/models/call_function.dart
  2. 2
      win_text_editor/lib/modules/memory_table/models/memory_table.dart
  3. 2
      win_text_editor/lib/modules/memory_table/services/memory_table_service.dart
  4. 53
      win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart
  5. 24
      win_text_editor/lib/modules/outline/controllers/outline_provider.dart
  6. 5
      win_text_editor/lib/modules/outline/services/functions_service.dart
  7. 5
      win_text_editor/lib/modules/outline/services/outline_service.dart
  8. 15
      win_text_editor/lib/modules/outline/services/std_field_service.dart
  9. 2
      win_text_editor/lib/modules/outline/widgets/outline_explorer.dart
  10. 143
      win_text_editor/lib/shared/components/code_generation_components.dart

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

@ -28,6 +28,7 @@ class CallFunction {
'factorParam': factorParam ?? '', 'factorParam': factorParam ?? '',
'input': 'input':
inputParameters inputParameters
.where((field) => field.isSelected)
.map( .map(
(field) => { (field) => {
'id': field.id, 'id': field.id,
@ -40,6 +41,7 @@ class CallFunction {
.toList(), .toList(),
'output': 'output':
outputParameters outputParameters
.where((field) => field.isSelected)
.map( .map(
(field) => { (field) => {
'id': field.id, 'id': field.id,

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

@ -41,7 +41,7 @@ class MemoryTable {
// //
List<String> get keyFields { List<String> get keyFields {
var name = keyName; var name = keyName;
if (name!.isEmpty) return []; if (name == null || name.isEmpty) return [];
for (var index in indexes) { for (var index in indexes) {
if (index.indexName == name) { if (index.indexName == name) {
return index.fields; return index.fields;

2
win_text_editor/lib/modules/memory_table/services/memory_table_service.dart

@ -69,7 +69,7 @@ class MemoryTableService {
final rule = containerType ?? ''; final rule = containerType ?? '';
// Get all index fields // Get all index fields
final items = indexNode.findAllElements('items'); final items = indexNode.findElements('items');
final fieldsList = final fieldsList =
items items
.map((item) => item.getAttribute('attrname') ?? '') .map((item) => item.getAttribute('attrname') ?? '')

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

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart'; import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart';
import 'package:win_text_editor/shared/components/my_checkbox.dart';
class MemoryTableRightSide extends StatefulWidget { class MemoryTableRightSide extends StatefulWidget {
final MemoryTableController controller; final MemoryTableController controller;
@ -14,7 +13,7 @@ class MemoryTableRightSide extends StatefulWidget {
} }
class _MemoryTableRightSideState extends State<MemoryTableRightSide> { class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
final List<String> _selectedOperations = []; String? _selectedOperation; //
@override @override
void initState() { void initState() {
@ -30,16 +29,16 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
} }
void _updateDisplay() { void _updateDisplay() {
widget.codeController.text = widget.controller.genCodeString(_selectedOperations)!; if (_selectedOperation != null) {
widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? '';
} else {
widget.codeController.text = '';
}
} }
void _toggleOperation(String operation, bool? value) { void _selectOperation(String operation) {
setState(() { setState(() {
if (value == true) { _selectedOperation = operation;
_selectedOperations.add(operation);
} else {
_selectedOperations.remove(operation);
}
_updateDisplay(); _updateDisplay();
}); });
} }
@ -48,7 +47,7 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
_buildCheckboxSection(), _buildRadioSection(),
Padding( Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0), padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Row( child: Row(
@ -75,21 +74,21 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
); );
} }
Widget _buildCheckboxSection() { Widget _buildRadioSection() {
final operations = ['获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录']; final operations = ['获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录'];
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
child: Card( child: Card(
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 8, top: 4, bottom: 12), padding: const EdgeInsets.all(12),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Wrap( Wrap(
spacing: 8, spacing: 16, //
runSpacing: 8, runSpacing: 8, //
children: operations.map((op) => _buildCheckbox(op)).toList(), children: operations.map((op) => _buildRadioItem(op)).toList(),
), ),
], ],
), ),
@ -98,11 +97,27 @@ class _MemoryTableRightSideState extends State<MemoryTableRightSide> {
); );
} }
Widget _buildCheckbox(String label) => MyCheckbox( Widget _buildRadioItem(String label) {
title: label, return Row(
value: _selectedOperations.contains(label), mainAxisSize: MainAxisSize.min, // 使Row只占用必要宽度
onChanged: (bool? value) => _toggleOperation(label, value), children: [
Transform.scale(
scale: 0.75,
child: Radio<String>(
value: label,
groupValue: _selectedOperation,
onChanged: (String? value) {
if (value != null) {
_selectOperation(value);
}
},
),
),
const SizedBox(width: 4),
Text(label, style: const TextStyle(fontSize: 14)),
],
); );
}
Widget _buildCodeEditor() { Widget _buildCodeEditor() {
return Card( return Card(

24
win_text_editor/lib/modules/outline/controllers/outline_provider.dart

@ -16,15 +16,6 @@ class OutlineProvider with ChangeNotifier {
isExpanded: true, isExpanded: true,
); );
static OutlineNode searchNode = OutlineNode(
name: "搜索结果",
title: "搜索结果",
value: 'Query',
isDirectory: true,
isRoot: true,
isExpanded: true,
);
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
bool get hasRoot => _outlineNode.isNotEmpty && _outlineNode[0].isRoot; bool get hasRoot => _outlineNode.isNotEmpty && _outlineNode[0].isRoot;
@ -71,7 +62,7 @@ class OutlineProvider with ChangeNotifier {
} }
} }
Future<void> loadDirectoryContents(OutlineNode dirNode) async { Future<void> loadDirectoryContents(OutlineNode dirNode, {bool refresh = false}) async {
if (dirNode.children.isNotEmpty) { if (dirNode.children.isNotEmpty) {
return; return;
} }
@ -86,10 +77,15 @@ class OutlineProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<void> refreshOutlineTree({bool loadContent = false}) async { Future<void> refreshOutlineTree() async {
_isLoading = true; _isLoading = true;
notifyListeners(); notifyListeners();
Logger().info('正在刷新大纲树...'); rootNode.isExpanded = false;
rootNode.children.clear();
final wordNodes = await OutlineService.getWordNodes(_currentRootPath!);
rootNode.title = "所有";
rootNode.children = wordNodes;
rootNode.isExpanded = true;
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
} }
@ -101,7 +97,7 @@ class OutlineProvider with ChangeNotifier {
return [rootNode]; return [rootNode];
} }
OutlineService.applySearchFilter(searchNode, searchQuery); OutlineService.applySearchFilter(rootNode, searchQuery);
return [searchNode]; return [rootNode];
} }
} }

5
win_text_editor/lib/modules/outline/services/functions_service.dart

@ -13,7 +13,7 @@ class FunctionsService {
static Map<String, List<String>> uftatomMap = {}; static Map<String, List<String>> uftatomMap = {};
static Future<void> initFunctionsMap(String rootPath) async { static Future<void> initFunctionsMap(String rootPath) async {
await _initUftMap('uftbusiness', rootPath, uftbusinessMap, ['.uffunction']); await _initUftMap('uftbusiness', rootPath, uftbusinessMap, ['.uftfunction']);
await _initUftMap('uftatom', rootPath, uftatomMap, ['.uftatomfunction', '.uftatomservice']); await _initUftMap('uftatom', rootPath, uftatomMap, ['.uftatomfunction', '.uftatomservice']);
} }
@ -51,8 +51,7 @@ class FunctionsService {
try { try {
final content = await file.readAsString(); final content = await file.readAsString();
final document = XmlDocument.parse(content); final document = XmlDocument.parse(content);
final businessNode = document.findAllElements('business:Function').firstOrNull; final businessNode = document.rootElement;
if (businessNode == null) return;
final chineseName = businessNode.getAttribute('chineseName') ?? '未命名'; final chineseName = businessNode.getAttribute('chineseName') ?? '未命名';
targetMap[chineseName] = [file.path]; targetMap[chineseName] = [file.path];

5
win_text_editor/lib/modules/outline/services/outline_service.dart

@ -309,11 +309,12 @@ class OutlineService {
_searchNode?.children.add(virtualNode); _searchNode?.children.add(virtualNode);
} }
root.children.clear();
root.isExpanded = false;
// //
if (_searchNode!.children.isNotEmpty) { if (_searchNode!.children.isNotEmpty) {
root.title = "搜索结果"; root.title = "搜索结果";
root.children.clear();
root.isExpanded = false;
root.children.add(_searchNode!); root.children.add(_searchNode!);
root.isExpanded = true; root.isExpanded = true;
} else { } else {

15
win_text_editor/lib/modules/outline/services/std_field_service.dart

@ -33,9 +33,10 @@ class StdFieldService {
for (final item in document.findAllElements('items')) { for (final item in document.findAllElements('items')) {
final chineseName = item.getAttribute('chineseName'); final chineseName = item.getAttribute('chineseName');
final name = item.getAttribute('name'); final name = item.getAttribute('name');
final status = item.getAttribute('status');
if (chineseName != null && name != null) { if (chineseName != null && name != null && status != '删除') {
stdfieldMap[chineseName] = name; stdfieldMap[name] = chineseName;
} }
} }
} }
@ -66,11 +67,11 @@ class StdFieldService {
Logger().info('搜索标准字段:${dirNode.name}'); Logger().info('搜索标准字段:${dirNode.name}');
stdfieldMap.forEach((key, value) { stdfieldMap.forEach((key, value) {
if (key.contains(dirNode.name)) { if (value.contains(dirNode.name)) {
final fieldNode = OutlineNode( final fieldNode = OutlineNode(
name: key, name: key,
title: '$key($value)', title: '$value($key)',
value: value, value: key,
isDirectory: true, isDirectory: true,
depth: 2, depth: 2,
); );
@ -116,8 +117,8 @@ class StdFieldService {
value.contains(searchQuery)) { value.contains(searchQuery)) {
final fieldNode = OutlineNode( final fieldNode = OutlineNode(
name: key, name: key,
title: '$key($value)', title: '$value($key)',
value: value, value: key,
isDirectory: false, isDirectory: false,
depth: 2, depth: 2,
); );

2
win_text_editor/lib/modules/outline/widgets/outline_explorer.dart

@ -125,7 +125,7 @@ class _OutlineExplorerState extends State<OutlineExplorer> {
(node) => _handleNodeDoubleTap(node as OutlineNode, fileProvider), (node) => _handleNodeDoubleTap(node as OutlineNode, fileProvider),
onRefresh: () async { onRefresh: () async {
await outlineProvider.refreshOutlineTree(); await outlineProvider.refreshOutlineTree();
setState(() {}); setState(() => _searchController.text = '');
}, },
), ),
), ),

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

@ -0,0 +1,143 @@
// shared/components/code_generation_components.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class CodeGenerationRadioItem extends StatelessWidget {
final String label;
final String? groupValue;
final ValueChanged<String?> onChanged;
const CodeGenerationRadioItem({
super.key,
required this.label,
required this.groupValue,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Transform.scale(
scale: 0.75,
child: Radio<String>(value: label, groupValue: groupValue, onChanged: onChanged),
),
const SizedBox(width: 4),
Text(label, style: const TextStyle(fontSize: 14)),
],
);
}
}
class CodeGenerationSection extends StatelessWidget {
final String title;
final Widget child;
final TextEditingController codeController;
const CodeGenerationSection({
super.key,
required this.title,
required this.child,
required this.codeController,
});
@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('已复制到剪贴板')));
}
},
),
],
),
),
Flexible(child: _buildCodeEditor(codeController)),
],
);
}
Widget _buildCodeEditor(TextEditingController controller) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4),
),
child: TextField(
controller: controller,
maxLines: null,
expands: true,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(8),
),
style: const TextStyle(fontFamily: 'monospace', color: Colors.blueAccent),
),
),
),
);
}
}
class OperationRadioSection extends StatelessWidget {
final List<String> operations;
final String? selectedOperation;
final ValueChanged<String?> onOperationSelected;
const OperationRadioSection({
super.key,
required this.operations,
required this.selectedOperation,
required this.onOperationSelected,
});
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: Card(
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
spacing: 16,
runSpacing: 8,
children:
operations
.map(
(op) => CodeGenerationRadioItem(
label: op,
groupValue: selectedOperation,
onChanged: onOperationSelected,
),
)
.toList(),
),
],
),
),
),
);
}
}
Loading…
Cancel
Save