Skip to content

Commit

Permalink
Merge pull request #1351 from davidskelly/case_insensitive_File_picker
Browse files Browse the repository at this point in the history
Case insensitive file picker
  • Loading branch information
Miguel Ruivo authored Mar 20, 2024
2 parents f23fdb5 + f2e71a9 commit e777abe
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 26 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 7.0.2
### Desktop (Linux)
File picker extensions for Linux Zenity are case insensitive now
Fixes [#1322](https://github.com/miguelpruivo/flutter_file_picker/issues/1322)

## 6.2.1
### Desktop (Windows)
The `initialDirectory` parameter of `getDirectoryPath()` now works ([#970](https://github.com/miguelpruivo/flutter_file_picker/issues/970)).
Expand Down Expand Up @@ -30,10 +35,13 @@ Fix several warnings in the iOS plugin implementation.
### iOS
Fix if selecting from gallery multiple files from remote sources (eg GoPro, Drone) imported to the device gallery and uploaded to iCloud they would have the same file name and it shows only one image repeated
Fix returned images are in different onder from the gallery selection

## 5.3.4
fix [#1317](https://github.com/miguelpruivo/flutter_file_picker/issues/1317)

## 5.3.3
fix [#1312](https://github.com/miguelpruivo/flutter_file_picker/issues/1312)

## 5.3.2
### Desktop (Windows)
Bumps the dependency `win32` to 5.0.2 ([#1281](https://github.com/miguelpruivo/flutter_file_picker/pull/1281)). Thank you @frg2089!
Expand Down
10 changes: 10 additions & 0 deletions lib/src/linux/dialog_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'package:file_picker/file_picker.dart';
import 'package:file_picker/src/linux/kdialog_handler.dart';
import 'package:file_picker/src/linux/qarma_and_zenity_handler.dart';

import '../utils.dart';

abstract class DialogHandler {
factory DialogHandler(String pathToExecutable) {
pathToExecutable = pathToExecutable.toLowerCase();
Expand Down Expand Up @@ -40,4 +42,12 @@ abstract class DialogHandler {
/// Converts the result string (stdout) of `qarma`, `zenity` or `kdialog`
/// into a [List<String>] of file paths.
List<String> resultStringToFilePaths(String fileSelectionResult);

static String toCaseInsensitive(String filter) {
return filter
.split("")
.map((e) =>
isAlpha(e) ? "[" + e.toLowerCase() + e.toUpperCase() + "]" : e)
.join();
}
}
10 changes: 5 additions & 5 deletions lib/src/linux/kdialog_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ class KDialogHandler implements DialogHandler {
case FileType.any:
return '';
case FileType.audio:
return 'Audio File (*.aac *.midi *.mp3 *.ogg *.wav)';
return 'Audio File (${DialogHandler.toCaseInsensitive("*.aac *.midi *.mp3 *.ogg *.wav")})';
case FileType.custom:
return '${allowedExtensions!.map((ext) => ext.toUpperCase()).join(' File, ')} File (*.${allowedExtensions.join(' *.')})';
return '${allowedExtensions!.map((ext) => ext.toUpperCase()).join(' File, ')} File (${DialogHandler.toCaseInsensitive("*.${allowedExtensions.join(' *.')}")})';
case FileType.image:
return 'Image File (*.bmp *.gif *.jpeg *.jpg *.png)';
return 'Image File (${DialogHandler.toCaseInsensitive("*.bmp *.gif *.jpeg *.jpg *.png")})';
case FileType.media:
return 'Media File (*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png)';
return 'Media File (${DialogHandler.toCaseInsensitive("*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png")})';
case FileType.video:
return 'Video File (*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv)';
return 'Video File (${DialogHandler.toCaseInsensitive("*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv")})';
default:
throw Exception('unknown file type');
}
Expand Down
10 changes: 5 additions & 5 deletions lib/src/linux/qarma_and_zenity_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ class QarmaAndZenityHandler implements DialogHandler {
case FileType.any:
return '';
case FileType.audio:
return '*.aac *.midi *.mp3 *.ogg *.wav';
return "Audio Files | ${DialogHandler.toCaseInsensitive('*.aac *.midi *.mp3 *.ogg *.wav')}";
case FileType.custom:
return '*.${allowedExtensions!.join(' *.')}';
return "Custom Files | ${DialogHandler.toCaseInsensitive('*.${allowedExtensions!.join(' *.')}')}";
case FileType.image:
return '*.bmp *.gif *.jpeg *.jpg *.png';
return "Image Files | ${DialogHandler.toCaseInsensitive('*.bmp *.gif *.jpeg *.jpg *.png')}";
case FileType.media:
return '*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png';
return "Media Files | ${DialogHandler.toCaseInsensitive('*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png')}";
case FileType.video:
return '*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv';
return "Video Files | ${DialogHandler.toCaseInsensitive('*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv')}";
default:
throw Exception('unknown file type');
}
Expand Down
6 changes: 6 additions & 0 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@ Future<String> isExecutableOnPath(String executable) async {
}
return path;
}

bool isAlpha(String x) {
int codeUnit = x.codeUnitAt(0);
return 'a'.codeUnitAt(0) <= codeUnit && codeUnit <= 'z'.codeUnitAt(0) ||
'A'.codeUnitAt(0) <= codeUnit && codeUnit <= 'Z'.codeUnitAt(0);
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: A package that allows you to use a native file explorer to pick sin
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
repository: https://github.com/miguelpruivo/flutter_file_picker
issue_tracker: https://github.com/miguelpruivo/flutter_file_picker/issues
version: 6.2.1
version: 7.0.2

dependencies:
flutter:
Expand Down
13 changes: 12 additions & 1 deletion test/file_picker_utils_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@TestOn('linux || mac-os')

import 'dart:io';
import 'package:file_picker/src/utils.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -143,4 +142,16 @@ void main() {
);
});
});

group('isAlpha()', () {
test('should identify alpha chars', () async {
expect(isAlpha('a'), equals(true));
expect(isAlpha('A'), equals(true));
expect(isAlpha('z'), equals(true));
expect(isAlpha('Z'), equals(true));
expect(isAlpha('.'), equals(false));
expect(isAlpha('*'), equals(false));
expect(isAlpha(' '), equals(false));
});
});
}
15 changes: 8 additions & 7 deletions test/linux/kdialog_handler_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@TestOn('linux')

import 'package:file_picker/src/file_picker.dart';
import 'package:file_picker/src/linux/kdialog_handler.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -21,25 +20,27 @@ void main() {

expect(
dialogHandler.fileTypeToFileFilter(FileType.audio, null),
equals('Audio File (*.aac *.midi *.mp3 *.ogg *.wav)'),
equals(
'Audio File (*.[aA][aA][cC] *.[mM][iI][dD][iI] *.[mM][pP]3 *.[oO][gG][gG] *.[wW][aA][vV])'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.image, null),
equals('Image File (*.bmp *.gif *.jpeg *.jpg *.png)'),
equals(
'Image File (*.[bB][mM][pP] *.[gG][iI][fF] *.[jJ][pP][eE][gG] *.[jJ][pP][gG] *.[pP][nN][gG])'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.media, null),
equals(
'Media File (*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png)',
'Media File (*.[aA][vV][iI] *.[fF][lL][vV] *.[mM][kK][vV] *.[mM][oO][vV] *.[mM][pP]4 *.[mM][pP][eE][gG] *.[wW][eE][bB][mM] *.[wW][mM][vV] *.[bB][mM][pP] *.[gG][iI][fF] *.[jJ][pP][eE][gG] *.[jJ][pP][gG] *.[pP][nN][gG])',
),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.video, null),
equals(
'Video File (*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv)'),
'Video File (*.[aA][vV][iI] *.[fF][lL][vV] *.[mM][kK][vV] *.[mM][oO][vV] *.[mM][pP]4 *.[mM][pP][eE][gG] *.[wW][eE][bB][mM] *.[wW][mM][vV])'),
);
});

