diff --git a/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart b/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart index 8f5dedb..a5a9be5 100644 --- a/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart +++ b/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart @@ -13,7 +13,7 @@ class XmlSearchController extends BaseContentController { String attributeName = ''; bool _isSearching = false; - final List _results = []; + final List _results = [SearchResult(rowNum: 1, attributeValue: '模拟数据')]; final XmlSearchService _searchService = XmlSearchService(); List get results => _results; @@ -103,8 +103,44 @@ class XmlSearchController extends BaseContentController { void cancelSearching() {} void removeResult(SearchResult result) async { - await _searchService.removeNode(searchDirectory, nodePath, attributeName, result); + await _searchService.removeNodes(searchDirectory, nodePath, attributeName, [result]); results.remove(result); notifyListeners(); } + + void toggleSelectAll(bool select) { + for (var result in results) { + result.isSelected = select; + } + notifyListeners(); + } + + List getSelectedResults() { + return results.where((r) => r.isSelected).toList(); + } + + Future batchRemoveNodes() async { + if (_searchDirectory.isEmpty) { + throw Exception('请先选择XML文件'); + } + + final selectedResults = getSelectedResults(); + if (selectedResults.isEmpty) { + return; + } + + _isSearching = true; + notifyListeners(); + + try { + // 先删除文件中的节点 + await _searchService.removeNodes(_searchDirectory, nodePath, attributeName, selectedResults); + + // 再从结果列表中移除 + _results.removeWhere((r) => r.isSelected); + } finally { + _isSearching = false; + notifyListeners(); + } + } } diff --git a/win_text_editor/lib/modules/xml_search/models/search_result.dart b/win_text_editor/lib/modules/xml_search/models/search_result.dart index 47740d7..0f2957d 100644 --- a/win_text_editor/lib/modules/xml_search/models/search_result.dart +++ b/win_text_editor/lib/modules/xml_search/models/search_result.dart @@ -3,6 +3,12 @@ class SearchResult { final int rowNum; final String attributeValue; int index = 0; + bool isSelected = false; // 新增选择状态字段 - SearchResult({required this.rowNum, required this.attributeValue, this.index = 0}); + SearchResult({ + required this.rowNum, + required this.attributeValue, + this.index = 0, + this.isSelected = false, + }); } diff --git a/win_text_editor/lib/modules/xml_search/services/xml_search_service.dart b/win_text_editor/lib/modules/xml_search/services/xml_search_service.dart index 2f0b82d..c105844 100644 --- a/win_text_editor/lib/modules/xml_search/services/xml_search_service.dart +++ b/win_text_editor/lib/modules/xml_search/services/xml_search_service.dart @@ -50,42 +50,45 @@ class XmlSearchService { return results; } - Future removeNode( + Future removeNodes( String directory, String nodeName, String attributeName, - SearchResult result, + List resultList, ) async { try { // 1. 打开并解析 XML 文件 final file = File(directory); final content = await file.readAsString(); final document = xml.XmlDocument.parse(content); + String newContent = content; // 2. 查找所有匹配的节点 - final nodes = - document.findAllElements(nodeName).where((node) { - final attributeValue = node.getAttribute(attributeName); - return attributeValue == result.attributeValue; - }).toList(); + for (SearchResult result in resultList) { + final nodes = + document.findAllElements(nodeName).where((node) { + final attributeValue = node.getAttribute(attributeName); + return attributeValue == result.attributeValue; + }).toList(); - // 3. 检查是否存在指定序号的节点 - if (result.index >= 0 && result.index < nodes.length) { - final nodeToRemove = nodes[result.index]; + // 3. 检查是否存在指定序号的节点 + if (result.index >= 0 && result.index < nodes.length) { + final nodeToRemove = nodes[result.index]; - // 4. 删除节点 - nodeToRemove.parent?.children.remove(nodeToRemove); + // 4. 删除节点 + nodeToRemove.parent?.children.remove(nodeToRemove); - // 5. 保存修改后的 XML 文件 - final newContent = document.toXmlString(pretty: true); - await file.writeAsString(newContent); + // 5. 保存修改后的 XML 文件 + newContent = document.toXmlString(pretty: true); - Logger().info( - '成功删除节点: $nodeName[$attributeName="${result.attributeValue}"][${result.index}]', - ); - } else { - Logger().warning('未找到序号为 ${result.index} 的匹配节点'); + Logger().info( + '成功删除节点: $nodeName[$attributeName="${result.attributeValue}"][${result.index}]', + ); + } else { + Logger().warning('未找到序号为 ${result.index} 的匹配节点'); + } } + await file.writeAsString(newContent); } catch (e) { Logger().error('删除节点时出错: $e'); rethrow; // 重新抛出异常以便上层处理 diff --git a/win_text_editor/lib/modules/xml_search/widgets/condition_setting.dart b/win_text_editor/lib/modules/xml_search/widgets/condition_setting.dart index 98d461c..ae0ff96 100644 --- a/win_text_editor/lib/modules/xml_search/widgets/condition_setting.dart +++ b/win_text_editor/lib/modules/xml_search/widgets/condition_setting.dart @@ -71,7 +71,6 @@ class _ConditionSettingState extends State { const SizedBox(height: 12), SizedBox( - width: MediaQuery.of(context).size.width * 0.5, height: 360, child: TextEditor( tabId: 'search_content_${controller.hashCode}', @@ -103,6 +102,15 @@ class _ConditionSettingState extends State { ), ], ), + const SizedBox(height: 12), + ElevatedButton.icon( + icon: const Icon(Icons.delete_forever, color: Colors.red), + label: const Text('批量删除节点', style: TextStyle(color: Colors.red)), + onPressed: () => _batchRemove(controller), + style: ElevatedButton.styleFrom( + minimumSize: const Size.fromHeight(48), // 设置按钮高度 + ), + ), ], ), ), @@ -147,4 +155,57 @@ class _ConditionSettingState extends State { controller.cancelSearching(); setState(() => _isSearching = false); } + + Future _batchRemove(XmlSearchController controller) async { + final selectedResults = controller.getSelectedResults(); + if (selectedResults.isEmpty) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('请先选择要删除的节点'))); + } + return; + } + + bool confirm = + await showDialog( + context: context, + builder: + (context) => AlertDialog( + title: const Text('确认批量删除'), + content: Text('确定要删除选中的 ${selectedResults.length} 个节点吗?'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, false), + child: const Text('取消'), + ), + TextButton( + onPressed: () => Navigator.pop(context, true), + child: const Text('确认', style: TextStyle(color: Colors.red)), + ), + ], + ), + ) ?? + false; + + if (confirm && mounted) { + setState(() => _isSearching = true); + try { + await controller.batchRemoveNodes(); + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('成功删除 ${selectedResults.length} 个节点'))); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('删除失败: ${e.toString()}'))); + } + } finally { + if (mounted) { + setState(() => _isSearching = false); + } + } + } + } } diff --git a/win_text_editor/lib/modules/xml_search/widgets/results_view.dart b/win_text_editor/lib/modules/xml_search/widgets/results_view.dart index 9697880..8c3551e 100644 --- a/win_text_editor/lib/modules/xml_search/widgets/results_view.dart +++ b/win_text_editor/lib/modules/xml_search/widgets/results_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_datagrid/datagrid.dart'; +import 'package:pluto_grid/pluto_grid.dart'; import 'package:path/path.dart' as path; import 'package:file_picker/file_picker.dart'; @@ -10,11 +10,18 @@ import 'package:win_text_editor/modules/xml_search/models/search_result.dart'; import 'dart:io'; import 'package:win_text_editor/modules/xml_search/controllers/xml_search_controller.dart'; -import 'package:win_text_editor/shared/components/my_grid_column.dart'; +import 'package:win_text_editor/shared/components/my_pluto_column.dart'; -class ResultsView extends StatelessWidget { +class ResultsView extends StatefulWidget { const ResultsView({super.key}); + @override + State createState() => _ResultsViewState(); +} + +class _ResultsViewState extends State { + late final PlutoGridStateManager stateManager; + @override Widget build(BuildContext context) { final controller = context.watch(); @@ -34,11 +41,9 @@ class ResultsView extends StatelessWidget { Offset position, XmlSearchController controller, ) async { - // 获取渲染对象以正确定位菜单 final renderBox = context.findRenderObject() as RenderBox; final localPosition = renderBox.globalToLocal(position); - // 显示菜单并等待选择结果 final result = await showMenu( context: context, position: RelativeRect.fromLTRB( @@ -50,7 +55,6 @@ class ResultsView extends StatelessWidget { items: [const PopupMenuItem(value: 'exportAll', child: Text('导出(csv)'))], ); - // 处理菜单选择结果 if (result != null && result.startsWith('export') && context.mounted) { try { await _exportToCsv(controller, result); @@ -84,161 +88,166 @@ class ResultsView extends StatelessWidget { } Widget _buildLocateGrid(XmlSearchController controller, BuildContext context) { - return SfDataGrid( - rowHeight: 32, - headerRowHeight: 32, - source: LocateDataSource(controller, context), - columns: [ - ShortGridColumn(columnName: 'rowNum', label: '序号'), - MyGridColumn(columnName: 'content', label: '搜索内容', minimumWidth: 300), - ShortGridColumn(columnName: 'index', label: '节点序号', width: 80), - ShortGridColumn(columnName: 'action', label: '操作', width: 90), - ], - selectionMode: SelectionMode.multiple, - navigationMode: GridNavigationMode.cell, - gridLinesVisibility: GridLinesVisibility.both, - headerGridLinesVisibility: GridLinesVisibility.both, - allowSorting: false, - allowFiltering: false, - columnWidthMode: ColumnWidthMode.fill, - isScrollbarAlwaysShown: true, - allowColumnsResizing: true, // 关键开关 - columnResizeMode: ColumnResizeMode.onResizeEnd, - ); - } -} + return PlutoGrid( + configuration: const PlutoGridConfiguration( + style: PlutoGridStyleConfig( + rowHeight: 32, + columnHeight: 32, + iconColor: Colors.transparent, + gridBorderRadius: BorderRadius.zero, + columnTextStyle: TextStyle( + color: Colors.black, + fontSize: 14, + fontWeight: FontWeight.normal, + ), + ), + columnSize: PlutoGridColumnSizeConfig( + autoSizeMode: PlutoAutoSizeMode.scale, + resizeMode: PlutoResizeMode.pushAndPull, + ), + ), -class LocateDataSource extends DataGridSource { - final XmlSearchController controller; - final BuildContext context; + columns: _buildColumns(), + mode: PlutoGridMode.normal, + rows: _buildRows(controller), + onLoaded: (PlutoGridOnLoadedEvent event) { + stateManager = event.stateManager; + stateManager.setSelectingMode(PlutoGridSelectingMode.row); - LocateDataSource(this.controller, this.context); + // 添加行选中状态监听器 + stateManager.addListener(() { + if (stateManager.hasFocus) { + final checkedRows = stateManager.checkedRows; + for (var row in checkedRows) { + final result = row.cells['action']?.value as SearchResult?; + if (result != null) { + result.isSelected = true; + } + } - @override - List get rows => - controller.results.map((result) { - return DataGridRow( - cells: [ - DataGridCell(columnName: 'rowNum', value: result.rowNum), - DataGridCell(columnName: 'content', value: path.basename(result.attributeValue)), - DataGridCell(columnName: 'index', value: result.index), - DataGridCell( - columnName: 'action', - value: result, // Store file path for delete action - ), - ], - ); - }).toList(); + // 更新未选中的行 + for (var row in stateManager.refRows.where((r) => !checkedRows.contains(r))) { + final result = row.cells['action']?.value as SearchResult?; + if (result != null) { + result.isSelected = false; + } + } - @override - DataGridRowAdapter? buildRow(DataGridRow row) { - final cells = row.getCells(); - final result = cells[3].value as SearchResult; - return DataGridRowAdapter( - cells: [ - Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Text(cells[0].value.toString()), - ), - // 文件名单元格 - Container( - alignment: Alignment.centerLeft, - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Text(cells[1].value.toString(), overflow: TextOverflow.ellipsis, maxLines: 1), - ), - // 内容单元格(带高亮) - Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Text(cells[2].value.toString()), - ), - Container( - alignment: Alignment.center, - child: Row( + controller.notifyListeners(); + } + }); + }, + noRowsWidget: const Center(child: Text('没有搜索结果')), + ); + } + + List _buildRows(XmlSearchController controller) { + return controller.results.map((result) { + return PlutoRow( + checked: result.isSelected, // 绑定选中状态到内置复选框 + cells: { + 'rowNum': PlutoCell(value: result.rowNum), + 'content': PlutoCell(value: result.attributeValue), + 'index': PlutoCell(value: result.index ?? 0), + 'action': PlutoCell(value: result), + }, + ); + }).toList(); + } + + List _buildColumns() { + return [ + MyPlutoColumn(title: '序号', field: 'rowNum', width: 90, checkable: true), + MyPlutoColumn( + title: '搜索内容', + field: 'content', + type: PlutoColumnType.text(), + editable: true, + autoSize: true, + ), + MyPlutoColumn(title: '节点序号', field: 'index'), + MyPlutoColumn( + title: '操作', + field: 'action', + renderer: (rendererContext) { + final result = rendererContext.row.cells['action']!.value as SearchResult; + return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: const Icon(Icons.delete_forever, size: 18, color: Colors.red), - onPressed: () => _showDeleteConfirmation(result), + onPressed: () => _showDeleteConfirmation(context, rendererContext.row, result), ), ], - ), - ), - ], - ); + ); + }, + ), + ]; } - Future _showDeleteConfirmation(SearchResult result) async { - bool confirmed = false; - - await showDialog( - context: context, - builder: (context) { - // 捕获键盘事件 - return Shortcuts( - shortcuts: const { - // 绑定回车键 - SingleActivator(LogicalKeyboardKey.enter): _ConfirmAction(), - }, - child: Actions( - actions: { - _ConfirmAction: CallbackAction<_ConfirmAction>( - onInvoke: (_) { - confirmed = true; - Navigator.pop(context, true); - return null; - }, - ), - }, - child: Focus( - autofocus: true, // 自动获取焦点 - child: AlertDialog( - title: const Text('确认删除'), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text('将所选xml节点删除吗?'), - const SizedBox(height: 8), - Text( - '${result.attributeValue}[${result.index}]', - style: const TextStyle(fontSize: 12, color: Colors.grey), - ), - ], - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context, false), - child: const Text('取消'), - ), - TextButton( - onPressed: () { - confirmed = true; + Future _showDeleteConfirmation( + BuildContext context, + PlutoRow row, + SearchResult result, + ) async { + bool confirmed = + await showDialog( + context: context, + builder: (context) { + return Shortcuts( + shortcuts: const {SingleActivator(LogicalKeyboardKey.enter): _ConfirmAction()}, + child: Actions( + actions: { + _ConfirmAction: CallbackAction<_ConfirmAction>( + onInvoke: (_) { Navigator.pop(context, true); + return null; }, - child: const Text('确认'), ), - ], + }, + child: Focus( + autofocus: true, + child: AlertDialog( + title: const Text('确认删除'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('将所选xml节点删除吗?'), + const SizedBox(height: 8), + Text( + '${result.attributeValue}[${result.index}]', + style: const TextStyle(fontSize: 12, color: Colors.grey), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, false), + child: const Text('取消'), + ), + TextButton( + onPressed: () => Navigator.pop(context, true), + child: const Text('确认'), + ), + ], + ), + ), ), - ), - ), - ); - }, - ); + ); + }, + ) ?? + false; if (confirmed && context.mounted) { try { + final controller = context.read(); controller.removeResult(result); - notifyListeners(); + stateManager.removeRows([row]); - if (context.mounted) { - Logger().info('已删除节点文件: ${result.attributeValue}[${result.index}]'); - } + Logger().info('已删除节点文件: ${result.attributeValue}[${result.index}]'); } catch (e) { - if (context.mounted) { - Logger().error('删除失败: ${e.toString()}'); - } + Logger().error('删除失败: ${e.toString()}'); } } } diff --git a/win_text_editor/lib/process.dart b/win_text_editor/lib/process.dart new file mode 100644 index 0000000..dfc75a2 --- /dev/null +++ b/win_text_editor/lib/process.dart @@ -0,0 +1,74 @@ +import 'dart:io'; +import 'package:xml/xml.dart'; + +void main2() { + const dictFilePath = "D:/PBHK/pbhk_trade/Sources/ServerUFT/UFT/metadata/dict.dict"; + const fieldFilePath = "D:/PBHK/pbhk_trade/Sources/ServerUFT/UFT/metadata/stdfield.stdfield"; + final dictFile = File(dictFilePath); + final fieldFile = File(fieldFilePath); + + if (!dictFile.existsSync()) { + print('字典文件不存在: $dictFilePath'); + return; + } + if (!fieldFile.existsSync()) { + print('字段文件不存在: $fieldFilePath'); + return; + } + + try { + // 1. 读取字典文件 + final dictDocument = XmlDocument.parse(dictFile.readAsStringSync()); + + // 2. 读取字段文件 + final fieldDocument = XmlDocument.parse(fieldFile.readAsStringSync()); + + // 3. 找出字典文件中所有 xsi:type="metadata:DictionaryType" 的items节点 + final dictionaryItems = + dictDocument.findAllElements('items').where((element) { + return element.getAttribute('xsi:type') == 'metadata:DictionaryType'; + }).toList(); + + // 4. 处理这些节点 + for (final item in dictionaryItems) { + bool hasConstantName = false; + String? dictionaryName; + + // 检查所有子节点 + for (final child in item.childElements) { + final constantName = child.getAttribute('constantName'); + if (constantName != null && constantName.isNotEmpty) { + hasConstantName = true; + break; + } + } + + // 如果没有子节点包含constantName属性 + if (!hasConstantName) { + dictionaryName = item.getAttribute('name'); + + if (dictionaryName != null && dictionaryName.isNotEmpty) { + // 在字段文件中查找是否有items节点的dictionaryType等于该name值 + final matchingFieldItems = fieldDocument.findAllElements('items').where((element) { + return element.getAttribute('dictionaryType') == dictionaryName; + }); + + // 如果没有找到匹配的字段,则删除字典中的当前节点 + if (matchingFieldItems.isEmpty) { + item.parent?.children.remove(item); + } + } else { + // 如果没有name属性,也删除该节点 + item.parent?.children.remove(item); + } + } + } + + // 5. 保存修改后的字典文件 + final outputPath = dictFilePath.replaceAll('.dict', '_modified.xml'); + File(outputPath).writeAsStringSync(dictDocument.toXmlString(pretty: true)); + print('处理完成,结果已保存到: $outputPath'); + } catch (e) { + print('处理XML文件时出错: $e'); + } +} diff --git a/win_text_editor/lib/shared/components/my_pluto_column.dart b/win_text_editor/lib/shared/components/my_pluto_column.dart new file mode 100644 index 0000000..c0058ca --- /dev/null +++ b/win_text_editor/lib/shared/components/my_pluto_column.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:pluto_grid/pluto_grid.dart'; + +class MyPlutoColumn extends PlutoColumn { + MyPlutoColumn({ + required String title, + required String field, + dynamic type, + double width = 80, + bool editable = false, + bool checkable = false, + bool enableSorting = false, + bool autoSize = false, + Widget Function(PlutoColumnRendererContext)? renderer, + PlutoColumnTextAlign textAlign = PlutoColumnTextAlign.start, + }) : super( + title: title, + field: field, + type: type ?? PlutoColumnType.text(defaultValue: ''), + width: width, + enableRowChecked: checkable, + enableContextMenu: false, + enableEditingMode: editable, + enableSorting: enableSorting, + readOnly: true, + backgroundColor: Colors.grey[100], + textAlign: textAlign, + titleTextAlign: PlutoColumnTextAlign.center, + suppressedAutoSize: !autoSize, + renderer: renderer, + ); +} diff --git a/win_text_editor/pubspec.lock b/win_text_editor/pubspec.lock index cf9f0ed..b06251b 100644 --- a/win_text_editor/pubspec.lock +++ b/win_text_editor/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: async sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.12.0" bitsdojo_window: @@ -14,7 +14,7 @@ packages: description: name: bitsdojo_window sha256: "88ef7765dafe52d97d7a3684960fb5d003e3151e662c18645c1641c22b873195" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.6" bitsdojo_window_linux: @@ -22,7 +22,7 @@ packages: description: name: bitsdojo_window_linux sha256: "9519c0614f98be733e0b1b7cb15b827007886f6fe36a4fb62cf3d35b9dd578ab" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.4" bitsdojo_window_macos: @@ -30,7 +30,7 @@ packages: description: name: bitsdojo_window_macos sha256: f7c5be82e74568c68c5b8449e2c5d8fd12ec195ecd70745a7b9c0f802bb0268f - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.4" bitsdojo_window_platform_interface: @@ -38,7 +38,7 @@ packages: description: name: bitsdojo_window_platform_interface sha256: "65daa015a0c6dba749bdd35a0f092e7a8ba8b0766aa0480eb3ef808086f6e27c" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.2" bitsdojo_window_windows: @@ -46,7 +46,7 @@ packages: description: name: bitsdojo_window_windows sha256: fa982cf61ede53f483e50b257344a1c250af231a3cdc93a7064dd6dc0d720b68 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.6" boolean_selector: @@ -54,7 +54,7 @@ packages: description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" characters: @@ -62,7 +62,7 @@ packages: description: name: characters sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" clock: @@ -70,7 +70,7 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" collection: @@ -78,7 +78,7 @@ packages: description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.19.1" cross_file: @@ -86,7 +86,7 @@ packages: description: name: cross_file sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.4+2" crypto: @@ -94,7 +94,7 @@ packages: description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.6" csv: @@ -102,7 +102,7 @@ packages: description: name: csv sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.0.0" expandable: @@ -110,7 +110,7 @@ packages: description: name: expandable sha256: "9604d612d4d1146dafa96c6d8eec9c2ff0994658d6d09fed720ab788c7f5afc2" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.1" fake_async: @@ -118,7 +118,7 @@ packages: description: name: fake_async sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.2" ffi: @@ -126,7 +126,7 @@ packages: description: name: ffi sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" file: @@ -134,7 +134,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "7.0.1" file_picker: @@ -142,7 +142,7 @@ packages: description: name: file_picker sha256: "77f8e81d22d2a07d0dee2c62e1dda71dc1da73bf43bb2d45af09727406167964" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "10.1.9" flutter: @@ -155,7 +155,7 @@ packages: description: name: flutter_js sha256: "0d22d73a474b5b80c3ab5508e7c3eab6fb20beea9dec45bbd21088cfd27a5e61" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.8.3" flutter_lints: @@ -163,7 +163,7 @@ packages: description: name: flutter_lints sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" flutter_plugin_android_lifecycle: @@ -171,7 +171,7 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.28" flutter_syntax_view: @@ -179,7 +179,7 @@ packages: description: name: flutter_syntax_view sha256: c5017bbedfdcf538daba765e16541fcb26434071655ca00cea7cbc205a70246a - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.7" flutter_test: @@ -197,7 +197,7 @@ packages: description: name: hive sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.3" hive_flutter: @@ -205,7 +205,7 @@ packages: description: name: hive_flutter sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" http: @@ -213,7 +213,7 @@ packages: description: name: http sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" http_parser: @@ -221,15 +221,23 @@ packages: description: name: http_parser sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.2" + intl: + dependency: transitive + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.19.0" leak_tracker: dependency: transitive description: name: leak_tracker sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "10.0.8" leak_tracker_flutter_testing: @@ -237,7 +245,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.9" leak_tracker_testing: @@ -245,7 +253,7 @@ packages: description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.1" lints: @@ -253,7 +261,7 @@ packages: description: name: lints sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" matcher: @@ -261,7 +269,7 @@ packages: description: name: matcher sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.17" material_color_utilities: @@ -269,7 +277,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.1" meta: @@ -277,7 +285,7 @@ packages: description: name: meta sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.16.0" mustache_template: @@ -285,7 +293,7 @@ packages: description: name: mustache_template sha256: a46e26f91445bfb0b60519be280555b06792460b27b19e2b19ad5b9740df5d1c - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" nested: @@ -293,7 +301,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.0" path: @@ -301,7 +309,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.1" path_provider: @@ -309,7 +317,7 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.5" path_provider_android: @@ -317,7 +325,7 @@ packages: description: name: path_provider_android sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.17" path_provider_foundation: @@ -325,7 +333,7 @@ packages: description: name: path_provider_foundation sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" path_provider_linux: @@ -333,7 +341,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -341,7 +349,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" path_provider_windows: @@ -349,7 +357,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.0" petitparser: @@ -357,7 +365,7 @@ packages: description: name: petitparser sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.0" platform: @@ -365,7 +373,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.6" plugin_platform_interface: @@ -373,23 +381,39 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.8" + pluto_grid: + dependency: "direct main" + description: + name: pluto_grid + sha256: "1d4cd9d2652742b556aa9b3230cc64672a3f63c34a9acc80fef794ab36ad903b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "8.0.0" provider: dependency: "direct main" description: name: provider sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.5" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.27.7" screen_retriever: dependency: transitive description: name: screen_retriever sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.9" shared_preferences: @@ -397,7 +421,7 @@ packages: description: name: shared_preferences sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.5.3" shared_preferences_android: @@ -405,7 +429,7 @@ packages: description: name: shared_preferences_android sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.10" shared_preferences_foundation: @@ -413,7 +437,7 @@ packages: description: name: shared_preferences_foundation sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.5.4" shared_preferences_linux: @@ -421,7 +445,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -429,7 +453,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" shared_preferences_web: @@ -437,7 +461,7 @@ packages: description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.3" shared_preferences_windows: @@ -445,7 +469,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" sky_engine: @@ -458,7 +482,7 @@ packages: description: name: source_span sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.10.1" stack_trace: @@ -466,7 +490,7 @@ packages: description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.12.1" stream_channel: @@ -474,7 +498,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" string_scanner: @@ -482,7 +506,7 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.1" sync_http: @@ -490,7 +514,7 @@ packages: description: name: sync_http sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.1" syncfusion_flutter_core: @@ -498,7 +522,7 @@ packages: description: name: syncfusion_flutter_core sha256: a2427697bfad5b611db78ea4c4daef82d3350b83c729a8dc37959662a31547f9 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "23.2.7" syncfusion_flutter_datagrid: @@ -506,7 +530,7 @@ packages: description: name: syncfusion_flutter_datagrid sha256: "9f621f6344d2ed7ea3a8d0ff5c145c174f1e227d6d8851290591ceb718e44600" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "23.2.7" term_glyph: @@ -514,7 +538,7 @@ packages: description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.2" test_api: @@ -522,7 +546,7 @@ packages: description: name: test_api sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.4" typed_data: @@ -530,7 +554,7 @@ packages: description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" vector_math: @@ -538,7 +562,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" vm_service: @@ -546,7 +570,7 @@ packages: description: name: vm_service sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "14.3.1" web: @@ -554,7 +578,7 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" win32: @@ -562,7 +586,7 @@ packages: description: name: win32 sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.13.0" window_manager: @@ -570,7 +594,7 @@ packages: description: name: window_manager sha256: "8699323b30da4cdbe2aa2e7c9de567a6abd8a97d9a5c850a3c86dcd0b34bbfbf" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.9" xdg_directories: @@ -578,7 +602,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" xml: @@ -586,7 +610,7 @@ packages: description: name: xml sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.5.0" yaml: @@ -594,8 +618,9 @@ packages: description: name: yaml sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.3" sdks: dart: ">=3.7.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/win_text_editor/pubspec.yaml b/win_text_editor/pubspec.yaml index 6b2bba6..319bdaf 100644 --- a/win_text_editor/pubspec.yaml +++ b/win_text_editor/pubspec.yaml @@ -27,6 +27,7 @@ dependencies: hive: ^2.2.3 hive_flutter: ^1.1.0 yaml: ^3.1.1 + pluto_grid: ^8.0.0 dev_dependencies: