Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct paths for favorites in file dialog #1351

Merged
merged 18 commits into from Oct 13, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
90 changes: 32 additions & 58 deletions dialog/file.go
Expand Up @@ -158,77 +158,35 @@ func (f *fileDialog) makeUI() fyne.CanvasObject {
scrollBread, f.fileScroll)
header := widget.NewLabelWithStyle(label+" File", fyne.TextAlignLeading, fyne.TextStyle{Bold: true})

favorites, err := f.loadFavorites()
if err != nil {
// only generate the Favorites group if we were able to load
// them successfully
favorites = []fyne.CanvasObject{}
fyne.LogError("Unable to load favorites", err)
}
favorites := f.loadFavorites()

favoritesGroup := widget.NewGroup("Favorites", favorites...)
return fyne.NewContainerWithLayout(layout.NewBorderLayout(header, footer, favoritesGroup, nil),
favoritesGroup, header, footer, body)

}

func (f *fileDialog) loadFavorites() ([]fyne.CanvasObject, error) {
var home fyne.ListableURI
var documents fyne.ListableURI
var downloads fyne.ListableURI
var osHome string
var err, err1 error

osHome, err = os.UserHomeDir()

if err == nil {
home, err1 = storage.ListerForURI(storage.NewFileURI(osHome))
if err1 == nil {
var documentsURI fyne.URI
documentsURI, err1 = storage.Child(home, "Documents")
if err1 == nil {
documents, err1 = storage.ListerForURI(documentsURI)
if err1 != nil {
err = err1
}
} else {
err = err1
}
var downloadsURI fyne.URI
downloadsURI, err1 = storage.Child(home, "Downloads")
if err1 == nil {
downloads, err1 = storage.ListerForURI(downloadsURI)
if err1 != nil {
err = err1
}
} else {
err = err1
}
} else {
err = err1
}
func (f *fileDialog) loadFavorites() []fyne.CanvasObject {
favoriteLocations, err := getFavoriteLocations()
if err != nil {
fyne.LogError("Getting favorite locations", err)
}
favoriteIcons := getFavoriteIcons()
favoriteOrder := getFavoriteOrder()

var places []fyne.CanvasObject

if home != nil {
places = append(places, makeFavoriteButton("Home", theme.HomeIcon(), func() {
f.setLocation(home)
}))
}
if documents != nil {
places = append(places, makeFavoriteButton("Documents", theme.DocumentIcon(), func() {
f.setLocation(documents)
}))
}
if downloads != nil {
places = append(places, makeFavoriteButton("Downloads", theme.DownloadIcon(), func() {
f.setLocation(downloads)
for _, locName := range favoriteOrder {
loc, ok := favoriteLocations[locName]
if !ok {
continue
}
icon := favoriteIcons[locName]
places = append(places, makeFavoriteButton(locName, icon, func() {
f.setLocation(loc)
}))
}

places = append(places, f.loadPlaces()...)
return places, err
return places
}

func (f *fileDialog) refreshDir(dir fyne.ListableURI) {
Expand Down Expand Up @@ -568,3 +526,19 @@ func makeFavoriteButton(title string, icon fyne.Resource, f func()) *widget.Butt
b.Alignment = widget.ButtonAlignLeading
return b
}

func getFavoriteIcons() map[string]fyne.Resource {
return map[string]fyne.Resource{
"Home": theme.HomeIcon(),
"Documents": theme.DocumentIcon(),
"Downloads": theme.DownloadIcon(),
}
}

func getFavoriteOrder() []string {
return []string{
"Home",
"Documents",
"Downloads",
}
}
41 changes: 41 additions & 0 deletions dialog/file_darwin.go
@@ -0,0 +1,41 @@
package dialog

import (
"os"

"fyne.io/fyne"
"fyne.io/fyne/storage"
)

func getFavoriteLocations() (map[string]fyne.ListableURI, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
homeURI := storage.NewFileURI(homeDir)

favoriteNames := getFavoriteOrder()
favoriteLocations := make(map[string]fyne.ListableURI)
for _, favName := range favoriteNames {
var uri fyne.URI
var err1 error
if favName == "Home" {
uri = homeURI
} else {
uri, err1 = storage.Child(homeURI, favName)
}
if err1 != nil {
err = err1
continue
}

listURI, err1 := storage.ListerForURI(uri)
if err1 != nil {
err = err1
continue
}
favoriteLocations[favName] = listURI
}

return favoriteLocations, err
}
36 changes: 36 additions & 0 deletions dialog/file_mobile.go
Expand Up @@ -3,8 +3,11 @@
package dialog

import (
"os"

"fyne.io/fyne"
"fyne.io/fyne/internal/driver/gomobile"
"fyne.io/fyne/storage"
)

func (f *fileDialog) loadPlaces() []fyne.CanvasObject {
Expand All @@ -30,3 +33,36 @@ func fileSaveOSOverride(f *FileDialog) bool {

return true
}

func getFavoriteLocations() (map[string]fyne.ListableURI, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
homeURI := storage.NewFileURI(homeDir)

favoriteNames := getFavoriteOrder()
favoriteLocations := make(map[string]fyne.ListableURI)
for _, favName := range favoriteNames {
var uri fyne.URI
var err1 error
if favName == "Home" {
uri = homeURI
} else {
uri, err1 = storage.Child(homeURI, favName)
}
if err1 != nil {
err = err1
continue
}

listURI, err1 := storage.ListerForURI(uri)
if err1 != nil {
err = err1
continue
}
favoriteLocations[favName] = listURI
}

return favoriteLocations, err
}
36 changes: 36 additions & 0 deletions dialog/file_test.go
Expand Up @@ -365,3 +365,39 @@ func TestFileFilters(t *testing.T) {
}
assert.Equal(t, 4, count)
}

func TestFileFavorites(t *testing.T) {
win := test.NewWindow(widget.NewLabel("Content"))

dlg := NewFileOpen(func(reader fyne.URIReadCloser, err error) {
assert.Nil(t, err)
assert.Nil(t, reader)
}, win)

dlg.Show()

// error can be ignored. It just tells you why the fallback
// paths are used if they are.
favoriteLocations, _ := getFavoriteLocations()
favorites := dlg.dialog.loadFavorites()
places := dlg.dialog.loadPlaces()
assert.Len(t, favorites, len(favoriteLocations)+len(places))

for _, f := range favorites {
btn := f.(*widget.Button)
test.Tap(btn)
loc, ok := favoriteLocations[btn.Text]
if ok {
// button is Home, Documents, Downloads
assert.Equal(t, loc.String(), dlg.dialog.dir.String())
} else {
// button is (on windows) C:\, D:\, etc.
assert.NotEqual(t, "Home", btn.Text)
}
ok, err := storage.Exists(dlg.dialog.dir)
assert.Nil(t, err)
assert.True(t, ok)
}

test.Tap(dlg.dialog.dismiss)
}
File renamed without changes.
33 changes: 33 additions & 0 deletions dialog/file_windows.go
Expand Up @@ -83,3 +83,36 @@ func fileOpenOSOverride(*FileDialog) bool {
func fileSaveOSOverride(*FileDialog) bool {
return false
}

func getFavoriteLocations() (map[string]fyne.ListableURI, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
homeURI := storage.NewFileURI(homeDir)

favoriteNames := getFavoriteOrder()
favoriteLocations := make(map[string]fyne.ListableURI)
for _, favName := range favoriteNames {
var uri fyne.URI
var err1 error
if favName == "Home" {
uri = homeURI
} else {
uri, err1 = storage.Child(homeURI, favName)
}
if err1 != nil {
err = err1
continue
}

listURI, err1 := storage.ListerForURI(uri)
if err1 != nil {
err = err1
continue
}
favoriteLocations[favName] = listURI
}

return favoriteLocations, err
}
98 changes: 98 additions & 0 deletions dialog/file_xdg.go
@@ -0,0 +1,98 @@
// +build linux openbsd freebsd netbsd
// +build !android

package dialog

import (
"bytes"
"fmt"
"os"
"os/exec"

"fyne.io/fyne"
"fyne.io/fyne/storage"
)

func getFavoriteLocation(homeURI fyne.URI, name string) (fyne.URI, error) {
cmdName := "xdg-user-dir"
fallback, err := storage.Child(homeURI, name)
var fallbackErr error
if err != nil {
fallbackErr = fmt.Errorf("couldn't get fallback: %s", err)
}

if _, err := exec.LookPath(cmdName); err != nil {
if fallbackErr != nil {
return nil, fallbackErr
}
return fallback, fmt.Errorf("%s not found in PATH. using fallback paths", cmdName)
}

cmd := exec.Command(cmdName, name)
stdout := bytes.NewBufferString("")

cmd.Stdout = stdout
err = cmd.Run()
if err != nil {
if fallbackErr != nil {
return nil, fallbackErr
}
return fallback, err
}

loc := stdout.String()
// Remove \n at the end
loc = loc[:len(loc)-1]
locURI := storage.NewFileURI(loc)

if locURI.String() == homeURI.String() {
if fallbackErr != nil {
return nil, fallbackErr
}
return fallback, fmt.Errorf("this computer does not have a %s folder", name)
}

return locURI, nil
}

func getFavoriteLocations() (map[string]fyne.ListableURI, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
homeURI := storage.NewFileURI(homeDir)

favoriteNames := getFavoriteOrder()
arguments := map[string]string{
"Documents": "DOCUMENTS",
"Downloads": "DOWNLOADS",
}

favoriteLocations := make(map[string]fyne.ListableURI)
for _, favName := range favoriteNames {
var uri fyne.URI
var err1 error
if favName == "Home" {
uri = homeURI
} else {
favURI, err2 := getFavoriteLocation(homeURI, arguments[favName])
if err2 != nil {
err1 = err2
}
uri = favURI
}
if err1 != nil {
err = err1
continue
}

listURI, err1 := storage.ListerForURI(uri)
if err1 != nil {
err = err1
continue
}
favoriteLocations[favName] = listURI
}

return favoriteLocations, err
}