fckeuspy-go/vendor/fyne.io/fyne/v2/dialog/file_xdg_flatpak.go

190 lines
4.8 KiB
Go

//go:build flatpak && !windows && !android && !ios && !wasm && !js
package dialog
import (
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
"fyne.io/fyne/v2/internal/build"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/storage"
"github.com/rymdport/portal"
"github.com/rymdport/portal/filechooser"
)
func openFile(parentWindowHandle string, options *filechooser.OpenFileOptions) (fyne.URIReadCloser, error) {
title := lang.L("Open") + " " + lang.L("File")
uri, err := open(parentWindowHandle, title, options)
if err != nil || uri == nil {
return nil, err
}
return storage.Reader(uri)
}
func openFolder(parentWindowHandle string, options *filechooser.OpenFileOptions) (fyne.ListableURI, error) {
title := lang.L("Open") + " " + lang.L("Folder")
uri, err := open(parentWindowHandle, title, options)
if err != nil || uri == nil {
return nil, err
}
return storage.ListerForURI(uri)
}
func open(parentWindowHandle, title string, options *filechooser.OpenFileOptions) (fyne.URI, error) {
uris, err := filechooser.OpenFile(parentWindowHandle, title, options)
if err != nil {
return nil, err
}
if len(uris) == 0 {
return nil, nil
}
return storage.ParseURI(uris[0])
}
func saveFile(parentWindowHandle string, options *filechooser.SaveFileOptions) (fyne.URIWriteCloser, error) {
title := lang.L("Save") + " " + lang.L("File")
uris, err := filechooser.SaveFile(parentWindowHandle, title, options)
if err != nil {
return nil, err
}
if len(uris) == 0 {
return nil, nil
}
uri, err := storage.ParseURI(uris[0])
if err != nil {
return nil, err
}
return storage.Writer(uri)
}
func fileOpenOSOverride(d *FileDialog) bool {
options := &filechooser.OpenFileOptions{
Directory: d.isDirectory(),
AcceptLabel: d.confirmText,
}
if d.startingLocation != nil {
options.CurrentFolder = d.startingLocation.Path()
}
options.Filters, options.CurrentFilter = convertFilterForPortal(d.filter)
windowHandle := windowHandleForPortal(d.parent)
go func() {
if options.Directory {
folder, err := openFolder(windowHandle, options)
fyne.Do(func() {
folderCallback := d.callback.(func(fyne.ListableURI, error))
folderCallback(folder, err)
})
} else {
file, err := openFile(windowHandle, options)
fyne.Do(func() {
fileCallback := d.callback.(func(fyne.URIReadCloser, error))
fileCallback(file, err)
})
}
}()
return true
}
func fileSaveOSOverride(d *FileDialog) bool {
options := &filechooser.SaveFileOptions{
AcceptLabel: d.confirmText,
CurrentName: d.initialFileName,
}
if d.startingLocation != nil {
options.CurrentFolder = d.startingLocation.Path()
}
options.Filters, options.CurrentFilter = convertFilterForPortal(d.filter)
callback := d.callback.(func(fyne.URIWriteCloser, error))
windowHandle := windowHandleForPortal(d.parent)
go func() {
file, err := saveFile(windowHandle, options)
fyne.Do(func() {
callback(file, err)
})
}()
return true
}
func windowHandleForPortal(window fyne.Window) string {
windowHandle := ""
if !build.IsWayland {
window.(driver.NativeWindow).RunNative(func(context any) {
handle := context.(driver.X11WindowContext).WindowHandle
windowHandle = portal.FormatX11WindowHandle(handle)
})
}
// TODO: We need to get the Wayland handle from the xdg_foreign protocol and convert to string on the form "wayland:{id}".
return windowHandle
}
func convertFilterForPortal(fyneFilter storage.FileFilter) (list []*filechooser.Filter, current *filechooser.Filter) {
if fyneFilter == nil || fyneFilter == folderFilter {
return nil, nil
}
if filter, ok := fyneFilter.(*storage.ExtensionFileFilter); ok {
rules := make([]filechooser.Rule, 0, 2*len(filter.Extensions))
for _, ext := range filter.Extensions {
lowercase := filechooser.Rule{
Type: filechooser.GlobPattern,
Pattern: "*" + strings.ToLower(ext),
}
uppercase := filechooser.Rule{
Type: filechooser.GlobPattern,
Pattern: "*" + strings.ToUpper(ext),
}
rules = append(rules, lowercase, uppercase)
}
name := formatFilterName(filter.Extensions, 3)
converted := &filechooser.Filter{Name: name, Rules: rules}
return []*filechooser.Filter{converted}, converted
}
if filter, ok := fyneFilter.(*storage.MimeTypeFileFilter); ok {
rules := make([]filechooser.Rule, len(filter.MimeTypes))
for i, mime := range filter.MimeTypes {
rules[i] = filechooser.Rule{
Type: filechooser.MIMEType,
Pattern: mime,
}
}
name := formatFilterName(filter.MimeTypes, 3)
converted := &filechooser.Filter{Name: name, Rules: rules}
return []*filechooser.Filter{converted}, converted
}
return nil, nil
}
func formatFilterName(patterns []string, count int) string {
if len(patterns) < count {
count = len(patterns)
}
name := strings.Join(patterns[:count], ", ")
if len(patterns) > count {
name += "…"
}
return name
}