fix: Récupérer l'opération active depuis la table operations

- Corrige l'erreur SQL 'Unknown column fk_operation in users'
- L'opération active est récupérée depuis operations.chk_active = 1
- Jointure avec users pour filtrer par entité de l'admin créateur
- Query: SELECT o.id FROM operations o INNER JOIN users u ON u.fk_entite = o.fk_entite WHERE u.id = ? AND o.chk_active = 1
This commit is contained in:
2026-01-26 16:57:08 +01:00
parent c24a3afe6a
commit 0687900564
3040 changed files with 77204 additions and 1578 deletions

View File

@@ -1 +0,0 @@
/home/pierre/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/

View File

@@ -0,0 +1,66 @@
# Below is a list of people and organizations that have contributed
# to the Flutter project. Names should be added to the list like so:
#
# Name/Organization <email address>
Google Inc.
The Chromium Authors
German Saprykin <saprykin.h@gmail.com>
Benjamin Sauer <sauer.benjamin@gmail.com>
larsenthomasj@gmail.com
Ali Bitek <alibitek@protonmail.ch>
Pol Batlló <pol.batllo@gmail.com>
Anatoly Pulyaevskiy
Hayden Flinner <haydenflinner@gmail.com>
Stefano Rodriguez <hlsroddy@gmail.com>
Salvatore Giordano <salvatoregiordanoo@gmail.com>
Brian Armstrong <brian@flutter.institute>
Paul DeMarco <paulmdemarco@gmail.com>
Fabricio Nogueira <feufeu@gmail.com>
Simon Lightfoot <simon@devangels.london>
Ashton Thomas <ashton@acrinta.com>
Thomas Danner <thmsdnnr@gmail.com>
Diego Velásquez <diego.velasquez.lopez@gmail.com>
Hajime Nakamura <nkmrhj@gmail.com>
Tuyển Vũ Xuân <netsoft1985@gmail.com>
Miguel Ruivo <miguel@miguelruivo.com>
Sarthak Verma <sarthak@artiosys.com>
Mike Diarmid <mike@invertase.io>
Invertase <oss@invertase.io>
Elliot Hesp <elliot@invertase.io>
Vince Varga <vince.varga@smaho.com>
Aawaz Gyawali <awazgyawali@gmail.com>
EUI Limited <ian.evans3@admiralgroup.co.uk>
Katarina Sheremet <katarina@sheremet.ch>
Thomas Stockx <thomas@stockxit.com>
Sarbagya Dhaubanjar <sarbagyastha@gmail.com>
Ozkan Eksi <ozeksi@gmail.com>
Rishab Nayak <rishab@bu.edu>
ko2ic <ko2ic.dev@gmail.com>
Jonathan Younger <jonathan@daikini.com>
Jose Sanchez <josesm82@gmail.com>
Debkanchan Samadder <debu.samadder@gmail.com>
Audrius Karosevicius <audrius.karosevicius@gmail.com>
Lukasz Piliszczuk <lukasz@intheloup.io>
SoundReply Solutions GmbH <ch@soundreply.com>
Rafal Wachol <rwachol@gmail.com>
Pau Picas <pau.picas@gmail.com>
Christian Weder <chrstian.weder@yapeal.ch>
Alexandru Tuca <salexandru.tuca@outlook.com>
Christian Weder <chrstian.weder@yapeal.ch>
Rhodes Davis Jr. <rody.davis.jr@gmail.com>
Luigi Agosti <luigi@tengio.com>
Quentin Le Guennec <quentin@tengio.com>
Koushik Ravikumar <koushik@tengio.com>
Nissim Dsilva <nissim@tengio.com>
Giancarlo Rocha <giancarloiff@gmail.com>
Ryo Miyake <ryo@miyake.id>
Théo Champion <contact.theochampion@gmail.com>
Kazuki Yamaguchi <y.kazuki0614n@gmail.com>
Eitan Schwartz <eshvartz@gmail.com>
Chris Rutkowski <chrisrutkowski89@gmail.com>
Juan Alvarez <juan.alvarez@resideo.com>
Aleksandr Yurkovskiy <sanekyy@gmail.com>
Anton Borries <mail@antonborri.es>
Alex Li <google@alexv525.com>
Rahul Raj <64.rahulraj@gmail.com>

