diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml index ed4d82499..b94efbc11 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -17,7 +17,6 @@ body: attributes: label: Which plugin is this bug report about? options: - - file_selector - menubar - window_size validations: diff --git a/.github/ISSUE_TEMPLATE/OTHER.yml b/.github/ISSUE_TEMPLATE/OTHER.yml index da1d7aba0..5220746a7 100644 --- a/.github/ISSUE_TEMPLATE/OTHER.yml +++ b/.github/ISSUE_TEMPLATE/OTHER.yml @@ -17,7 +17,6 @@ body: attributes: label: Which plugin is this request about? options: - - file_selector - menubar - window_size - A proposal for a new experimental plugin diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 933142eac..f73ede577 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,15 +62,3 @@ jobs: flutter packages get flutter build -v ${{matrix.TARGET}} --release working-directory: ${{ github.workspace }}/fde/testbed - - name: Build file_selector implementations debug - if: startsWith(matrix.os, 'ubuntu') - run: | - flutter packages get - flutter build -v ${{matrix.TARGET}} --debug - working-directory: ${{ github.workspace }}/fde/plugins/file_selector/file_selector_linux/example - - name: Build file_selector implementations release - if: startsWith(matrix.os, 'ubuntu') - run: | - flutter packages get - flutter build -v ${{matrix.TARGET}} --release - working-directory: ${{ github.workspace }}/fde/plugins/file_selector/file_selector_linux/example diff --git a/plugins/README.md b/plugins/README.md index 7f2ef4cff..e4da1136f 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -12,10 +12,10 @@ you should include them directly from this repository: ``` dependencies: ... - file_chooser: + menubar: git: url: https://github.com/google/flutter-desktop-embedding.git - path: plugins/file_chooser + path: plugins/menubar ref: INSERT_HASH_HERE ``` diff --git a/plugins/file_chooser/README.md b/plugins/file_chooser/README.md deleted file mode 100644 index e32ed5a4b..000000000 --- a/plugins/file_chooser/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# file_chooser - -This plugin has been removed in favor of the newer -[`file_selector`](../file_selector/README.md) plugin. If you were previously -using `file_chooser`, or were linked to this plugin, you should use -`file_selector` instead. diff --git a/plugins/file_selector/README.md b/plugins/file_selector/README.md deleted file mode 100644 index 4691f4524..000000000 --- a/plugins/file_selector/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# file_selector Desktop Implementations - -This folder contains the unendorsed Linux implementation of the -[`file_selector`](https://github.com/flutter/plugins/tree/master/packages/file_selector) -plugin. It is not currently -[endorsed](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin), -and is here rather than in the flutter/plugins repository, because -it has not yet been refactored to support thorough -unit testing, and so it doesn't meet the Flutter testing -requirements. Once automated tests are developed, it will be moved to -flutter/plugins and endorsed (as has already happened with Windows and -macOS). - -Unlike other FDE plugins it is published normally, since it has a -long-term support path. As with any unundorsed plugin, you need to -depend directly on the implementation package -([`file_selector_linux`](https://pub.dev/packages/file_selector_linux)) -as well as the app-facing package (`file_selector`) in your `pubspec.yaml`. diff --git a/plugins/file_selector/analysis_options.yaml b/plugins/file_selector/analysis_options.yaml deleted file mode 100644 index d8788fd2a..000000000 --- a/plugins/file_selector/analysis_options.yaml +++ /dev/null @@ -1,248 +0,0 @@ -# This is a copy of the flutter/plugins analysis options file, to avoid -# needing to make a lot of Dart style changes when moving the plugin. - -analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false - errors: - # treat missing required parameters as a warning (not a hint) - missing_required_param: warning - # treat missing returns as a warning (not a hint) - missing_return: warning - # allow having TODO comments in the code - todo: ignore - # allow self-reference to deprecated members (we do this because otherwise we have - # to annotate every member in every test, assert, etc, when we deprecate something) - deprecated_member_use_from_same_package: ignore - # Ignore analyzer hints for updating pubspecs when using Future or - # Stream and not importing dart:async - # Please see https://github.com/flutter/flutter/pull/24528 for details. - sdk_version_async_exported_from_core: ignore - # Turned off until null-safe rollout is complete. - unnecessary_null_comparison: ignore - ### Local flutter/plugins changes ### - # Allow null checks for as long as mixed mode is officially supported. - always_require_non_null_named_parameters: false # not needed with nnbd - exclude: - # Ignore generated files - - '**/*.g.dart' - - 'lib/src/generated/*.dart' - - '**/*.mocks.dart' # Mockito @GenerateMocks - - '**/*.pigeon.dart' # Pigeon generated file - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 - - always_require_non_null_named_parameters - - always_specify_types - # - always_use_package_imports # we do this commonly - - annotate_overrides - # - avoid_annotating_with_dynamic # conflicts with always_specify_types - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 - # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls # LOCAL CHANGE - Needs to be enabled and violations fixed. - - avoid_empty_else - - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters # incompatible with prefer_final_parameters - - avoid_function_literals_in_foreach_calls - # - avoid_implementing_value_types # LOCAL CHANGE - Needs to be enabled and violations fixed. - - avoid_init_to_null - - avoid_js_rounded_ints - # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it - # - avoid_print # LOCAL CHANGE - Needs to be enabled and violations fixed. - # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - # - avoid_returning_null # still violated by some pre-nnbd code that we haven't yet migrated - - avoid_returning_null_for_future - - avoid_returning_null_for_void - # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters # conflicts with always_specify_types - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - # - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - # - cascade_invocations # doesn't match the typical style of this repo - - cast_nullable_to_non_nullable - # - close_sinks # not reliable enough - # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 - # - conditional_uri_does_not_exist # not yet tested - # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 - - control_flow_in_finally - # - curly_braces_in_flow_control_structures # not required by flutter style - # - depend_on_referenced_packages # LOCAL CHANGE - Needs to be enabled and violations fixed. - - deprecated_consistency - # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) - - directives_ordering - # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - - iterable_contains_unrelated_type - # - join_return_with_assignment # not required by flutter style - - leading_newlines_in_multiline_strings - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars # not required by flutter style - - list_remove_unrelated_type - # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - # - no_default_cases # LOCAL CHANGE - Needs to be enabled and violations fixed. - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - # - no_leading_underscores_for_local_identifiers # LOCAL CHANGE - Needs to be enabled and violations fixed. - - no_logic_in_create_state - # - no_runtimeType_toString # ok in tests; we enable this only in packages/ - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - # - omit_local_variable_types # opposite of always_specify_types - # - one_member_abstracts # too many false positives - # - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al # LOCAL CHANGE - Needs to be enabled and violations fixed. - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - # - parameter_assignments # we do this commonly - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - # - prefer_asserts_with_message # not required by flutter style - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - # - prefer_constructors_over_static_methods # far too many false positives - - prefer_contains - # - prefer_double_quotes # opposite of prefer_single_quotes - - prefer_equal_for_default_values - # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 - # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere - - prefer_null_aware_operators - # - prefer_relative_imports # LOCAL CHANGE - Needs to be enabled and violations fixed. - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml - - recursive_getters - # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 - - secure_pubspec_urls - # - sized_box_for_whitespace # LOCAL CHANGE - Needs to be enabled and violations fixed. - # - sized_box_shrink_expand # not yet tested - - slash_for_doc_comments - - sort_child_properties_last - - sort_constructors_first - # - sort_pub_dependencies # prevents separating pinned transitive dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - # - type_annotate_public_apis # subset of always_specify_types - - type_init_formals - # - unawaited_futures # too many false positives, especially with the way AnimationController works - # - unnecessary_await_in_return # LOCAL CHANGE - Needs to be enabled and violations fixed. - - unnecessary_brace_in_string_interps - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final # conflicts with prefer_final_locals - - unnecessary_getters_setters - # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 - - unnecessary_late - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - # - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unrelated_type_equality_checks - - unsafe_html - # - use_build_context_synchronously # LOCAL CHANGE - Needs to be enabled and violations fixed. - # - use_colored_box # not yet tested - # - use_decorated_box # not yet tested - # - use_enums # not yet tested - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - # - use_named_constants # LOCAL CHANGE - Needs to be enabled and violations fixed. - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 - - use_super_parameters - - use_test_throws_matchers - # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - - valid_regexps - - void_checks - ### Local flutter/plugins additions ### - # These are from flutter/flutter/packages, so will need to be preserved - # separately when moving to a shared file. - - no_runtimeType_toString # use objectRuntimeType from package:foundation - - public_member_api_docs # see https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#documentation-dartdocs-javadocs-etc - # Flutter has a specific use case for dependencies that are intentionally - # not sorted, which doesn't apply to this repo. - - sort_pub_dependencies diff --git a/plugins/file_selector/file_selector_linux/.gitignore b/plugins/file_selector/file_selector_linux/.gitignore deleted file mode 100644 index 0393a47ff..000000000 --- a/plugins/file_selector/file_selector_linux/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.dart_tool -.packages -.flutter-plugins -.flutter-plugins-dependencies -pubspec.lock diff --git a/plugins/file_selector/file_selector_linux/CHANGELOG.md b/plugins/file_selector/file_selector_linux/CHANGELOG.md deleted file mode 100644 index 3c089b7bc..000000000 --- a/plugins/file_selector/file_selector_linux/CHANGELOG.md +++ /dev/null @@ -1,15 +0,0 @@ -## 0.0.3 - -* Adds Dart implementation for in-package method channel. - -## 0.0.2+1 - -* Update README - -## 0.0.2 - -* Update SDK constraint to signal compatibility with null safety. - -## 0.0.1 - -* Initial Linux implementation of `file_selector`. diff --git a/plugins/file_selector/file_selector_linux/LICENSE b/plugins/file_selector/file_selector_linux/LICENSE deleted file mode 100644 index 67c7e2c52..000000000 --- a/plugins/file_selector/file_selector_linux/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2020 The Flutter Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/file_selector/file_selector_linux/README.md b/plugins/file_selector/file_selector_linux/README.md deleted file mode 100644 index 5e40d914e..000000000 --- a/plugins/file_selector/file_selector_linux/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# file\_selector\_linux - -The Linux implementation of [`file_selector`][1]. - -## Usage - -### Importing the package - -This implementation has not yet been endorsed, meaning that you need to -[depend on `file_selector_linux`][2] in addition to -[depending on `file_selector`][3]. - -Once your pubspec includes the Linux implementation, you can use the -`file_selector` APIs normally. You should not use the `file_selector_linux` -APIs directly. - -[1]: https://pub.dev/packages/file_selector -[2]: https://pub.dev/packages/file_selector_linux/install -[3]: https://pub.dev/packages/file_selector/install diff --git a/plugins/file_selector/file_selector_linux/example/.gitignore b/plugins/file_selector/file_selector_linux/example/.gitignore deleted file mode 100644 index fb545cde3..000000000 --- a/plugins/file_selector/file_selector_linux/example/.gitignore +++ /dev/null @@ -1,48 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Currently only web supported -android/ -ios/ - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/plugins/file_selector/file_selector_linux/example/.metadata b/plugins/file_selector/file_selector_linux/example/.metadata deleted file mode 100644 index 200186f9b..000000000 --- a/plugins/file_selector/file_selector_linux/example/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 7736f3bc90270dcb0480db2ccffbf1d13c28db85 - channel: dev - -project_type: app diff --git a/plugins/file_selector/file_selector_linux/example/README.md b/plugins/file_selector/file_selector_linux/example/README.md deleted file mode 100644 index 377c02ccb..000000000 --- a/plugins/file_selector/file_selector_linux/example/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# file\_selector\_example - -Demonstrates unendorsed desktop implementations of the -[`file_selector` plugin](https://pub.dev/packages/file_selector). diff --git a/plugins/file_selector/file_selector_linux/example/lib/get_directory_page.dart b/plugins/file_selector/file_selector_linux/example/lib/get_directory_page.dart deleted file mode 100644 index 0699dd121..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/get_directory_page.dart +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/material.dart'; - -/// Screen that allows the user to select a directory using `getDirectoryPath`, -/// then displays the selected directory in a dialog. -class GetDirectoryPage extends StatelessWidget { - /// Default Constructor - const GetDirectoryPage({Key? key}) : super(key: key); - - Future _getDirectoryPath(BuildContext context) async { - const String confirmButtonText = 'Choose'; - final String? directoryPath = - await FileSelectorPlatform.instance.getDirectoryPath( - confirmButtonText: confirmButtonText, - ); - if (directoryPath == null) { - // Operation was canceled by the user. - return; - } - await showDialog( - context: context, - builder: (BuildContext context) => TextDisplay(directoryPath), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Open a text file'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - style: ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ), - child: const Text('Press to ask user to choose a directory'), - onPressed: () => _getDirectoryPath(context), - ), - ], - ), - ), - ); - } -} - -/// Widget that displays a text file in a dialog. -class TextDisplay extends StatelessWidget { - /// Creates a `TextDisplay`. - const TextDisplay(this.directoryPath, {Key? key}) : super(key: key); - - /// The path selected in the dialog. - final String directoryPath; - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Selected Directory'), - content: Scrollbar( - child: SingleChildScrollView( - child: Text(directoryPath), - ), - ), - actions: [ - TextButton( - child: const Text('Close'), - onPressed: () => Navigator.pop(context), - ), - ], - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/home_page.dart b/plugins/file_selector/file_selector_linux/example/lib/home_page.dart deleted file mode 100644 index a4b2ae1f6..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/home_page.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/material.dart'; - -/// Home Page of the application. -class HomePage extends StatelessWidget { - /// Default Constructor - const HomePage({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - final ButtonStyle style = ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ); - return Scaffold( - appBar: AppBar( - title: const Text('File Selector Demo Home Page'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - style: style, - child: const Text('Open a text file'), - onPressed: () => Navigator.pushNamed(context, '/open/text'), - ), - const SizedBox(height: 10), - ElevatedButton( - style: style, - child: const Text('Open an image'), - onPressed: () => Navigator.pushNamed(context, '/open/image'), - ), - const SizedBox(height: 10), - ElevatedButton( - style: style, - child: const Text('Open multiple images'), - onPressed: () => Navigator.pushNamed(context, '/open/images'), - ), - const SizedBox(height: 10), - ElevatedButton( - style: style, - child: const Text('Save a file'), - onPressed: () => Navigator.pushNamed(context, '/save/text'), - ), - const SizedBox(height: 10), - ElevatedButton( - style: style, - child: const Text('Open a get directory dialog'), - onPressed: () => Navigator.pushNamed(context, '/directory'), - ), - ], - ), - ), - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/main.dart b/plugins/file_selector/file_selector_linux/example/lib/main.dart deleted file mode 100644 index 3e447104e..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/main.dart +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/material.dart'; - -import 'get_directory_page.dart'; -import 'home_page.dart'; -import 'open_image_page.dart'; -import 'open_multiple_images_page.dart'; -import 'open_text_page.dart'; -import 'save_text_page.dart'; - -void main() { - runApp(const MyApp()); -} - -/// MyApp is the Main Application. -class MyApp extends StatelessWidget { - /// Default Constructor - const MyApp({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'File Selector Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - ), - home: const HomePage(), - routes: { - '/open/image': (BuildContext context) => const OpenImagePage(), - '/open/images': (BuildContext context) => - const OpenMultipleImagesPage(), - '/open/text': (BuildContext context) => const OpenTextPage(), - '/save/text': (BuildContext context) => SaveTextPage(), - '/directory': (BuildContext context) => const GetDirectoryPage(), - }, - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/open_image_page.dart b/plugins/file_selector/file_selector_linux/example/lib/open_image_page.dart deleted file mode 100644 index 9e1d2074d..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/open_image_page.dart +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io'; - -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -/// Screen that allows the user to select an image file using -/// `openFiles`, then displays the selected images in a gallery dialog. -class OpenImagePage extends StatelessWidget { - /// Default Constructor - const OpenImagePage({Key? key}) : super(key: key); - - Future _openImageFile(BuildContext context) async { - final XTypeGroup typeGroup = XTypeGroup( - label: 'images', - extensions: ['jpg', 'png'], - ); - final XFile? file = await FileSelectorPlatform.instance - .openFile(acceptedTypeGroups: [typeGroup]); - if (file == null) { - // Operation was canceled by the user. - return; - } - final String fileName = file.name; - final String filePath = file.path; - - await showDialog( - context: context, - builder: (BuildContext context) => ImageDisplay(fileName, filePath), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Open an image'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - style: ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ), - child: const Text('Press to open an image file(png, jpg)'), - onPressed: () => _openImageFile(context), - ), - ], - ), - ), - ); - } -} - -/// Widget that displays an image in a dialog. -class ImageDisplay extends StatelessWidget { - /// Default Constructor. - const ImageDisplay(this.fileName, this.filePath, {Key? key}) - : super(key: key); - - /// The name of the selected file. - final String fileName; - - /// The path to the selected file. - final String filePath; - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: Text(fileName), - // On web the filePath is a blob url - // while on other platforms it is a system path. - content: kIsWeb ? Image.network(filePath) : Image.file(File(filePath)), - actions: [ - TextButton( - child: const Text('Close'), - onPressed: () { - Navigator.pop(context); - }, - ), - ], - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/open_multiple_images_page.dart b/plugins/file_selector/file_selector_linux/example/lib/open_multiple_images_page.dart deleted file mode 100644 index 21da8c22f..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/open_multiple_images_page.dart +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io'; - -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -/// Screen that allows the user to select multiple image files using -/// `openFiles`, then displays the selected images in a gallery dialog. -class OpenMultipleImagesPage extends StatelessWidget { - /// Default Constructor - const OpenMultipleImagesPage({Key? key}) : super(key: key); - - Future _openImageFile(BuildContext context) async { - final XTypeGroup jpgsTypeGroup = XTypeGroup( - label: 'JPEGs', - extensions: ['jpg', 'jpeg'], - ); - final XTypeGroup pngTypeGroup = XTypeGroup( - label: 'PNGs', - extensions: ['png'], - ); - final List files = await FileSelectorPlatform.instance - .openFiles(acceptedTypeGroups: [ - jpgsTypeGroup, - pngTypeGroup, - ]); - if (files.isEmpty) { - // Operation was canceled by the user. - return; - } - await showDialog( - context: context, - builder: (BuildContext context) => MultipleImagesDisplay(files), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Open multiple images'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - style: ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ), - child: const Text('Press to open multiple images (png, jpg)'), - onPressed: () => _openImageFile(context), - ), - ], - ), - ), - ); - } -} - -/// Widget that displays a text file in a dialog. -class MultipleImagesDisplay extends StatelessWidget { - /// Default Constructor. - const MultipleImagesDisplay(this.files, {Key? key}) : super(key: key); - - /// The files containing the images. - final List files; - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Gallery'), - // On web the filePath is a blob url - // while on other platforms it is a system path. - content: Center( - child: Row( - children: [ - ...files.map( - (XFile file) => Flexible( - child: kIsWeb - ? Image.network(file.path) - : Image.file(File(file.path))), - ) - ], - ), - ), - actions: [ - TextButton( - child: const Text('Close'), - onPressed: () { - Navigator.pop(context); - }, - ), - ], - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/open_text_page.dart b/plugins/file_selector/file_selector_linux/example/lib/open_text_page.dart deleted file mode 100644 index 05c6d166f..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/open_text_page.dart +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/material.dart'; - -/// Screen that allows the user to select a text file using `openFile`, then -/// displays its contents in a dialog. -class OpenTextPage extends StatelessWidget { - /// Default Constructor - const OpenTextPage({Key? key}) : super(key: key); - - Future _openTextFile(BuildContext context) async { - final XTypeGroup typeGroup = XTypeGroup( - label: 'text', - extensions: ['txt', 'json'], - ); - final XFile? file = await FileSelectorPlatform.instance - .openFile(acceptedTypeGroups: [typeGroup]); - if (file == null) { - // Operation was canceled by the user. - return; - } - final String fileName = file.name; - final String fileContent = await file.readAsString(); - - await showDialog( - context: context, - builder: (BuildContext context) => TextDisplay(fileName, fileContent), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Open a text file'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - style: ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ), - child: const Text('Press to open a text file (json, txt)'), - onPressed: () => _openTextFile(context), - ), - ], - ), - ), - ); - } -} - -/// Widget that displays a text file in a dialog. -class TextDisplay extends StatelessWidget { - /// Default Constructor. - const TextDisplay(this.fileName, this.fileContent, {Key? key}) - : super(key: key); - - /// The name of the selected file. - final String fileName; - - /// The contents of the text file. - final String fileContent; - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: Text(fileName), - content: Scrollbar( - child: SingleChildScrollView( - child: Text(fileContent), - ), - ), - actions: [ - TextButton( - child: const Text('Close'), - onPressed: () => Navigator.pop(context), - ), - ], - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/lib/save_text_page.dart b/plugins/file_selector/file_selector_linux/example/lib/save_text_page.dart deleted file mode 100644 index 9803f285a..000000000 --- a/plugins/file_selector/file_selector_linux/example/lib/save_text_page.dart +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:typed_data'; -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/material.dart'; - -/// Screen that allows the user to select a save location using `getSavePath`, -/// then writes text to a file at that location. -class SaveTextPage extends StatelessWidget { - /// Default Constructor - SaveTextPage({Key? key}) : super(key: key); - - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _contentController = TextEditingController(); - - Future _saveFile() async { - final String fileName = _nameController.text; - final String? path = await FileSelectorPlatform.instance.getSavePath( - // Operation was canceled by the user. - suggestedName: fileName, - ); - if (path == null) { - return; - } - final String text = _contentController.text; - final Uint8List fileData = Uint8List.fromList(text.codeUnits); - const String fileMimeType = 'text/plain'; - final XFile textFile = - XFile.fromData(fileData, mimeType: fileMimeType, name: fileName); - await textFile.saveTo(path); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Save text into a file'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - width: 300, - child: TextField( - minLines: 1, - maxLines: 12, - controller: _nameController, - decoration: const InputDecoration( - hintText: '(Optional) Suggest File Name', - ), - ), - ), - Container( - width: 300, - child: TextField( - minLines: 1, - maxLines: 12, - controller: _contentController, - decoration: const InputDecoration( - hintText: 'Enter File Contents', - ), - ), - ), - const SizedBox(height: 10), - ElevatedButton( - style: ElevatedButton.styleFrom( - // TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724 - // ignore: deprecated_member_use - primary: Colors.blue, - // ignore: deprecated_member_use - onPrimary: Colors.white, - ), - onPressed: _saveFile, - child: const Text('Press to save a text file'), - ), - ], - ), - ), - ); - } -} diff --git a/plugins/file_selector/file_selector_linux/example/linux/.gitignore b/plugins/file_selector/file_selector_linux/example/linux/.gitignore deleted file mode 100644 index d3896c984..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -flutter/ephemeral diff --git a/plugins/file_selector/file_selector_linux/example/linux/CMakeLists.txt b/plugins/file_selector/file_selector_linux/example/linux/CMakeLists.txt deleted file mode 100644 index 9d7224cc9..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/CMakeLists.txt +++ /dev/null @@ -1,111 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -set(BINARY_NAME "example") -set(APPLICATION_ID "com.example.example") - -cmake_policy(SET CMP0063 NEW) - -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Configure build options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - -# Flutter library and tool build rules. -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Application build -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) -apply_standard_settings(${BINARY_NAME}) -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) -add_dependencies(${BINARY_NAME} flutter_assemble) -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - -# Enable the test target. -set(include_file_selector_linux_tests TRUE) -# Provide an alias for the test target using the name expected by repo tooling. -add_custom_target(unit_tests DEPENDS file_selector_linux_test) - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/plugins/file_selector/file_selector_linux/example/linux/flutter/CMakeLists.txt b/plugins/file_selector/file_selector_linux/example/linux/flutter/CMakeLists.txt deleted file mode 100644 index 33fd5801e..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) diff --git a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.cc b/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 64a0ecea4..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); - file_selector_plugin_register_with_registrar(file_selector_linux_registrar); -} diff --git a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.h b/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugins.cmake b/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 2db3c22ae..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - file_selector_linux -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/plugins/file_selector/file_selector_linux/example/linux/main.cc b/plugins/file_selector/file_selector_linux/example/linux/main.cc deleted file mode 100644 index e7c5c5437..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} diff --git a/plugins/file_selector/file_selector_linux/example/linux/my_application.cc b/plugins/file_selector/file_selector_linux/example/linux/my_application.cc deleted file mode 100644 index 543eaca72..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/my_application.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char** dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = TRUE; -#ifdef GDK_WINDOWING_X11 - GdkScreen *screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "example"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } - else { - gtk_window_set_title(window, "example"); - } - - gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - - FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject *object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication* self) {} - -MyApplication* my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - nullptr)); -} diff --git a/plugins/file_selector/file_selector_linux/example/linux/my_application.h b/plugins/file_selector/file_selector_linux/example/linux/my_application.h deleted file mode 100644 index 72271d5e4..000000000 --- a/plugins/file_selector/file_selector_linux/example/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/plugins/file_selector/file_selector_linux/example/pubspec.yaml b/plugins/file_selector/file_selector_linux/example/pubspec.yaml deleted file mode 100644 index a14186da2..000000000 --- a/plugins/file_selector/file_selector_linux/example/pubspec.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: file_selector_linux_example -description: Local testbed for Linux file_selector implementation. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.0.0+1 - -environment: - sdk: ">=2.12.0 <3.0.0" - -dependencies: - file_selector_linux: - path: ../ - file_selector_platform_interface: ^2.0.0 - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - -flutter: - uses-material-design: true diff --git a/plugins/file_selector/file_selector_linux/lib/file_selector_linux.dart b/plugins/file_selector/file_selector_linux/lib/file_selector_linux.dart deleted file mode 100644 index 430b41c39..000000000 --- a/plugins/file_selector/file_selector_linux/lib/file_selector_linux.dart +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/foundation.dart' show visibleForTesting; -import 'package:flutter/services.dart'; - -const MethodChannel _channel = - MethodChannel('plugins.flutter.dev/file_selector_linux'); - -const String _typeGroupLabelKey = 'label'; -const String _typeGroupExtensionsKey = 'extensions'; -const String _typeGroupMimeTypesKey = 'mimeTypes'; - -const String _openFileMethod = 'openFile'; -const String _getSavePathMethod = 'getSavePath'; -const String _getDirectoryPathMethod = 'getDirectoryPath'; - -const String _acceptedTypeGroupsKey = 'acceptedTypeGroups'; -const String _confirmButtonTextKey = 'confirmButtonText'; -const String _initialDirectoryKey = 'initialDirectory'; -const String _multipleKey = 'multiple'; -const String _suggestedNameKey = 'suggestedName'; - -/// An implementation of [FileSelectorPlatform] for Linux. -class FileSelectorLinux extends FileSelectorPlatform { - /// The MethodChannel that is being used by this implementation of the plugin. - @visibleForTesting - MethodChannel get channel => _channel; - - /// Registers the Linux implementation. - static void registerWith() { - FileSelectorPlatform.instance = FileSelectorLinux(); - } - - @override - Future openFile({ - List? acceptedTypeGroups, - String? initialDirectory, - String? confirmButtonText, - }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); - final List? path = await _channel.invokeListMethod( - _openFileMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - 'initialDirectory': initialDirectory, - _confirmButtonTextKey: confirmButtonText, - _multipleKey: false, - }, - ); - return path == null ? null : XFile(path.first); - } - - @override - Future> openFiles({ - List? acceptedTypeGroups, - String? initialDirectory, - String? confirmButtonText, - }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); - final List? pathList = await _channel.invokeListMethod( - _openFileMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - _initialDirectoryKey: initialDirectory, - _confirmButtonTextKey: confirmButtonText, - _multipleKey: true, - }, - ); - return pathList?.map((String path) => XFile(path)).toList() ?? []; - } - - @override - Future getSavePath({ - List? acceptedTypeGroups, - String? initialDirectory, - String? suggestedName, - String? confirmButtonText, - }) async { - final List> serializedTypeGroups = - _serializeTypeGroups(acceptedTypeGroups); - return _channel.invokeMethod( - _getSavePathMethod, - { - if (serializedTypeGroups.isNotEmpty) - _acceptedTypeGroupsKey: serializedTypeGroups, - _initialDirectoryKey: initialDirectory, - _suggestedNameKey: suggestedName, - _confirmButtonTextKey: confirmButtonText, - }, - ); - } - - @override - Future getDirectoryPath({ - String? initialDirectory, - String? confirmButtonText, - }) async { - return _channel.invokeMethod( - _getDirectoryPathMethod, - { - _initialDirectoryKey: initialDirectory, - _confirmButtonTextKey: confirmButtonText, - }, - ); - } -} - -List> _serializeTypeGroups(List? groups) { - return (groups ?? []).map(_serializeTypeGroup).toList(); -} - -Map _serializeTypeGroup(XTypeGroup group) { - final Map serialization = { - _typeGroupLabelKey: group.label ?? '', - }; - if (group.allowsAny) { - serialization[_typeGroupExtensionsKey] = ['*']; - } else { - if ((group.extensions?.isEmpty ?? true) && - (group.mimeTypes?.isEmpty ?? true)) { - throw ArgumentError('Provided type group $group does not allow ' - 'all files, but does not set any of the Linux-supported filter ' - 'categories. "extensions" or "mimeTypes" must be non-empty for Linux ' - 'if anything is non-empty.'); - } - if (group.extensions?.isNotEmpty ?? false) { - serialization[_typeGroupExtensionsKey] = group.extensions - ?.map((String extension) => '*.$extension') - .toList() ?? - []; - } - if (group.mimeTypes?.isNotEmpty ?? false) { - serialization[_typeGroupMimeTypesKey] = group.mimeTypes ?? []; - } - } - return serialization; -} diff --git a/plugins/file_selector/file_selector_linux/linux/CMakeLists.txt b/plugins/file_selector/file_selector_linux/linux/CMakeLists.txt deleted file mode 100644 index d0316d94e..000000000 --- a/plugins/file_selector/file_selector_linux/linux/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -set(PROJECT_NAME "file_selector_linux") -project(${PROJECT_NAME} LANGUAGES CXX) - -set(PLUGIN_NAME "${PROJECT_NAME}_plugin") - -list(APPEND PLUGIN_SOURCES - "file_selector_plugin.cc" -) - -add_library(${PLUGIN_NAME} SHARED - "file_selector_plugin.cc" -) -apply_standard_settings(${PLUGIN_NAME}) -set_target_properties(${PLUGIN_NAME} PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) -target_include_directories(${PLUGIN_NAME} INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) -target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) - - -# === Tests === - -if(${include_${PROJECT_NAME}_tests}) -if(${CMAKE_VERSION} VERSION_LESS "3.11.0") -message("Unit tests require CMake 3.11.0 or later") -else() -set(TEST_RUNNER "${PROJECT_NAME}_test") -enable_testing() -# TODO(stuartmorgan): Consider using a single shared, pre-checked-in googletest -# instance rather than downloading for each plugin. This approach makes sense -# for a template, but not for a monorepo with many plugins. -include(FetchContent) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/release-1.11.0.zip -) -# Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -# Disable install commands for gtest so it doesn't end up in the bundle. -set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE) - -FetchContent_MakeAvailable(googletest) - -# The plugin's exported API is not very useful for unit testing, so build the -# sources directly into the test binary rather than using the shared library. -add_executable(${TEST_RUNNER} - test/file_selector_plugin_test.cc - test/test_main.cc - ${PLUGIN_SOURCES} -) -apply_standard_settings(${TEST_RUNNER}) -target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(${TEST_RUNNER} PRIVATE flutter) -target_link_libraries(${TEST_RUNNER} PRIVATE PkgConfig::GTK) -target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) - -include(GoogleTest) -# TODO(stuartmorgan): Switch back to gtest_discover_tests when moving to -# flutter/plugins; it doesn't work in the FDE CI because it requires actually -# running a GTK app, which it hasn't been set up for. -gtest_add_tests(TARGET ${TEST_RUNNER}) -#gtest_discover_tests(${TEST_RUNNER}) -endif() # CMake version check -endif() # include_${PROJECT_NAME}_tests diff --git a/plugins/file_selector/file_selector_linux/linux/file_selector_plugin.cc b/plugins/file_selector/file_selector_linux/linux/file_selector_plugin.cc deleted file mode 100644 index 5fc94f984..000000000 --- a/plugins/file_selector/file_selector_linux/linux/file_selector_plugin.cc +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "include/file_selector_linux/file_selector_plugin.h" - -#include -#include - -#include "file_selector_plugin_private.h" - -// From file_selector_linux.dart -const char kChannelName[] = "plugins.flutter.dev/file_selector_linux"; - -const char kOpenFileMethod[] = "openFile"; -const char kGetSavePathMethod[] = "getSavePath"; -const char kGetDirectoryPathMethod[] = "getDirectoryPath"; - -const char kAcceptedTypeGroupsKey[] = "acceptedTypeGroups"; -const char kConfirmButtonTextKey[] = "confirmButtonText"; -const char kInitialDirectoryKey[] = "initialDirectory"; -const char kMultipleKey[] = "multiple"; -const char kSuggestedNameKey[] = "suggestedName"; - -const char kTypeGroupLabelKey[] = "label"; -const char kTypeGroupExtensionsKey[] = "extensions"; -const char kTypeGroupMimeTypesKey[] = "mimeTypes"; - -// Errors -const char kBadArgumentsError[] = "Bad Arguments"; -const char kNoScreenError[] = "No Screen"; - -struct _FlFileSelectorPlugin { - GObject parent_instance; - - FlPluginRegistrar* registrar; - - // Connection to Flutter engine. - FlMethodChannel* channel; -}; - -G_DEFINE_TYPE(FlFileSelectorPlugin, fl_file_selector_plugin, G_TYPE_OBJECT) - -// Converts a type group received from Flutter into a GTK file filter. -static GtkFileFilter* type_group_to_filter(FlValue* value) { - g_autoptr(GtkFileFilter) filter = gtk_file_filter_new(); - - FlValue* label = fl_value_lookup_string(value, kTypeGroupLabelKey); - if (label != nullptr && fl_value_get_type(label) == FL_VALUE_TYPE_STRING) { - gtk_file_filter_set_name(filter, fl_value_get_string(label)); - } - - FlValue* extensions = fl_value_lookup_string(value, kTypeGroupExtensionsKey); - if (extensions != nullptr && - fl_value_get_type(extensions) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(extensions); i++) { - FlValue* v = fl_value_get_list_value(extensions, i); - const gchar* pattern = fl_value_get_string(v); - gtk_file_filter_add_pattern(filter, pattern); - } - } - FlValue* mime_types = fl_value_lookup_string(value, kTypeGroupMimeTypesKey); - if (mime_types != nullptr && - fl_value_get_type(mime_types) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(mime_types); i++) { - FlValue* v = fl_value_get_list_value(mime_types, i); - const gchar* pattern = fl_value_get_string(v); - gtk_file_filter_add_mime_type(filter, pattern); - } - } - - return GTK_FILE_FILTER(g_object_ref(filter)); -} - -// Creates a GtkFileChooserNative for the given method call details. -static GtkFileChooserNative* create_dialog( - GtkWindow* window, GtkFileChooserAction action, const gchar* title, - const gchar* default_confirm_button_text, FlValue* properties) { - const gchar* confirm_button_text = default_confirm_button_text; - FlValue* value = fl_value_lookup_string(properties, kConfirmButtonTextKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) - confirm_button_text = fl_value_get_string(value); - - g_autoptr(GtkFileChooserNative) dialog = - GTK_FILE_CHOOSER_NATIVE(gtk_file_chooser_native_new( - title, window, action, confirm_button_text, "_Cancel")); - - value = fl_value_lookup_string(properties, kMultipleKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_BOOL) { - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), - fl_value_get_bool(value)); - } - - value = fl_value_lookup_string(properties, kInitialDirectoryKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), - fl_value_get_string(value)); - } - - value = fl_value_lookup_string(properties, kSuggestedNameKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_STRING) { - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), - fl_value_get_string(value)); - } - - value = fl_value_lookup_string(properties, kAcceptedTypeGroupsKey); - if (value != nullptr && fl_value_get_type(value) == FL_VALUE_TYPE_LIST) { - for (size_t i = 0; i < fl_value_get_length(value); i++) { - FlValue* type_group = fl_value_get_list_value(value, i); - GtkFileFilter* filter = type_group_to_filter(type_group); - if (filter == nullptr) { - return nullptr; - } - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - } - } - - return GTK_FILE_CHOOSER_NATIVE(g_object_ref(dialog)); -} - -// TODO(stuartmorgan): Move this logic back into method_call_cb once -// https://github.com/flutter/flutter/issues/88724 is fixed, and test -// through the public API instead. This only exists to move as much -// logic as possible behind the private entry point used by unit tests. -GtkFileChooserNative* create_dialog_for_method(GtkWindow* window, - const gchar* method, - FlValue* properties) { - if (strcmp(method, kOpenFileMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_OPEN, "Open File", - "_Open", properties); - } else if (strcmp(method, kGetDirectoryPathMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, - "Choose Directory", "_Open", properties); - } else if (strcmp(method, kGetSavePathMethod) == 0) { - return create_dialog(window, GTK_FILE_CHOOSER_ACTION_SAVE, "Save File", - "_Save", properties); - } - return nullptr; -} - -// Shows the requested dialog type. -static FlMethodResponse* show_dialog(FlFileSelectorPlugin* self, - const gchar* method, FlValue* properties, - bool return_list) { - if (fl_value_get_type(properties) != FL_VALUE_TYPE_MAP) { - return FL_METHOD_RESPONSE(fl_method_error_response_new( - kBadArgumentsError, "Argument map missing or malformed", nullptr)); - } - - FlView* view = fl_plugin_registrar_get_view(self->registrar); - if (view == nullptr) { - return FL_METHOD_RESPONSE( - fl_method_error_response_new(kNoScreenError, nullptr, nullptr)); - } - GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(view))); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(window, method, properties); - - if (dialog == nullptr) { - return FL_METHOD_RESPONSE(fl_method_error_response_new( - kBadArgumentsError, "Unable to create dialog from arguments", nullptr)); - } - - gint response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog)); - g_autoptr(FlValue) result = nullptr; - if (response == GTK_RESPONSE_ACCEPT) { - if (return_list) { - result = fl_value_new_list(); - g_autoptr(GSList) filenames = - gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - for (GSList* link = filenames; link != nullptr; link = link->next) { - g_autofree gchar* filename = static_cast(link->data); - fl_value_append_take(result, fl_value_new_string(filename)); - } - } else { - g_autofree gchar* filename = - gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - result = fl_value_new_string(filename); - } - } - - return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); -} - -// Called when a method call is received from Flutter. -static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, - gpointer user_data) { - FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN(user_data); - - const gchar* method = fl_method_call_get_name(method_call); - FlValue* args = fl_method_call_get_args(method_call); - - g_autoptr(FlMethodResponse) response = nullptr; - if (strcmp(method, kOpenFileMethod) == 0) { - response = show_dialog(self, method, args, true); - } else if (strcmp(method, kGetDirectoryPathMethod) == 0 || - strcmp(method, kGetSavePathMethod) == 0) { - response = show_dialog(self, method, args, false); - } else { - response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); - } - - g_autoptr(GError) error = nullptr; - if (!fl_method_call_respond(method_call, response, &error)) - g_warning("Failed to send method call response: %s", error->message); -} - -static void fl_file_selector_plugin_dispose(GObject* object) { - FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN(object); - - g_clear_object(&self->registrar); - g_clear_object(&self->channel); - - G_OBJECT_CLASS(fl_file_selector_plugin_parent_class)->dispose(object); -} - -static void fl_file_selector_plugin_class_init( - FlFileSelectorPluginClass* klass) { - G_OBJECT_CLASS(klass)->dispose = fl_file_selector_plugin_dispose; -} - -static void fl_file_selector_plugin_init(FlFileSelectorPlugin* self) {} - -FlFileSelectorPlugin* fl_file_selector_plugin_new( - FlPluginRegistrar* registrar) { - FlFileSelectorPlugin* self = FL_FILE_SELECTOR_PLUGIN( - g_object_new(fl_file_selector_plugin_get_type(), nullptr)); - - self->registrar = FL_PLUGIN_REGISTRAR(g_object_ref(registrar)); - - g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); - self->channel = - fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), - kChannelName, FL_METHOD_CODEC(codec)); - fl_method_channel_set_method_call_handler(self->channel, method_call_cb, - g_object_ref(self), g_object_unref); - - return self; -} - -void file_selector_plugin_register_with_registrar( - FlPluginRegistrar* registrar) { - FlFileSelectorPlugin* plugin = fl_file_selector_plugin_new(registrar); - g_object_unref(plugin); -} diff --git a/plugins/file_selector/file_selector_linux/linux/file_selector_plugin_private.h b/plugins/file_selector/file_selector_linux/linux/file_selector_plugin_private.h deleted file mode 100644 index e58a78ccd..000000000 --- a/plugins/file_selector/file_selector_linux/linux/file_selector_plugin_private.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include "include/file_selector_linux/file_selector_plugin.h" - -// Creates a GtkFileChooserNative for the given method call. -GtkFileChooserNative* create_dialog_for_method(GtkWindow* window, - const gchar* method, - FlValue* properties); diff --git a/plugins/file_selector/file_selector_linux/linux/include/file_selector_linux/file_selector_plugin.h b/plugins/file_selector/file_selector_linux/linux/include/file_selector_linux/file_selector_plugin.h deleted file mode 100644 index 9a00d1566..000000000 --- a/plugins/file_selector/file_selector_linux/linux/include/file_selector_linux/file_selector_plugin.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PLUGINS_FILE_SELECTOR_LINUX_FILE_SELECTOR_PLUGIN_H_ -#define PLUGINS_FILE_SELECTOR_LINUX_FILE_SELECTOR_PLUGIN_H_ - -// A plugin to show native save/open file choosers. - -#include - -G_BEGIN_DECLS - -#ifdef FLUTTER_PLUGIN_IMPL -#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) -#else -#define FLUTTER_PLUGIN_EXPORT -#endif - -G_DECLARE_FINAL_TYPE(FlFileSelectorPlugin, fl_file_selector_plugin, FL, - FILE_SELECTOR_PLUGIN, GObject) - -FLUTTER_PLUGIN_EXPORT FlFileSelectorPlugin* fl_file_selector_plugin_new( - FlPluginRegistrar* registrar); - -FLUTTER_PLUGIN_EXPORT void file_selector_plugin_register_with_registrar( - FlPluginRegistrar* registrar); - -G_END_DECLS - -#endif // PLUGINS_FILE_SELECTOR_LINUX_FILE_SELECTOR_PLUGIN_H_ diff --git a/plugins/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc b/plugins/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc deleted file mode 100644 index 2e12c464a..000000000 --- a/plugins/file_selector/file_selector_linux/linux/test/file_selector_plugin_test.cc +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#include "include/file_selector_linux/file_selector_plugin.h" - -#include -#include -#include - -#include "file_selector_plugin_private.h" - -// TODO(stuartmorgan): Restructure the helper to take a callback for showing -// the dialog, so that the tests can mock out that callback with something -// that changes the selection so that the return value path can be tested -// as well. -// TODO(stuartmorgan): Add an injectable wrapper around -// gtk_file_chooser_native_new to allow for testing values that are given as -// construction paramaters and can't be queried later. - -TEST(FileSelectorPlugin, TestOpenSimple) { - g_autoptr(FlValue) args = fl_value_new_map(); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_OPEN); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - false); -} - -TEST(FileSelectorPlugin, TestOpenMultiple) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "multiple", fl_value_new_bool(true)); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_OPEN); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - true); -} - -TEST(FileSelectorPlugin, TestOpenWithFilter) { - g_autoptr(FlValue) type_groups = fl_value_new_list(); - - { - g_autoptr(FlValue) text_group_mime_types = fl_value_new_list(); - fl_value_append_take(text_group_mime_types, - fl_value_new_string("text/plain")); - g_autoptr(FlValue) text_group = fl_value_new_map(); - fl_value_set_string_take(text_group, "label", fl_value_new_string("Text")); - fl_value_set_string(text_group, "mimeTypes", text_group_mime_types); - fl_value_append(type_groups, text_group); - } - - { - g_autoptr(FlValue) image_group_extensions = fl_value_new_list(); - fl_value_append_take(image_group_extensions, fl_value_new_string("*.png")); - fl_value_append_take(image_group_extensions, fl_value_new_string("*.gif")); - fl_value_append_take(image_group_extensions, fl_value_new_string("*.jgpeg")); - g_autoptr(FlValue) image_group = fl_value_new_map(); - fl_value_set_string_take(image_group, "label", - fl_value_new_string("Images")); - fl_value_set_string(image_group, "extensions", image_group_extensions); - fl_value_append(type_groups, image_group); - } - - { - g_autoptr(FlValue) any_group_extensions = fl_value_new_list(); - fl_value_append_take(any_group_extensions, fl_value_new_string("*")); - g_autoptr(FlValue) any_group = fl_value_new_map(); - fl_value_set_string_take(any_group, "label", fl_value_new_string("Any")); - fl_value_set_string(any_group, "extensions", any_group_extensions); - fl_value_append(type_groups, any_group); - } - - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string(args, "acceptedTypeGroups", type_groups); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "openFile", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_OPEN); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - false); - // Validate filters. - g_autoptr(GSList) type_group_list = - gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(dialog)); - EXPECT_EQ(g_slist_length(type_group_list), 3); - GtkFileFilter* text_filter = - GTK_FILE_FILTER(g_slist_nth_data(type_group_list, 0)); - GtkFileFilter* image_filter = - GTK_FILE_FILTER(g_slist_nth_data(type_group_list, 1)); - GtkFileFilter* any_filter = - GTK_FILE_FILTER(g_slist_nth_data(type_group_list, 2)); - // Filters can't be inspected, so query them to see that they match expected - // filter behavior. - GtkFileFilterInfo text_file_info = {}; - text_file_info.contains = static_cast( - GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE); - text_file_info.display_name = "foo.txt"; - text_file_info.mime_type = "text/plain"; - GtkFileFilterInfo image_file_info = {}; - image_file_info.contains = static_cast( - GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE); - image_file_info.display_name = "foo.png"; - image_file_info.mime_type = "image/png"; - EXPECT_TRUE(gtk_file_filter_filter(text_filter, &text_file_info)); - EXPECT_FALSE(gtk_file_filter_filter(text_filter, &image_file_info)); - EXPECT_FALSE(gtk_file_filter_filter(image_filter, &text_file_info)); - EXPECT_TRUE(gtk_file_filter_filter(image_filter, &image_file_info)); - EXPECT_TRUE(gtk_file_filter_filter(any_filter, &image_file_info)); - EXPECT_TRUE(gtk_file_filter_filter(any_filter, &text_file_info)); -} - -TEST(FileSelectorPlugin, TestSaveSimple) { - g_autoptr(FlValue) args = fl_value_new_map(); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getSavePath", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_SAVE); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - false); -} - -TEST(FileSelectorPlugin, TestSaveWithArguments) { - g_autoptr(FlValue) args = fl_value_new_map(); - fl_value_set_string_take(args, "initialDirectory", - fl_value_new_string("/tmp")); - fl_value_set_string_take(args, "suggestedName", - fl_value_new_string("foo.txt")); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getSavePath", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_SAVE); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - false); - g_autofree gchar* current_name = - gtk_file_chooser_get_current_name(GTK_FILE_CHOOSER(dialog)); - EXPECT_STREQ(current_name, "foo.txt"); - // TODO(stuartmorgan): gtk_file_chooser_get_current_folder doesn't seem to - // return a value set by gtk_file_chooser_set_current_folder, or at least - // doesn't in a test context, so that's not currently validated. -} - -TEST(FileSelectorPlugin, TestGetDirectory) { - g_autoptr(FlValue) args = fl_value_new_map(); - - g_autoptr(GtkFileChooserNative) dialog = - create_dialog_for_method(nullptr, "getDirectoryPath", args); - - ASSERT_NE(dialog, nullptr); - EXPECT_EQ(gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)), - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); - EXPECT_EQ(gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog)), - false); -} diff --git a/plugins/file_selector/file_selector_linux/linux/test/test_main.cc b/plugins/file_selector/file_selector_linux/linux/test/test_main.cc deleted file mode 100644 index 9bcf05853..000000000 --- a/plugins/file_selector/file_selector_linux/linux/test/test_main.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#include -#include - -int main(int argc, char** argv) { - gtk_init(0, nullptr); - - testing::InitGoogleTest(&argc, argv); - int exit_code = RUN_ALL_TESTS(); - - return exit_code; -} diff --git a/plugins/file_selector/file_selector_linux/pubspec.yaml b/plugins/file_selector/file_selector_linux/pubspec.yaml deleted file mode 100644 index c7bdb40ff..000000000 --- a/plugins/file_selector/file_selector_linux/pubspec.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: file_selector_linux -description: Liunx implementation of the file_selector plugin. -version: 0.0.3 -homepage: https://github.com/google/flutter-desktop-embedding/tree/master/plugins/file_selector/file_selector_linux - -flutter: - plugin: - implements: file_selector - platforms: - linux: - pluginClass: FileSelectorPlugin - dartPluginClass: FileSelectorLinux - -environment: - sdk: ">=2.12.0 <3.0.0" - flutter: ">=1.22.0" - -dependencies: - cross_file: ^0.3.1 - file_selector_platform_interface: ^2.1.0 - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter diff --git a/plugins/file_selector/file_selector_linux/test/file_selector_linux_test.dart b/plugins/file_selector/file_selector_linux/test/file_selector_linux_test.dart deleted file mode 100644 index 67b99298a..000000000 --- a/plugins/file_selector/file_selector_linux/test/file_selector_linux_test.dart +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file_selector_linux/file_selector_linux.dart'; -import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - late FileSelectorLinux plugin; - late List log; - - setUp(() { - plugin = FileSelectorLinux(); - log = []; - plugin.channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return null; - }); - }); - - test('registers instance', () { - FileSelectorLinux.registerWith(); - expect(FileSelectorPlatform.instance, isA()); - }); - - group('#openFile', () { - test('passes the accepted type groups correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'text', - extensions: ['txt'], - mimeTypes: ['text/plain'], - macUTIs: ['public.text'], - ); - - final XTypeGroup groupTwo = XTypeGroup( - label: 'image', - extensions: ['jpg'], - mimeTypes: ['image/jpg'], - macUTIs: ['public.image'], - webWildCards: ['image/*'], - ); - - await plugin.openFile(acceptedTypeGroups: [group, groupTwo]); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }), - ], - ); - }); - - test('passes initialDirectory correctly', () async { - await plugin.openFile(initialDirectory: '/example/directory'); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - 'multiple': false, - }), - ], - ); - }); - - test('passes confirmButtonText correctly', () async { - await plugin.openFile(confirmButtonText: 'Open File'); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Open File', - 'multiple': false, - }), - ], - ); - }); - - test('throws for a type group that does not support Linux', () async { - final XTypeGroup group = XTypeGroup( - label: 'images', - webWildCards: ['images/*'], - ); - - await expectLater( - plugin.openFile(acceptedTypeGroups: [group]), - throwsArgumentError); - }); - - test('passes a wildcard group correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'any', - ); - - await plugin.openFile(acceptedTypeGroups: [group]); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }), - ], - ); - }); - }); - - group('#openFiles', () { - test('passes the accepted type groups correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'text', - extensions: ['txt'], - mimeTypes: ['text/plain'], - macUTIs: ['public.text'], - ); - - final XTypeGroup groupTwo = XTypeGroup( - label: 'image', - extensions: ['jpg'], - mimeTypes: ['image/jpg'], - macUTIs: ['public.image'], - webWildCards: ['image/*'], - ); - - await plugin.openFiles(acceptedTypeGroups: [group, groupTwo]); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': true, - }), - ], - ); - }); - - test('passes initialDirectory correctly', () async { - await plugin.openFiles(initialDirectory: '/example/directory'); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - 'multiple': true, - }), - ], - ); - }); - - test('passes confirmButtonText correctly', () async { - await plugin.openFiles(confirmButtonText: 'Open File'); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Open File', - 'multiple': true, - }), - ], - ); - }); - - test('throws for a type group that does not support Linux', () async { - final XTypeGroup group = XTypeGroup( - label: 'images', - webWildCards: ['images/*'], - ); - - await expectLater( - plugin.openFile(acceptedTypeGroups: [group]), - throwsArgumentError); - }); - - test('passes a wildcard group correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'any', - ); - - await plugin.openFile(acceptedTypeGroups: [group]); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }), - ], - ); - }); - }); - - group('#getSavePath', () { - test('passes the accepted type groups correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'text', - extensions: ['txt'], - mimeTypes: ['text/plain'], - macUTIs: ['public.text'], - ); - - final XTypeGroup groupTwo = XTypeGroup( - label: 'image', - extensions: ['jpg'], - mimeTypes: ['image/jpg'], - macUTIs: ['public.image'], - webWildCards: ['image/*'], - ); - - await plugin - .getSavePath(acceptedTypeGroups: [group, groupTwo]); - - expect( - log, - [ - isMethodCall('getSavePath', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'text', - 'extensions': ['*.txt'], - 'mimeTypes': ['text/plain'], - }, - { - 'label': 'image', - 'extensions': ['*.jpg'], - 'mimeTypes': ['image/jpg'], - }, - ], - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': null, - }), - ], - ); - }); - - test('passes initialDirectory correctly', () async { - await plugin.getSavePath(initialDirectory: '/example/directory'); - - expect( - log, - [ - isMethodCall('getSavePath', arguments: { - 'initialDirectory': '/example/directory', - 'suggestedName': null, - 'confirmButtonText': null, - }), - ], - ); - }); - - test('passes confirmButtonText correctly', () async { - await plugin.getSavePath(confirmButtonText: 'Open File'); - - expect( - log, - [ - isMethodCall('getSavePath', arguments: { - 'initialDirectory': null, - 'suggestedName': null, - 'confirmButtonText': 'Open File', - }), - ], - ); - }); - - test('throws for a type group that does not support Linux', () async { - final XTypeGroup group = XTypeGroup( - label: 'images', - webWildCards: ['images/*'], - ); - - await expectLater( - plugin.openFile(acceptedTypeGroups: [group]), - throwsArgumentError); - }); - - test('passes a wildcard group correctly', () async { - final XTypeGroup group = XTypeGroup( - label: 'any', - ); - - await plugin.openFile(acceptedTypeGroups: [group]); - - expect( - log, - [ - isMethodCall('openFile', arguments: { - 'acceptedTypeGroups': >[ - { - 'label': 'any', - 'extensions': ['*'], - }, - ], - 'initialDirectory': null, - 'confirmButtonText': null, - 'multiple': false, - }), - ], - ); - }); - }); - - group('#getDirectoryPath', () { - test('passes initialDirectory correctly', () async { - await plugin.getDirectoryPath(initialDirectory: '/example/directory'); - - expect( - log, - [ - isMethodCall('getDirectoryPath', arguments: { - 'initialDirectory': '/example/directory', - 'confirmButtonText': null, - }), - ], - ); - }); - test('passes confirmButtonText correctly', () async { - await plugin.getDirectoryPath(confirmButtonText: 'Open File'); - - expect( - log, - [ - isMethodCall('getDirectoryPath', arguments: { - 'initialDirectory': null, - 'confirmButtonText': 'Open File', - }), - ], - ); - }); - }); -}