diff options
Diffstat (limited to 'cmd/rescribe/gui.go')
-rw-r--r-- | cmd/rescribe/gui.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/cmd/rescribe/gui.go b/cmd/rescribe/gui.go new file mode 100644 index 0000000..4944e42 --- /dev/null +++ b/cmd/rescribe/gui.go @@ -0,0 +1,140 @@ +// Copyright 2021 Nick White. +// Use of this source code is governed by the GPLv3 +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "fmt" + "io" + "log" + "os" + "path/filepath" + "strings" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/app" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" +) + +// copyStdoutToChan creates a pipe to copy anything written +// to stdout instead to a rune channel +func copyStdoutToChan() (chan rune, error) { + c := make(chan rune) + + origStdout := os.Stdout + r, w, err := os.Pipe() + if err != nil { + return c, fmt.Errorf("Error creating pipe for stdout redirection: %v", err) + } + os.Stdout = w + + bufReader := bufio.NewReader(r) + + go func() { + defer func() { + close(c) + w.Close() + os.Stdout = origStdout + }() + for { + r, _, err := bufReader.ReadRune() + if err != nil && err != io.EOF { + return + } + c <- r + if err == io.EOF { + return + } + } + }() + + return c, nil +} + +// startGui starts the gui process +func startGui(log log.Logger, cmd string, training string, systess bool, tessdir string) error { + myApp := app.New() + myWindow := myApp.NewWindow("Rescribe OCR") + + var gobtn *widget.Button + + dir := widget.NewEntry() + dir.SetPlaceHolder("Folder to process") + dir.OnChanged = func(s string) { + // TODO: also check if string is a directory, and only enable if so + if dir.Text != "" { + gobtn.Enable() + } else { + gobtn.Disable() + } + } + + openbtn := widget.NewButtonWithIcon("Choose folder", theme.FolderOpenIcon(), func() { + dialog.ShowFolderOpen(func(uri fyne.ListableURI, err error) { + if err == nil && uri != nil { + dir.SetText(uri.Path()) + } + }, myWindow)}) + + progressBar := widget.NewProgressBar() + + logarea := widget.NewMultiLineEntry() + logarea.Disable() + + + // TODO: have the button be pressed if enter is pressed + gobtn = widget.NewButtonWithIcon("Process OCR", theme.UploadIcon(), func() { + if dir.Text == "" { + return + } + + gobtn.Disable() + gobtn.SetText("Processing...") + + progressBar.SetValue(0.5) + + stdout, err := copyStdoutToChan() + if err != nil { + fmt.Fprintf(os.Stderr, "Error copying stdout to chan: %v\n", err) + return + } + + // update log area with output from outC in a concurrent goroutine + go func() { + for r := range stdout { + logarea.SetText(logarea.Text + string(r)) + logarea.CursorRow = strings.Count(logarea.Text, "\n") + // TODO: set text on progress bar, or a label below it, to latest line printed, rather than just using a whole multiline entry like this + // TODO: parse the stdout and set progressBar based on that + } + }() + + err = startProcess(log, cmd, dir.Text, filepath.Base(dir.Text), training, systess, dir.Text, tessdir) + if err != nil { + fmt.Fprintf(os.Stderr, "Error executing process: %v\n", err) + return + } + + progressBar.SetValue(1.0) + gobtn.SetText("Process OCR") + gobtn.Enable() + }) + gobtn.Disable() + + diropener := container.New(layout.NewGridLayout(2), dir, openbtn) + + content := container.NewVBox(diropener, gobtn, progressBar, logarea) + + myWindow.SetContent(content) + + myWindow.Show() + myApp.Run() + + return nil +} |