View File

@@ -0,0 +1,109 @@
## 2.2.1
* Adds pub topics to package metadata.
* Updates minimum supported SDK version to Flutter 3.7/Dart 2.19.
## 2.2.0
* Adds getApplicationCachePath() for storing app-specific cache files.
## 2.1.11
* Removes obsolete null checks on non-nullable values.
* Updates minimum supported SDK version to Flutter 3.3/Dart 2.18.
## 2.1.10
* Clarifies explanation of endorsement in README.
* Aligns Dart and Flutter SDK constraints.
## 2.1.9
* Updates links for the merge of flutter/plugins into flutter/packages.
## 2.1.8
* Adds compatibility with `xdg_directories` 1.0.
* Updates minimum Flutter version to 3.0.
## 2.1.7
* Bumps ffi dependency to match path_provider_windows.
## 2.1.6
* Fixes library_private_types_in_public_api, sort_child_properties_last and use_key_in_widget_constructors
lint warnings.
## 2.1.5
* Removes dependency on `meta`.
## 2.1.4
* Fixes `getApplicationSupportPath` handling of applications where the
application ID is not set.
## 2.1.3
* Change getApplicationSupportPath from using executable name to application ID (if provided).
* If the executable name based directory exists, continue to use that so existing applications continue with the same behaviour.
## 2.1.2
* Fixes link in README.
## 2.1.1
* Removed obsolete `pluginClass: none` from pubpsec.
## 2.1.0
* Now `getTemporaryPath` returns the value of the `TMPDIR` environment variable primarily. If `TMPDIR` is not set, `/tmp` is returned.
## 2.0.2
* Updated installation instructions in README.
## 2.0.1
* Add `implements` to pubspec.yaml.
* Add `registerWith` method to the main Dart class.
## 2.0.0
* Migrate to null safety.
## 0.1.1+3
* Update Flutter SDK constraint.
## 0.1.1+2
* Log errors in the example when calls to the `path_provider` fail.
## 0.1.1+1
* Check in linux/ directory for example/
## 0.1.1 - NOT PUBLISHED
* Reverts changes on 0.1.0, which broke the tree.
## 0.1.0 - NOT PUBLISHED
* This release updates getApplicationSupportPath to use the application ID instead of the executable name.
* No migration is provided, so any older apps that were using this path will now have a different directory.
## 0.0.1+2
* This release updates the example to depend on the endorsed plugin rather than relative path
## 0.0.1+1
* This updates the readme and pubspec and example to reflect the endorsement of this implementation of `path_provider`
## 0.0.1
* The initial implementation of path\_provider for Linux
* Implements getApplicationSupportPath, getApplicationDocumentsPath, getDownloadsPath, and getTemporaryPath

View File

@@ -0,0 +1,25 @@
Copyright 2013 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.

View File

@@ -0,0 +1,15 @@
# path\_provider\_linux
The linux implementation of [`path_provider`][1].
## Usage
This package is [endorsed][2], which means you can simply use `path_provider`
normally. This package will be automatically included in your app when you do,
so you do not need to add it to your `pubspec.yaml`.
However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.
[1]: https://pub.dev/packages/path_provider
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin

View File

@@ -0,0 +1,9 @@
# Platform Implementation Test App
This is a test app for manual testing and automated integration testing
of this platform implementation. It is not intended to demonstrate actual use of
this package, since the intent is that plugin clients use the app-facing
package.
Unless you are making changes to this implementation package, this example is
very unlikely to be relevant.

View File

