import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter/services.dart'; // 复制功能需要 import 'package:win_text_editor/app/providers/editor_provider.dart'; import 'package:file_picker/file_picker.dart'; import 'dart:io'; // 用于文件操作 class TextTab extends StatefulWidget { final String tabId; const TextTab({super.key, required this.tabId}); @override State createState() => _TextTabState(); } class _TextTabState extends State { late TextEditingController _controller; late EditorProvider _provider; @override void initState() { super.initState(); _provider = Provider.of(context, listen: false); _controller = TextEditingController(text: _getCurrentContent()); } String _getCurrentContent() { return _provider.tabs.firstWhere((t) => t.id == widget.tabId).content; } @override void didUpdateWidget(TextTab oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.tabId != widget.tabId) { _controller.text = _getCurrentContent(); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final tab = _provider.tabs.firstWhere((t) => t.id == widget.tabId); // Add this line return Column( children: [ // 新增工具条 Container( height: 40, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.grey[100], border: Border(bottom: BorderSide(color: Colors.grey[300]!)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '源文本${tab.content.isEmpty ? '' : ' (${tab.content.length}字符)'}', style: const TextStyle(fontWeight: FontWeight.bold), ), Row( children: [ IconButton( icon: const Icon(Icons.folder_open, size: 20), tooltip: '打开文件', onPressed: () => _openFile(context), ), IconButton( icon: const Icon(Icons.content_copy, size: 20), tooltip: '复制内容', onPressed: tab.content.isEmpty ? null : () => _copyToClipboard(context, tab.content), ), IconButton( icon: const Icon(Icons.save, size: 20), tooltip: '保存到文件', onPressed: tab.content.isEmpty ? null : () => _saveFile(context, tab.content), ), ], ), ], ), ), // 文本编辑区 Expanded( child: TextField( controller: _controller, maxLines: null, onChanged: (text) => _provider.updateContent(widget.tabId, text), decoration: const InputDecoration( border: InputBorder.none, contentPadding: EdgeInsets.all(16), ), ), ), ], ); } // _openFile方法现在需要更新控制器 Future _openFile(BuildContext context) async { try { final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: false); if (result != null && result.files.single.path != null) { final file = File(result.files.single.path!); // 尝试读取文件内容 final content = await file.readAsString(); // 同时更新Provider和控制器 _provider.updateContent(widget.tabId, content); setState(() { _controller.text = content; }); // 强制刷新文本控制器 if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('已加载: ${file.path}'))); } } } on FormatException { // 二进制文件错误 ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('这不是可读的文本文件'))); } on FileSystemException catch (e) { // 文件系统错误 ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('文件访问错误: ${e.message}'))); } catch (e) { if (context.mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('读取失败: ${e.toString()}'))); } } } // 复制到剪贴板 Future _copyToClipboard(BuildContext context, String content) async { await Clipboard.setData(ClipboardData(text: content)); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制到剪贴板'))); } } // 保存文件模拟功能 Future _saveFile(BuildContext context, String content) async { // 这里是模拟代码,实际应该使用文件保存对话框 if (context.mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('已保存 ${content.length} 个字符'))); } } }