diff --git a/dialog/file.go b/dialog/file.go index 3b2ba597b6..04c276a28a 100644 --- a/dialog/file.go +++ b/dialog/file.go @@ -158,17 +158,27 @@ func (f *fileDialog) makeUI() fyne.CanvasObject { } func (f *fileDialog) loadFavorites() []fyne.CanvasObject { - home, _ := os.UserHomeDir() - places := []fyne.CanvasObject{ - makeFavoriteButton("Home", theme.HomeIcon(), func() { - f.setDirectory(home) - }), - makeFavoriteButton("Documents", theme.DocumentIcon(), func() { - f.setDirectory(filepath.Join(home, "Documents")) - }), - makeFavoriteButton("Downloads", theme.DownloadIcon(), func() { - f.setDirectory(filepath.Join(home, "Downloads")) - }), + favoriteLocations, err := getFavoriteLocations() + if err != nil { + fyne.LogError("Getting Favorite locations", err) + } + + var places []fyne.CanvasObject + + if loc, ok := favoriteLocations["Home"]; ok { + places = append(places, makeFavoriteButton("Home", theme.HomeIcon(), func() { + f.setDirectory(loc) + })) + } + if loc, ok := favoriteLocations["Documents"]; ok { + places = append(places, makeFavoriteButton("Documents", theme.DocumentIcon(), func() { + f.setDirectory(loc) + })) + } + if loc, ok := favoriteLocations["Downloads"]; ok { + places = append(places, makeFavoriteButton("Downloads", theme.DownloadIcon(), func() { + f.setDirectory(loc) + })) } places = append(places, f.loadPlaces()...) diff --git a/dialog/file_darwin.go b/dialog/file_darwin.go new file mode 100644 index 0000000000..63876f83dc --- /dev/null +++ b/dialog/file_darwin.go @@ -0,0 +1,19 @@ +package dialog + +import ( + "os" + "path/filepath" +) + +func getFavoriteLocations() (map[string]string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, err + } + + return map[string]string{ + "Home": homeDir, + "Documents": filepath.Join(homeDir, "Documents"), + "Downloads": filepath.Join(homeDir, "Downloads"), + }, nil +} diff --git a/dialog/file_mobile.go b/dialog/file_mobile.go index 966cab1aa5..89356d65e2 100644 --- a/dialog/file_mobile.go +++ b/dialog/file_mobile.go @@ -3,6 +3,9 @@ package dialog import ( + "os" + "path/filepath" + "fyne.io/fyne" "fyne.io/fyne/internal/driver/gomobile" ) @@ -30,3 +33,16 @@ func fileSaveOSOverride(f *FileDialog) bool { return true } + +func getFavoriteLocations() (map[string]string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, err + } + + return map[string]string{ + "Home": homeDir, + "Documents": filepath.Join(homeDir, "Documents"), + "Downloads": filepath.Join(homeDir, "Downloads"), + }, nil +} diff --git a/dialog/file_test.go b/dialog/file_test.go index bbfbfff6fd..6608cb795f 100644 --- a/dialog/file_test.go +++ b/dialog/file_test.go @@ -1,6 +1,7 @@ package dialog import ( + "fmt" "log" "os" "path/filepath" @@ -282,3 +283,29 @@ 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() + + favorites := dlg.dialog.loadFavorites() + places := dlg.dialog.loadPlaces() + assert.Equal(t, 3+len(places), len(favorites)) + + curDir := "" + for _, f := range favorites { + btn := f.(*widget.Button) + t.Log(fmt.Sprint("Changing from ", curDir, " to ", btn.Text)) + test.Tap(btn) + assert.NotEqual(t, curDir, dlg.dialog.dir) + curDir = dlg.dialog.dir + } + + test.Tap(dlg.dialog.dismiss) +} diff --git a/dialog/file_other.go b/dialog/file_unix.go similarity index 100% rename from dialog/file_other.go rename to dialog/file_unix.go diff --git a/dialog/file_windows.go b/dialog/file_windows.go index f257dfeb5f..54c624b3fe 100644 --- a/dialog/file_windows.go +++ b/dialog/file_windows.go @@ -81,3 +81,16 @@ func fileOpenOSOverride(*FileDialog) bool { func fileSaveOSOverride(*FileDialog) bool { return false } + +func getFavoriteLocations() (map[string]string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, err + } + + return map[string]string{ + "Home": homeDir, + "Documents": filepath.Join(homeDir, "Documents"), + "Downloads": filepath.Join(homeDir, "Downloads"), + }, nil +} diff --git a/dialog/file_xdg.go b/dialog/file_xdg.go new file mode 100644 index 0000000000..7d9141c77e --- /dev/null +++ b/dialog/file_xdg.go @@ -0,0 +1,67 @@ +// +build linux openbsd freebsd netbsd +// +build !android + +package dialog + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "path/filepath" +) + +func getFavoriteLocation(homeDir, name string) (string, error) { + cmdName := "xdg-user-dir" + fallback := filepath.Join(homeDir, name) + + if _, err := exec.LookPath(cmdName); err != nil { + 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 { + return fallback, err + } + + loc := stdout.String() + // Remove \n at the end + loc = loc[:len(loc)-1] + + if loc == homeDir { + return fallback, fmt.Errorf("this computer does not have a %s folder", name) + } + + return stdout.String(), nil +} + +func getFavoriteLocations() (map[string]string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, err + } + + rv := map[string]string{ + "Home": homeDir, + } + documentsDir, err1 := getFavoriteLocation(homeDir, "DOCUMENTS") + if err == nil { + rv["Documents"] = documentsDir + } else { + rv["Documents"] = filepath.Join(homeDir, "Documents") + err = err1 + } + downloadsDir, err1 := getFavoriteLocation(homeDir, "DOWNLOADS") + if err == nil { + rv["Downloads"] = downloadsDir + } else { + rv["Downloads"] = filepath.Join(homeDir, "Downloads") + err = err1 + } + + return rv, err +}