@@ -0,0 +1,66 @@
// 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:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path_provider_linux/path_provider_linux.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('getTemporaryDirectory', (WidgetTester tester) async {
final PathProviderLinux provider = PathProviderLinux();
final String? result = await provider.getTemporaryPath();
_verifySampleFile(result, 'temporaryDirectory');
});
testWidgets('getDownloadDirectory', (WidgetTester tester) async {
if (!Platform.isLinux) {
return;
}
final PathProviderLinux provider = PathProviderLinux();
final String? result = await provider.getDownloadsPath();
_verifySampleFile(result, 'downloadDirectory');
});
testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async {
final PathProviderLinux provider = PathProviderLinux();
final String? result = await provider.getApplicationDocumentsPath();
_verifySampleFile(result, 'applicationDocuments');
});
testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async {
final PathProviderLinux provider = PathProviderLinux();
final String? result = await provider.getApplicationSupportPath();
_verifySampleFile(result, 'applicationSupport');
});
testWidgets('getApplicationCacheDirectory', (WidgetTester tester) async {
final PathProviderLinux provider = PathProviderLinux();
final String? result = await provider.getApplicationCachePath();
_verifySampleFile(result, 'applicationCache');
});
}
/// Verify a file called [name] in [directoryPath] by recreating it with test
/// contents when necessary.
void _verifySampleFile(String? directoryPath, String name) {
expect(directoryPath, isNotNull);
if (directoryPath == null) {
return;
}
final Directory directory = Directory(directoryPath);
final File file = File('${directory.path}${Platform.pathSeparator}$name');
if (file.existsSync()) {
file.deleteSync();
expect(file.existsSync(), isFalse);
}
file.writeAsStringSync('Hello world!');
expect(file.readAsStringSync(), 'Hello world!');
expect(directory.listSync(), isNotEmpty);
file.deleteSync();
}

View File

@@ -0,0 +1,109 @@
// 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 'package:flutter/services.dart';
import 'package:path_provider_linux/path_provider_linux.dart';
void main() {
runApp(const MyApp());
}
/// Sample app
class MyApp extends StatefulWidget {
/// Default Constructor
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? _tempDirectory = 'Unknown';
String? _downloadsDirectory = 'Unknown';
String? _appSupportDirectory = 'Unknown';
String? _appCacheDirectory = 'Unknown';
String? _documentsDirectory = 'Unknown';
final PathProviderLinux _provider = PathProviderLinux();
@override
void initState() {
super.initState();
initDirectories();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initDirectories() async {
String? tempDirectory;
String? downloadsDirectory;
String? appSupportDirectory;
String? appCacheDirectory;
String? documentsDirectory;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
tempDirectory = await _provider.getTemporaryPath();
} on PlatformException {
tempDirectory = 'Failed to get temp directory.';
}
try {
downloadsDirectory = await _provider.getDownloadsPath();
} on PlatformException {
downloadsDirectory = 'Failed to get downloads directory.';
}
try {
documentsDirectory = await _provider.getApplicationDocumentsPath();
} on PlatformException {
documentsDirectory = 'Failed to get documents directory.';
}
try {
appSupportDirectory = await _provider.getApplicationSupportPath();
} on PlatformException {
appSupportDirectory = 'Failed to get documents directory.';
}
try {
appCacheDirectory = await _provider.getApplicationCachePath();
} on PlatformException {
appCacheDirectory = 'Failed to get cache directory.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
return;
}
setState(() {
_tempDirectory = tempDirectory;
_downloadsDirectory = downloadsDirectory;
_appSupportDirectory = appSupportDirectory;
_appCacheDirectory = appCacheDirectory;
_documentsDirectory = documentsDirectory;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Path Provider Linux example app'),
),
body: Center(
child: Column(
children: <Widget>[
Text('Temp Directory: $_tempDirectory\n'),
Text('Documents Directory: $_documentsDirectory\n'),
Text('Downloads Directory: $_downloadsDirectory\n'),
Text('Application Support Directory: $_appSupportDirectory\n'),
Text('Application Cache Directory: $_appCacheDirectory\n'),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,106 @@
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
set(BINARY_NAME "example")
set(APPLICATION_ID "dev.flutter.plugins.path_provider_linux_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 "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>: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"
)
# 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()

View File

@@ -0,0 +1,86 @@
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"
linux-x64 ${CMAKE_BUILD_TYPE}
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)

View File

@@ -0,0 +1,23 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
)
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 $<TARGET_FILE:${plugin}_plugin>)
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)

View File

@@ -0,0 +1,15 @@
// 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 "my_application.h"
int main(int argc, char** argv) {
// Only X11 is currently supported.
// Wayland support is being developed:
// https://github.com/flutter/flutter/issues/57932.
gdk_set_allowed_backends("x11");
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}

View File

@@ -0,0 +1,49 @@
// 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 "my_application.h"
#include <flutter_linux/flutter_linux.h>
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
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));
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
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));
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
}
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));
}

