diff --git a/core/app/app.go b/core/app/app.go index 03cb405..b352037 100644 --- a/core/app/app.go +++ b/core/app/app.go @@ -92,7 +92,7 @@ type Controller struct { type View interface { BringToFront() ShowFilename(string) - SelectOpenFile(title string, dir string, patterns ...string) (string, bool, error) + SelectOpenFile(callback func(filename string, err error), title string, dir string, extensions ...string) SelectSaveFile(title string, dir string, filename string, patterns ...string) (string, bool, error) ShowInfoDialog(title string, format string, args ...any) ShowErrorDialog(string, ...any) @@ -455,14 +455,17 @@ func (c *Controller) New() { } func (c *Controller) Open() { - filename, ok, err := c.view.SelectOpenFile("Open Logfile", c.configuration.LogDirectory(), "*.log") - if !ok { - return - } + c.view.SelectOpenFile(c.open, "Open Logfile", c.configuration.LogDirectory(), "log") +} + +func (c *Controller) open(filename string, err error) { if err != nil { c.view.ShowErrorDialog("Cannot select a file: %v", err) return } + if filename == "" { + return + } store := store.NewFileStore(filename) qsos, station, contest, keyerSettings, err := store.ReadAll() diff --git a/fyneui/mainMenu.go b/fyneui/mainMenu.go index 0f33808..228ea6d 100644 --- a/fyneui/mainMenu.go +++ b/fyneui/mainMenu.go @@ -3,6 +3,7 @@ package fyneui import "fyne.io/fyne/v2" type MainMenuController interface { + Open() Quit() OpenWiki() @@ -13,8 +14,28 @@ type MainMenuController interface { type mainMenu struct { controller MainMenuController + fileMenu + editMenu + bandmapMenu + windowMenu + helpMenu +} + +type fileMenu struct { + fileOpen *fyne.MenuItem fileQuit *fyne.MenuItem +} +type editMenu struct { +} + +type bandmapMenu struct { +} + +type windowMenu struct { +} + +type helpMenu struct { helpWiki *fyne.MenuItem helpSponsors *fyne.MenuItem helpAbout *fyne.MenuItem @@ -40,14 +61,20 @@ func setupMainMenu(mainWindow fyne.Window, controller MainMenuController) *mainM // FILE func (m *mainMenu) setupFileMenu() []*fyne.MenuItem { + m.fileOpen = fyne.NewMenuItem("Open...", m.onFileOpen) m.fileQuit = fyne.NewMenuItem("Quit", m.onFileQuit) m.fileQuit.IsQuit = true return []*fyne.MenuItem{ + m.fileOpen, m.fileQuit, } } +func (m *mainMenu) onFileOpen() { + m.controller.Open() +} + func (m *mainMenu) onFileQuit() { m.controller.Quit() } diff --git a/fyneui/mainWindow.go b/fyneui/mainWindow.go index 824787f..6fa97f3 100644 --- a/fyneui/mainWindow.go +++ b/fyneui/mainWindow.go @@ -2,10 +2,12 @@ package fyneui import ( "fmt" + "log" "path/filepath" "fyne.io/fyne/v2" "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/widget" ) @@ -40,8 +42,48 @@ func (w *mainWindow) UseDefaultWindowGeometry() { w.window.CenterOnScreen() } -func (w *mainWindow) SelectOpenFile(title string, dir string, patterns ...string) (string, bool, error) { - return "", false, nil +func (w *mainWindow) SelectOpenFile(callback func(string, error), title string, dir string, extensions ...string) { + dirURI, err := storage.ListerForURI(storage.NewFileURI(dir)) + if err != nil { + callback("", err) + return + } + log.Printf("OPEN FILE in %s with extensions %v", dir, extensions) + + dialogCallback := func(reader fyne.URIReadCloser, err error) { + defer func() { + if reader != nil { + reader.Close() + } + }() + if err != nil { + callback("", err) + return + } + if reader == nil { + callback("", nil) + return + } + filename := reader.URI().Path() + log.Printf("file selected to open: %s", filename) + callback(filename, nil) + } + + fileDialog := dialog.NewFileOpen(dialogCallback, w.window) + fileDialog.SetView(dialog.ListView) + fileDialog.Resize(fyne.NewSize(1000, 600)) + // fileDialog.SetTitleText(title) // TODO: activate with fyne 2.6 + fileDialog.SetConfirmText("Open") + fileDialog.SetDismissText("Cancel") + fileDialog.SetLocation(dirURI) + if len(extensions) > 0 { + filterExtensions := make([]string, len(extensions), len(extensions)) + for i, extension := range extensions { + filterExtensions[i] = "." + extension + } + fileDialog.SetFilter(storage.NewExtensionFileFilter(filterExtensions)) + } + fileDialog.Show() } func (w *mainWindow) SelectSaveFile(title string, dir string, filename string, patterns ...string) (string, bool, error) { @@ -56,6 +98,7 @@ func (w *mainWindow) ShowInfoDialog(title string, format string, a ...any) { ) } -func (w *mainWindow) ShowErrorDialog(string, ...interface{}) { - +func (w *mainWindow) ShowErrorDialog(format string, a ...any) { + log.Printf(format, a...) + // TODO: show error dialog } diff --git a/go.mod b/go.mod index 727ef11..9b7a2b9 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ go 1.22.3 // replace github.com/gotk3/gotk3 => ../gotk3 +// replace fyne.io/fyne/v2 => ../fyne + require ( fyne.io/fyne/v2 v2.5.2 github.com/ftl/cabrillo v0.2.2 diff --git a/ui/mainWindow.go b/ui/mainWindow.go index 5643f83..847bba5 100644 --- a/ui/mainWindow.go +++ b/ui/mainWindow.go @@ -73,35 +73,37 @@ func (w *mainWindow) BringToFront() { w.window.Present() } -func (w *mainWindow) SelectOpenFile(title string, dir string, patterns ...string) (string, bool, error) { +func (w *mainWindow) SelectOpenFile(callback func(string, error), title string, dir string, extensions ...string) { dlg, err := gtk.FileChooserDialogNewWith1Button(title, &w.window.Window, gtk.FILE_CHOOSER_ACTION_OPEN, "Open", gtk.RESPONSE_ACCEPT) if err != nil { errors.Wrap(err, "cannot create a file selection dialog to open a file") } defer dlg.Destroy() - log.Printf("OPEN FILE in %s", dir) + log.Printf("OPEN FILE in %s with extensions %v", dir, extensions) dlg.SetTransientFor(nil) dlg.SetCurrentFolder(dir) - if len(patterns) > 0 { + if len(extensions) > 0 { filter, err := gtk.FileFilterNew() if err != nil { - return "", false, errors.Wrap(err, "cannot create a file selection dialog to open a file") + callback("", errors.Wrap(err, "cannot create a file selection dialog to open a file")) + return } - for _, pattern := range patterns { - filter.AddPattern(pattern) + for _, extension := range extensions { + filter.AddPattern("*." + extension) } dlg.SetFilter(filter) } result := dlg.Run() if result != gtk.RESPONSE_ACCEPT { - return "", false, nil + callback("", nil) + return } - return dlg.GetFilename(), true, nil + callback(dlg.GetFilename(), nil) } func (w *mainWindow) SelectSaveFile(title string, dir string, filename string, patterns ...string) (string, bool, error) {