Expand All @@ -48,12 +49,12 @@ void main() {

expect(
dialogHandler.fileTypeToFileFilter(FileType.custom, ['dart']),
equals('DART File (*.dart)'),
equals('DART File (*.[dD][aA][rR][tT])'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.custom, ['dart', 'html']),
equals('DART File, HTML File (*.dart *.html)'),
equals('DART File, HTML File (*.[dD][aA][rR][tT] *.[hH][tT][mM][lL])'),
);
});
});
Expand Down
16 changes: 9 additions & 7 deletions test/linux/qarma_and_zenity_handler_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@TestOn('linux')

import 'package:file_picker/src/file_picker.dart';
import 'package:file_picker/src/linux/qarma_and_zenity_handler.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -20,24 +19,27 @@ void main() {

expect(
dialogHandler.fileTypeToFileFilter(FileType.audio, null),
equals('*.aac *.midi *.mp3 *.ogg *.wav'),
equals(
'Audio Files | *.[aA][aA][cC] *.[mM][iI][dD][iI] *.[mM][pP]3 *.[oO][gG][gG] *.[wW][aA][vV]'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.image, null),
equals('*.bmp *.gif *.jpeg *.jpg *.png'),
equals(
'Image Files | *.[bB][mM][pP] *.[gG][iI][fF] *.[jJ][pP][eE][gG] *.[jJ][pP][gG] *.[pP][nN][gG]'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.media, null),
equals(
'*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv *.bmp *.gif *.jpeg *.jpg *.png',
'Media Files | *.[aA][vV][iI] *.[fF][lL][vV] *.[mM][kK][vV] *.[mM][oO][vV] *.[mM][pP]4 *.[mM][pP][eE][gG] *.[wW][eE][bB][mM] *.[wW][mM][vV] *.[bB][mM][pP] *.[gG][iI][fF] *.[jJ][pP][eE][gG] *.[jJ][pP][gG] *.[pP][nN][gG]',
),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.video, null),
equals('*.avi *.flv *.mkv *.mov *.mp4 *.mpeg *.webm *.wmv'),
equals(
'Video Files | *.[aA][vV][iI] *.[fF][lL][vV] *.[mM][kK][vV] *.[mM][oO][vV] *.[mM][pP]4 *.[mM][pP][eE][gG] *.[wW][eE][bB][mM] *.[wW][mM][vV]'),
);
});

Expand All @@ -46,12 +48,12 @@ void main() {

expect(
dialogHandler.fileTypeToFileFilter(FileType.custom, ['dart']),
equals('*.dart'),
equals('Custom Files | *.[dD][aA][rR][tT]'),
);

expect(
dialogHandler.fileTypeToFileFilter(FileType.custom, ['dart', 'html']),
equals('*.dart *.html'),
equals('Custom Files | *.[dD][aA][rR][tT] *.[hH][tT][mM][lL]'),
);
});
});
Expand Down

0 comments on commit e777abe

Please sign in to comment.