View File

@@ -0,0 +1,22 @@
// 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.
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
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_

View File

@@ -0,0 +1,28 @@
name: pathproviderexample
description: Demonstrates how to use the path_provider_linux plugin.
publish_to: "none"
environment:
sdk: ">=2.19.0 <4.0.0"
flutter: ">=3.7.0"
dependencies:
flutter:
sdk: flutter
path_provider_linux:
# When depending on this package from a real application you should use:
# path_provider_linux: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
flutter:
uses-material-design: true

View File

@@ -0,0 +1,7 @@
// 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:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();

View File

@@ -0,0 +1,5 @@
// 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.
export 'src/path_provider_linux.dart';

View File

@@ -0,0 +1,9 @@
// 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.
// getApplicationId() is implemented using FFI; export a stub for platforms
// that don't support FFI (e.g., web) to avoid having transitive dependencies
// break web compilation.
export 'get_application_id_stub.dart'
if (dart.library.ffi) 'get_application_id_real.dart';

View File

@@ -0,0 +1,78 @@
// 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:ffi';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart' show visibleForTesting;
// GApplication* g_application_get_default();
typedef _GApplicationGetDefaultC = IntPtr Function();
typedef _GApplicationGetDefaultDart = int Function();
// const gchar* g_application_get_application_id(GApplication* application);
typedef _GApplicationGetApplicationIdC = Pointer<Utf8> Function(IntPtr);
typedef _GApplicationGetApplicationIdDart = Pointer<Utf8> Function(int);
/// Interface for interacting with libgio.
@visibleForTesting
class GioUtils {
/// Creates a default instance that uses the real libgio.
GioUtils() {
try {
_gio = DynamicLibrary.open('libgio-2.0.so');
} on ArgumentError {
_gio = null;
}
}
DynamicLibrary? _gio;
/// True if libgio was opened successfully.
bool get libraryIsPresent => _gio != null;
/// Wraps `g_application_get_default`.
int gApplicationGetDefault() {
if (_gio == null) {
return 0;
}
final _GApplicationGetDefaultDart getDefault = _gio!
.lookupFunction<_GApplicationGetDefaultC, _GApplicationGetDefaultDart>(
'g_application_get_default');
return getDefault();
}
/// Wraps g_application_get_application_id.
Pointer<Utf8> gApplicationGetApplicationId(int app) {
if (_gio == null) {
return nullptr;
}
final _GApplicationGetApplicationIdDart gApplicationGetApplicationId = _gio!
.lookupFunction<_GApplicationGetApplicationIdC,
_GApplicationGetApplicationIdDart>(
'g_application_get_application_id');
return gApplicationGetApplicationId(app);
}
}
/// Allows overriding the default GioUtils instance with a fake for testing.
@visibleForTesting
GioUtils? gioUtilsOverride;
/// Gets the application ID for this app.
String? getApplicationId() {
final GioUtils gio = gioUtilsOverride ?? GioUtils();
if (!gio.libraryIsPresent) {
return null;
}
final int app = gio.gApplicationGetDefault();
if (app == 0) {
return null;
}
final Pointer<Utf8> appId = gio.gApplicationGetApplicationId(app);
if (appId == nullptr) {
return null;
}
return appId.toDartString();
}

