tally/workbook.go

162 lines
4.3 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"tildegit.org/sloum/tally/qline"
"tildegit.org/sloum/tally/termios"
"time"
)
const (
Left rune = 'h'
Right rune = 'l'
Up rune = 'k'
Down rune = 'j'
Quit rune = 'Q'
Edit rune = '\n'
EditAlt rune = ' '
EditText rune = '"'
Del rune = 'd'
Com rune = ':'
ZoomIn rune = '+'
ZoomOut rune = '-'
Yank rune = 'y'
Paste rune = 'p'
PasteRelative rune = 'P'
ToTop rune = 'g'
ToBottom rune = 'G'
RowStart rune = '^'
RowEnd rune = '$'
ModBold rune = 'b'
ModFaint rune = 'f'
ModItalic rune = 'i'
ModUnderline rune = 'u'
OpenLink rune = 'O'
)
type workbook struct {
name string
path string
sheets []sheet
sheet int
termRows int
termCols int
}
func (w *workbook) PollForTermSize() {
for {
var cols, rows = termios.GetWindowSize()
if rows != w.termRows || cols != w.termCols {
w.termRows = rows
w.termCols = cols
fmt.Print("\033[2J")
w.Draw()
}
time.Sleep(500 * time.Millisecond)
}
}
func (w workbook) Draw() {
fmt.Print("\033[0;0H")
fmt.Printf("FILE: \033[1m%-*.*s\033[0m\n", w.termCols-6, w.termCols-6, w.path)
fmt.Printf("EXPR: %-*.*s\n",
w.termCols-6, w.termCols-6,
w.sheets[w.sheet].CurrentValue(true))
w.sheets[w.sheet].Draw(w.termCols,w.termRows)
}
func (w *workbook) Run() {
defer termios.Restore()
termios.SetCharMode()
fmt.Print("\033[?25l\033[2J")
go w.PollForTermSize()
var input rune
var chErr error
for {
w.Draw()
input, chErr = Getch()
if chErr != nil {
continue
}
switch input {
case Left, Right, Up, Down, ToTop, RowStart, ToBottom, RowEnd, qline.LeftArrow, qline.RightArrow, qline.DownArrow, qline.UpArrow, qline.Home, qline.End, qline.PageUp, qline.PageDown:
w.sheets[w.sheet].moveSelection(input, w.termRows)
case Quit:
if modified {
fmt.Print("There are unsaved changes. Quit anyway? [y/n]")
answer, err := Getch()
if err != nil || answer == 'n' || answer == 'N' {
continue
}
fmt.Print("\n")
}
termios.Restore()
fmt.Print("\033[?25h")
os.Exit(0)
case Edit, EditAlt, EditText:
quote := false
if input == EditText {
quote = true
}
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].Edit(w.sheets[w.sheet].selection.row, w.sheets[w.sheet].selection.col, w.termCols, quote)
w.sheets[w.sheet].Recalculate()
case Del, qline.Delete, qline.BackSpace:
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1] = cell{}
w.sheets[w.sheet].Recalculate()
case Com:
line := GetEditLine(":", "", w.termCols)
runCommand(strings.Fields(line))
case ZoomIn:
w.sheets[w.sheet].ZoomIn()
fmt.Print("\033[2J")
case ZoomOut:
w.sheets[w.sheet].ZoomOut()
fmt.Print("\033[2J")
case Yank:
w.sheets[w.sheet].Yank()
case Paste:
w.sheets[w.sheet].Paste()
w.sheets[w.sheet].Recalculate()
case PasteRelative:
w.sheets[w.sheet].PasteRelative()
w.sheets[w.sheet].Recalculate()
case ModBold:
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Bold)
case ModFaint:
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Faint)
case ModItalic:
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Italic)
case ModUnderline:
w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Underline)
case OpenLink:
url := w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].mask
if IsURL(url) {
OpenInBrowser(url)
}
}
}
}
func makeWorkbook(path string) workbook {
// TODO parse path and get file name
// set name of strict to the filename
// or untitled.qsh if no filename; set
// path to the full path
cols, rows := termios.GetWindowSize()
sh := makeSheet("Sheet1")
wb = workbook{filepath.Base(path), path, make([]sheet,1), 0, rows, cols}
wb.sheets[0] = sh
return wb
}
func (w workbook) header() string {
return fmt.Sprintf("\033[1;7m %s \033[0m %s\n",w.name, w.sheets[w.sheet].name)
}