summaryrefslogtreecommitdiff
path: root/cmd/rescribe/gui.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/rescribe/gui.go')
-rw-r--r--cmd/rescribe/gui.go140
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
+}