View File

@@ -0,0 +1,6 @@
// 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.
/// Gets the application ID for this app.
String? getApplicationId() => null;

View File

@@ -0,0 +1,102 @@
// 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:flutter/foundation.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;
import 'get_application_id.dart';
/// The linux implementation of [PathProviderPlatform]
///
/// This class implements the `package:path_provider` functionality for Linux.
class PathProviderLinux extends PathProviderPlatform {
/// Constructs an instance of [PathProviderLinux]
PathProviderLinux() : _environment = Platform.environment;
/// Constructs an instance of [PathProviderLinux] with the given [environment]
@visibleForTesting
PathProviderLinux.private(
{Map<String, String> environment = const <String, String>{},
String? executableName,
String? applicationId})
: _environment = environment,
_executableName = executableName,
_applicationId = applicationId;
final Map<String, String> _environment;
String? _executableName;
String? _applicationId;
/// Registers this class as the default instance of [PathProviderPlatform]
static void registerWith() {
PathProviderPlatform.instance = PathProviderLinux();
}
@override
Future<String?> getTemporaryPath() {
final String environmentTmpDir = _environment['TMPDIR'] ?? '';
return Future<String?>.value(
environmentTmpDir.isEmpty ? '/tmp' : environmentTmpDir,
);
}
@override
Future<String?> getApplicationSupportPath() async {
final Directory directory =
Directory(path.join(xdg.dataHome.path, await _getId()));
if (directory.existsSync()) {
return directory.path;
}
// This plugin originally used the executable name as a directory.
// Use that if it exists for backwards compatibility.
final Directory legacyDirectory =
Directory(path.join(xdg.dataHome.path, await _getExecutableName()));
if (legacyDirectory.existsSync()) {
return legacyDirectory.path;
}
// Create the directory, because mobile implementations assume the directory exists.
await directory.create(recursive: true);
return directory.path;
}
@override
Future<String?> getApplicationDocumentsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOCUMENTS')?.path);
}
@override
Future<String?> getApplicationCachePath() async {
final Directory directory =
Directory(path.join(xdg.cacheHome.path, await _getId()));
if (!directory.existsSync()) {
await directory.create(recursive: true);
}
return directory.path;
}
@override
Future<String?> getDownloadsPath() {
return Future<String?>.value(xdg.getUserDirectory('DOWNLOAD')?.path);
}
// Gets the name of this executable.
Future<String> _getExecutableName() async {
_executableName ??= path.basenameWithoutExtension(
await File('/proc/self/exe').resolveSymbolicLinks());
return _executableName!;
}
// Gets the unique ID for this application.
Future<String> _getId() async {
_applicationId ??= getApplicationId();
// If no application ID then fall back to using the executable name.
return _applicationId ?? await _getExecutableName();
}
}

View File

@@ -0,0 +1,33 @@
name: path_provider_linux
description: Linux implementation of the path_provider plugin
repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_linux
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22
version: 2.2.1
environment:
sdk: ">=2.19.0 <4.0.0"
flutter: ">=3.7.0"
flutter:
plugin:
implements: path_provider
platforms:
linux:
dartPluginClass: PathProviderLinux
dependencies:
ffi: ">=1.1.2 <3.0.0"
flutter:
sdk: flutter
path: ^1.8.0
path_provider_platform_interface: ^2.1.0
xdg_directories: ">=0.2.0 <2.0.0"
dev_dependencies:
flutter_test:
sdk: flutter
topics:
- files
- path-provider
- paths

View File

