Browse Source

修复中文输入的问题

master
hejl 2 months ago
parent
commit
f8a7081149
  1. 33
      win_text_editor/lib/app/components/text_editor.dart
  2. 103
      win_text_editor/lib/app/modules/content_search/content_search_service.dart

33
win_text_editor/lib/app/components/text_editor.dart

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -29,6 +30,8 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix @@ -29,6 +30,8 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix
final TextEditingController _textController = TextEditingController();
final FocusNode _focusNode = FocusNode();
bool _isLoading = false;
String _lastSyncedText = '';
Timer? _debounceTimer;
@override
bool get wantKeepAlive => true;
@ -36,26 +39,38 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix @@ -36,26 +39,38 @@ class TextEditorState extends State<TextEditor> with AutomaticKeepAliveClientMix
@override
void initState() {
super.initState();
_textController.text = widget.initialContent ?? '';
_lastSyncedText = widget.initialContent ?? '';
_textController.text = _lastSyncedText;
_textController.addListener(_handleTextChanged);
}
@override
void didUpdateWidget(TextEditor oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.initialContent != widget.initialContent) {
_textController.text = widget.initialContent ?? '';
void _handleTextChanged() {
if (_debounceTimer?.isActive ?? false) {
_debounceTimer?.cancel();
}
_debounceTimer = Timer(const Duration(milliseconds: 300), () {
final currentText = _textController.text;
if (widget.onContentChanged != null && currentText != _lastSyncedText) {
_lastSyncedText = currentText;
widget.onContentChanged!(currentText);
}
});
}
void _handleTextChanged() {
if (widget.onContentChanged != null) {
widget.onContentChanged!(_textController.text);
@override
void didUpdateWidget(TextEditor oldWidget) {
super.didUpdateWidget(oldWidget);
final newText = widget.initialContent ?? '';
if (newText != _textController.text && newText != _lastSyncedText) {
_lastSyncedText = newText;
_textController.text = newText;
}
}
@override
void dispose() {
_debounceTimer?.cancel();
_textController.removeListener(_handleTextChanged);
_textController.dispose();
_focusNode.dispose();

103
win_text_editor/lib/app/modules/content_search/content_search_service.dart

@ -17,19 +17,19 @@ class ContentSearchService { @@ -17,19 +17,19 @@ class ContentSearchService {
final queries = _splitQuery(query); //
for (final q in queries) {
final pattern = _buildSearchPattern(
final pattern = _buildSearchPattern(
query: q,
caseSensitive: caseSensitive,
wholeWord: wholeWord,
useRegex: useRegex,
);
caseSensitive: caseSensitive,
wholeWord: wholeWord,
useRegex: useRegex,
);
await for (final entity in dir.list(recursive: true)) {
if (entity is File && _matchesFileType(entity.path, fileType)) {
await for (final entity in dir.list(recursive: true)) {
if (entity is File && _matchesFileType(entity.path, fileType)) {
await _searchInFile(entity, pattern, results, q); //
}
}
}
}
return results;
}
@ -48,19 +48,19 @@ class ContentSearchService { @@ -48,19 +48,19 @@ class ContentSearchService {
final queries = _splitQuery(query); //
for (final q in queries) {
final pattern = _buildSearchPattern(
final pattern = _buildSearchPattern(
query: q,
caseSensitive: caseSensitive,
wholeWord: wholeWord,
useRegex: useRegex,
);
caseSensitive: caseSensitive,
wholeWord: wholeWord,
useRegex: useRegex,
);
await for (final entity in dir.list(recursive: true)) {
if (entity is File && _matchesFileType(entity.path, fileType)) {
await for (final entity in dir.list(recursive: true)) {
if (entity is File && _matchesFileType(entity.path, fileType)) {
await _countInFile(entity, pattern, counts, q); //
}
}
}
}
return counts;
}
@ -89,11 +89,76 @@ class ContentSearchService { @@ -89,11 +89,76 @@ class ContentSearchService {
return RegExp(pattern, caseSensitive: caseSensitive, multiLine: true);
}
///
static bool _matchesFileType(String filePath, String fileType) {
//
if (fileType == '*.*') return true;
final ext = path.extension(filePath).toLowerCase();
return ext == fileType.toLowerCase();
if (fileType == '*') return true;
//
final parts = fileType.split('.');
final patternName = parts.length > 0 ? parts[0] : '';
final patternExt = parts.length > 1 ? parts.sublist(1).join('.') : '';
//
final fileName = path.basename(filePath);
final fileExt = path.extension(fileName).toLowerCase().replaceFirst('.', '');
//
bool nameMatches = true;
if (patternName.isNotEmpty && patternName != '*') {
nameMatches = _matchesWildcard(fileName, patternName);
}
//
bool extMatches = true;
if (patternExt.isNotEmpty) {
if (patternExt == '*') {
extMatches = true;
} else {
extMatches = _matchesWildcard(fileExt, patternExt);
}
}
return nameMatches && extMatches;
}
//
static bool _matchesWildcard(String input, String pattern) {
//
if (pattern == '*') return true;
//
final m = input.length;
final n = pattern.length;
final dp = List.generate(m + 1, (_) => List.filled(n + 1, false));
//
dp[0][0] = true;
// *
for (int j = 1; j <= n; j++) {
if (pattern[j - 1] == '*') {
dp[0][j] = dp[0][j - 1];
}
}
//
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (pattern[j - 1] == '*') {
// *
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
} else if (pattern[j - 1] == '?' || input[i - 1] == pattern[j - 1]) {
// ?
dp[i][j] = dp[i - 1][j - 1];
} else {
//
dp[i][j] = false;
}
}
}
return dp[m][n];
}
/// queryTerm

Loading…
Cancel
Save