@@ -0,0 +1,62 @@
// 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:ffi';
import 'package:ffi/ffi.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_linux/src/get_application_id_real.dart';
class _FakeGioUtils implements GioUtils {
int? application;
Pointer<Utf8>? applicationId;
@override
bool libraryIsPresent = false;
@override
int gApplicationGetDefault() => application!;
@override
Pointer<Utf8> gApplicationGetApplicationId(int app) => applicationId!;
}
void main() {
late _FakeGioUtils fakeGio;
setUp(() {
fakeGio = _FakeGioUtils();
gioUtilsOverride = fakeGio;
});
tearDown(() {
gioUtilsOverride = null;
});
test('returns null if libgio is not available', () {
expect(getApplicationId(), null);
});
test('returns null if g_paplication_get_default returns 0', () {
fakeGio.libraryIsPresent = true;
fakeGio.application = 0;
expect(getApplicationId(), null);
});
test('returns null if g_application_get_application_id returns nullptr', () {
fakeGio.libraryIsPresent = true;
fakeGio.application = 1;
fakeGio.applicationId = nullptr;
expect(getApplicationId(), null);
});
test('returns value if g_application_get_application_id returns a value', () {
fakeGio.libraryIsPresent = true;
fakeGio.application = 1;
const String id = 'foo';
final Pointer<Utf8> idPtr = id.toNativeUtf8();
fakeGio.applicationId = idPtr;
expect(getApplicationId(), id);
calloc.free(idPtr);
});
}

View File

@@ -0,0 +1,71 @@
// 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_test/flutter_test.dart';
import 'package:path_provider_linux/path_provider_linux.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdg;
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
PathProviderLinux.registerWith();
test('registered instance', () {
expect(PathProviderPlatform.instance, isA<PathProviderLinux>());
});
test('getTemporaryPath defaults to TMPDIR', () async {
final PathProviderPlatform plugin = PathProviderLinux.private(
environment: <String, String>{'TMPDIR': '/run/user/0/tmp'},
);
expect(await plugin.getTemporaryPath(), '/run/user/0/tmp');
});
test('getTemporaryPath uses fallback if TMPDIR is empty', () async {
final PathProviderPlatform plugin = PathProviderLinux.private(
environment: <String, String>{'TMPDIR': ''},
);
expect(await plugin.getTemporaryPath(), '/tmp');
});
test('getTemporaryPath uses fallback if TMPDIR is unset', () async {
final PathProviderPlatform plugin = PathProviderLinux.private(
environment: <String, String>{},
);
expect(await plugin.getTemporaryPath(), '/tmp');
});
test('getApplicationSupportPath', () async {
final PathProviderPlatform plugin = PathProviderLinux.private(
executableName: 'path_provider_linux_test_binary',
applicationId: 'com.example.Test');
// Note this will fail if ${xdg.dataHome.path}/path_provider_linux_test_binary exists on the local filesystem.
expect(await plugin.getApplicationSupportPath(),
'${xdg.dataHome.path}/com.example.Test');
});
test('getApplicationSupportPath uses executable name if no application Id',
() async {
final PathProviderPlatform plugin = PathProviderLinux.private(
executableName: 'path_provider_linux_test_binary');
expect(await plugin.getApplicationSupportPath(),
'${xdg.dataHome.path}/path_provider_linux_test_binary');
});
test('getApplicationDocumentsPath', () async {
final PathProviderPlatform plugin = PathProviderPlatform.instance;
expect(await plugin.getApplicationDocumentsPath(), startsWith('/'));
});
test('getApplicationCachePath', () async {
final PathProviderPlatform plugin = PathProviderLinux.private(
executableName: 'path_provider_linux_test_binary');
expect(await plugin.getApplicationCachePath(),
'${xdg.cacheHome.path}/path_provider_linux_test_binary');
});
test('getDownloadsPath', () async {
final PathProviderPlatform plugin = PathProviderPlatform.instance;
expect(await plugin.getDownloadsPath(), startsWith('/'));
});
}