2015-04-24 22:53:33 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2015-04-28 15:05:24 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2015-05-14 15:17:43 +00:00
|
|
|
"time"
|
2015-09-17 16:52:02 +00:00
|
|
|
|
|
|
|
"github.com/br0xen/termbox-util"
|
|
|
|
"github.com/nsf/termbox-go"
|
2015-04-24 22:53:33 +00:00
|
|
|
)
|
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
/*
|
|
|
|
ViewPort helps keep track of what's being displayed on the screen
|
|
|
|
*/
|
2015-04-24 22:53:33 +00:00
|
|
|
type ViewPort struct {
|
2015-09-17 16:52:02 +00:00
|
|
|
bytesPerRow int
|
|
|
|
numberOfRows int
|
|
|
|
firstRow int
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
/*
|
|
|
|
BrowserScreen holds all that's going on :D
|
|
|
|
*/
|
2015-04-24 22:53:33 +00:00
|
|
|
type BrowserScreen struct {
|
2015-09-17 16:52:02 +00:00
|
|
|
db *BoltDB
|
|
|
|
viewPort ViewPort
|
|
|
|
queuedCommand string
|
|
|
|
currentPath []string
|
|
|
|
currentType int
|
|
|
|
message string
|
|
|
|
mode BrowserMode
|
|
|
|
inputModal *termbox_util.InputModal
|
|
|
|
confirmModal *termbox_util.ConfirmModal
|
|
|
|
messageTimeout time.Duration
|
|
|
|
messageTime time.Time
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
/*
|
|
|
|
BrowserMode is just for designating the mode that we're in
|
|
|
|
*/
|
2015-05-02 03:17:31 +00:00
|
|
|
type BrowserMode int
|
|
|
|
|
|
|
|
const (
|
2015-09-17 16:52:02 +00:00
|
|
|
modeBrowse = 16 // 0000 0001 0000
|
|
|
|
modeChange = 32 // 0000 0010 0000
|
|
|
|
modeChangeKey = 33 // 0000 0010 0001
|
|
|
|
modeChangeVal = 34 // 0000 0010 0010
|
|
|
|
modeInsert = 64 // 0000 0100 0000
|
|
|
|
modeInsertBucket = 65 // 0000 0100 0001
|
|
|
|
modeInsertPair = 68 // 0000 0100 0100
|
|
|
|
modeInsertPairKey = 69 // 0000 0100 0101
|
|
|
|
modeInserPairVal = 70 // 0000 0100 0110
|
|
|
|
modeDelete = 256 // 0001 0000 0000
|
|
|
|
modeModToParent = 8 // 0000 0000 1000
|
2015-05-02 03:17:31 +00:00
|
|
|
)
|
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
/*
|
|
|
|
BoltType is just for tracking what type of db item we're looking at
|
|
|
|
*/
|
2015-04-30 16:22:37 +00:00
|
|
|
type BoltType int
|
|
|
|
|
|
|
|
const (
|
2015-09-17 16:52:02 +00:00
|
|
|
typeBucket = iota
|
|
|
|
typePair
|
2015-04-30 16:22:37 +00:00
|
|
|
)
|
|
|
|
|
2015-04-24 22:53:33 +00:00
|
|
|
func (screen *BrowserScreen) handleKeyEvent(event termbox.Event) int {
|
2015-05-03 23:57:37 +00:00
|
|
|
if screen.mode == 0 {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
2015-05-03 23:57:37 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.mode == modeBrowse {
|
2015-05-02 03:17:31 +00:00
|
|
|
return screen.handleBrowseKeyEvent(event)
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if screen.mode&modeChange == modeChange {
|
2015-05-02 03:17:31 +00:00
|
|
|
return screen.handleInputKeyEvent(event)
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if screen.mode&modeInsert == modeInsert {
|
2015-05-04 18:50:41 +00:00
|
|
|
return screen.handleInsertKeyEvent(event)
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if screen.mode == modeDelete {
|
2015-05-04 18:50:41 +00:00
|
|
|
return screen.handleDeleteKeyEvent(event)
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return BrowserScreenIndex
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
|
2015-04-30 16:22:37 +00:00
|
|
|
if event.Ch == '?' {
|
|
|
|
// About
|
2015-09-17 16:52:02 +00:00
|
|
|
return AboutScreenIndex
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-24 22:53:33 +00:00
|
|
|
} else if event.Ch == 'q' || event.Key == termbox.KeyEsc || event.Key == termbox.KeyCtrlC {
|
2015-04-30 16:22:37 +00:00
|
|
|
// Quit
|
2015-09-17 16:52:02 +00:00
|
|
|
return ExitScreenIndex
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'g' {
|
|
|
|
// Jump to Beginning
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = screen.db.getNextVisiblePath(nil)
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'G' {
|
|
|
|
// Jump to End
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = screen.db.getPrevVisiblePath(nil)
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-05-08 15:14:02 +00:00
|
|
|
} else if event.Key == termbox.KeyCtrlR {
|
|
|
|
screen.refreshDatabase()
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Key == termbox.KeyCtrlF {
|
|
|
|
// Jump forward half a screen
|
|
|
|
_, h := termbox.Size()
|
|
|
|
half := h / 2
|
2015-05-02 03:17:31 +00:00
|
|
|
screen.jumpCursorDown(half)
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Key == termbox.KeyCtrlB {
|
|
|
|
_, h := termbox.Size()
|
|
|
|
half := h / 2
|
2015-05-02 03:17:31 +00:00
|
|
|
screen.jumpCursorUp(half)
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'j' || event.Key == termbox.KeyArrowDown {
|
|
|
|
screen.moveCursorDown()
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'k' || event.Key == termbox.KeyArrowUp {
|
|
|
|
screen.moveCursorUp()
|
2015-05-02 03:17:31 +00:00
|
|
|
|
|
|
|
} else if event.Ch == 'p' {
|
2015-05-04 22:41:47 +00:00
|
|
|
// p creates a new pair at the current level
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.startInsertItem(typePair)
|
2015-05-04 22:41:47 +00:00
|
|
|
} else if event.Ch == 'P' {
|
|
|
|
// P creates a new pair at the parent level
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.startInsertItemAtParent(typePair)
|
2015-05-02 03:17:31 +00:00
|
|
|
|
|
|
|
} else if event.Ch == 'b' {
|
2015-05-04 22:41:47 +00:00
|
|
|
// b creates a new bucket at the current level
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.startInsertItem(typeBucket)
|
2015-05-04 22:41:47 +00:00
|
|
|
} else if event.Ch == 'B' {
|
|
|
|
// B creates a new bucket at the parent level
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.startInsertItemAtParent(typeBucket)
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-28 15:05:24 +00:00
|
|
|
} else if event.Ch == 'e' {
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, _ := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-03 23:57:37 +00:00
|
|
|
if b != nil {
|
2015-05-15 21:07:05 +00:00
|
|
|
screen.setMessage("Cannot edit a bucket, did you mean to (r)ename?")
|
2015-05-03 23:57:37 +00:00
|
|
|
} else if p != nil {
|
2015-05-04 18:50:41 +00:00
|
|
|
screen.startEditItem()
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
2015-05-15 21:07:05 +00:00
|
|
|
} else if event.Ch == 'r' {
|
|
|
|
screen.startRenameItem()
|
|
|
|
|
2015-04-28 15:05:24 +00:00
|
|
|
} else if event.Key == termbox.KeyEnter {
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, _ := screen.db.getGenericFromPath(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.db.toggleOpenBucket(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if p != nil {
|
2015-05-04 18:50:41 +00:00
|
|
|
screen.startEditItem()
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'l' || event.Key == termbox.KeyArrowRight {
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, _ := screen.db.getGenericFromPath(screen.currentPath)
|
2015-04-28 15:05:24 +00:00
|
|
|
// Select the current item
|
2015-04-30 16:22:37 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.db.toggleOpenBucket(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if p != nil {
|
2015-05-04 18:50:41 +00:00
|
|
|
screen.startEditItem()
|
2015-04-30 16:22:37 +00:00
|
|
|
} else {
|
2015-05-14 15:17:43 +00:00
|
|
|
screen.setMessage("Not sure what to do here...")
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'h' || event.Key == termbox.KeyArrowLeft {
|
|
|
|
// If we are _on_ a bucket that's open, close it
|
2015-09-17 16:52:02 +00:00
|
|
|
b, _, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
if e == nil && b != nil && b.expanded {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.db.closeBucket(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
if len(screen.currentPath) > 1 {
|
|
|
|
parentBucket, err := screen.db.getBucketFromPath(screen.currentPath[:len(screen.currentPath)-1])
|
2015-04-30 16:22:37 +00:00
|
|
|
if err == nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.db.closeBucket(parentBucket.GetPath())
|
2015-04-30 16:22:37 +00:00
|
|
|
// Figure out how far up we need to move the cursor
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = parentBucket.GetPath()
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.db.closeBucket(screen.currentPath)
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
} else if event.Ch == 'D' {
|
2015-05-04 18:50:41 +00:00
|
|
|
screen.startDeleteItem()
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return BrowserScreenIndex
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) handleInputKeyEvent(event termbox.Event) int {
|
|
|
|
if event.Key == termbox.KeyEsc {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.inputModal.Clear()
|
2015-05-03 23:57:37 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.inputModal.HandleKeyPress(event)
|
|
|
|
if screen.inputModal.IsDone() {
|
|
|
|
b, p, _ := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-18 13:49:47 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.mode == modeChangeKey {
|
|
|
|
newName := screen.inputModal.GetValue()
|
|
|
|
if renameBucket(screen.currentPath, newName) != nil {
|
2015-05-18 13:49:47 +00:00
|
|
|
screen.setMessage("Error renaming bucket.")
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
b.name = newName
|
|
|
|
screen.currentPath[len(screen.currentPath)-1] = b.name
|
2015-05-18 13:49:47 +00:00
|
|
|
screen.setMessage("Bucket Renamed!")
|
|
|
|
screen.refreshDatabase()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.mode == modeChangeKey {
|
|
|
|
newKey := screen.inputModal.GetValue()
|
|
|
|
if updatePairKey(screen.currentPath, newKey) != nil {
|
2015-05-15 21:07:05 +00:00
|
|
|
screen.setMessage("Error occurred updating Pair.")
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
p.key = newKey
|
|
|
|
screen.currentPath[len(screen.currentPath)-1] = p.key
|
2015-05-15 21:07:05 +00:00
|
|
|
screen.setMessage("Pair updated!")
|
|
|
|
screen.refreshDatabase()
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if screen.mode == modeChangeVal {
|
|
|
|
newVal := screen.inputModal.GetValue()
|
|
|
|
if updatePairValue(screen.currentPath, newVal) != nil {
|
2015-05-15 21:07:05 +00:00
|
|
|
screen.setMessage("Error occurred updating Pair.")
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
p.val = newVal
|
2015-05-15 21:07:05 +00:00
|
|
|
screen.setMessage("Pair updated!")
|
|
|
|
screen.refreshDatabase()
|
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.inputModal.Clear()
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return BrowserScreenIndex
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
2015-05-04 18:50:41 +00:00
|
|
|
func (screen *BrowserScreen) handleDeleteKeyEvent(event termbox.Event) int {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.confirmModal.HandleKeyPress(event)
|
|
|
|
if screen.confirmModal.IsDone() {
|
|
|
|
if screen.confirmModal.IsAccepted() {
|
|
|
|
holdNextPath := screen.db.getNextVisiblePath(screen.currentPath)
|
|
|
|
holdPrevPath := screen.db.getPrevVisiblePath(screen.currentPath)
|
|
|
|
if deleteKey(screen.currentPath) == nil {
|
2015-05-08 15:14:02 +00:00
|
|
|
screen.refreshDatabase()
|
2015-05-04 18:50:41 +00:00
|
|
|
// Move the current path endpoint appropriately
|
|
|
|
//found_new_path := false
|
2015-09-17 16:52:02 +00:00
|
|
|
if holdNextPath != nil {
|
|
|
|
if len(holdNextPath) > 2 {
|
|
|
|
if holdNextPath[len(holdNextPath)-2] == screen.currentPath[len(screen.currentPath)-2] {
|
|
|
|
screen.currentPath = holdNextPath
|
|
|
|
} else if holdPrevPath != nil {
|
|
|
|
screen.currentPath = holdPrevPath
|
2015-05-04 18:50:41 +00:00
|
|
|
} else {
|
|
|
|
// Otherwise, go to the parent
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = screen.currentPath[:(len(holdNextPath) - 2)]
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Root bucket deleted, set to next
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = holdNextPath
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if holdPrevPath != nil {
|
|
|
|
screen.currentPath = holdPrevPath
|
2015-05-04 18:50:41 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = screen.currentPath[:0]
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.confirmModal.Clear()
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return BrowserScreenIndex
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) handleInsertKeyEvent(event termbox.Event) int {
|
2015-05-02 03:17:31 +00:00
|
|
|
if event.Key == termbox.KeyEsc {
|
2015-05-08 15:14:02 +00:00
|
|
|
if len(screen.db.buckets) == 0 {
|
2015-09-17 16:52:02 +00:00
|
|
|
return ExitScreenIndex
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.inputModal.Clear()
|
2015-05-04 18:50:41 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.inputModal.HandleKeyPress(event)
|
|
|
|
if screen.inputModal.IsDone() {
|
|
|
|
newVal := screen.inputModal.GetValue()
|
|
|
|
screen.inputModal.Clear()
|
|
|
|
var insertPath []string
|
|
|
|
if len(screen.currentPath) > 0 {
|
|
|
|
_, p, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-08 15:14:02 +00:00
|
|
|
if e != nil {
|
2015-05-14 15:17:43 +00:00
|
|
|
screen.setMessage("Error Inserting new item. Invalid Path.")
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
insertPath = screen.currentPath
|
2015-05-08 15:14:02 +00:00
|
|
|
// where are we inserting?
|
|
|
|
if p != nil {
|
|
|
|
// If we're sitting on a pair, we have to go to it's parent
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = screen.mode | modeModToParent
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.mode&modeModToParent == modeModToParent {
|
|
|
|
if len(screen.currentPath) > 1 {
|
|
|
|
insertPath = screen.currentPath[:len(screen.currentPath)-1]
|
2015-05-08 15:14:02 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
insertPath = make([]string, 0)
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-05-04 22:41:47 +00:00
|
|
|
}
|
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
parentB, _, _ := screen.db.getGenericFromPath(insertPath)
|
|
|
|
if screen.mode&modeInsertBucket == modeInsertBucket {
|
|
|
|
err := insertBucket(insertPath, newVal)
|
2015-05-08 15:14:02 +00:00
|
|
|
if err != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.setMessage(fmt.Sprintf("%s => %s", err, insertPath))
|
2015-05-18 13:49:47 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
if parentB != nil {
|
|
|
|
parentB.expanded = true
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = append(insertPath, newVal)
|
2015-05-18 13:49:47 +00:00
|
|
|
|
2015-05-08 15:14:02 +00:00
|
|
|
screen.refreshDatabase()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.inputModal.Clear()
|
|
|
|
} else if screen.mode&modeInsertPair == modeInsertPair {
|
|
|
|
err := insertPair(insertPath, newVal, "")
|
2015-05-12 21:04:49 +00:00
|
|
|
if err != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.setMessage(fmt.Sprintf("%s => %s", err, insertPath))
|
2015-05-12 21:04:49 +00:00
|
|
|
screen.refreshDatabase()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeBrowse
|
|
|
|
screen.inputModal.Clear()
|
2015-05-12 21:04:49 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
if parentB != nil {
|
|
|
|
parentB.expanded = true
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = append(insertPath, newVal)
|
2015-05-12 21:04:49 +00:00
|
|
|
screen.refreshDatabase()
|
|
|
|
screen.startEditItem()
|
2015-05-04 22:41:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return BrowserScreenIndex
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|
|
|
|
|
2015-05-02 03:17:31 +00:00
|
|
|
func (screen *BrowserScreen) jumpCursorUp(distance int) bool {
|
|
|
|
// Jump up 'distance' lines
|
2015-09-17 16:52:02 +00:00
|
|
|
visPaths, err := screen.db.buildVisiblePathSlice()
|
2015-05-02 03:17:31 +00:00
|
|
|
if err == nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
findPath := strings.Join(screen.currentPath, "/")
|
|
|
|
startJump := false
|
|
|
|
for i := range visPaths {
|
|
|
|
if visPaths[len(visPaths)-1-i] == findPath {
|
|
|
|
startJump = true
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if startJump {
|
|
|
|
distance--
|
2015-05-02 03:17:31 +00:00
|
|
|
if distance == 0 {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = strings.Split(visPaths[len(visPaths)-1-i], "/")
|
2015-05-02 03:17:31 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if strings.Join(screen.currentPath, "/") == findPath {
|
|
|
|
screen.currentPath = screen.db.getNextVisiblePath(nil)
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
func (screen *BrowserScreen) jumpCursorDown(distance int) bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
visPaths, err := screen.db.buildVisiblePathSlice()
|
2015-05-02 03:17:31 +00:00
|
|
|
if err == nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
findPath := strings.Join(screen.currentPath, "/")
|
|
|
|
startJump := false
|
|
|
|
for i := range visPaths {
|
|
|
|
if visPaths[i] == findPath {
|
|
|
|
startJump = true
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if startJump {
|
|
|
|
distance--
|
2015-05-02 03:17:31 +00:00
|
|
|
if distance == 0 {
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.currentPath = strings.Split(visPaths[i], "/")
|
2015-05-02 03:17:31 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if strings.Join(screen.currentPath, "/") == findPath {
|
|
|
|
screen.currentPath = screen.db.getPrevVisiblePath(nil)
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
func (screen *BrowserScreen) moveCursorUp() bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
newPath := screen.db.getPrevVisiblePath(screen.currentPath)
|
|
|
|
if newPath != nil {
|
|
|
|
screen.currentPath = newPath
|
2015-04-30 16:22:37 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
func (screen *BrowserScreen) moveCursorDown() bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
newPath := screen.db.getNextVisiblePath(screen.currentPath)
|
|
|
|
if newPath != nil {
|
|
|
|
screen.currentPath = newPath
|
2015-04-30 16:22:37 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2015-04-28 15:05:24 +00:00
|
|
|
func (screen *BrowserScreen) performLayout() {}
|
2015-04-24 22:53:33 +00:00
|
|
|
|
2015-04-28 15:05:24 +00:00
|
|
|
func (screen *BrowserScreen) drawScreen(style Style) {
|
2015-09-17 16:52:02 +00:00
|
|
|
if len(screen.db.buckets) == 0 && screen.mode&modeInsertBucket != modeInsertBucket {
|
2015-05-08 15:14:02 +00:00
|
|
|
// Force a bucket insert
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.startInsertItemAtParent(typeBucket)
|
2015-05-08 15:14:02 +00:00
|
|
|
}
|
2015-05-18 13:49:47 +00:00
|
|
|
if screen.message == "" {
|
|
|
|
screen.setMessageWithTimeout("Press '?' for help", -1)
|
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
screen.drawLeftPane(style)
|
|
|
|
screen.drawRightPane(style)
|
|
|
|
screen.drawHeader(style)
|
|
|
|
screen.drawFooter(style)
|
2015-05-05 01:17:41 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.inputModal != nil {
|
|
|
|
screen.inputModal.Draw()
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.mode == modeDelete {
|
|
|
|
screen.confirmModal.Draw()
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
func (screen *BrowserScreen) drawHeader(style Style) {
|
2015-04-28 15:05:24 +00:00
|
|
|
width, _ := termbox.Size()
|
2015-04-30 16:22:37 +00:00
|
|
|
spaces := strings.Repeat(" ", (width / 2))
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("%s%s%s", spaces, ProgramName, spaces), 0, 0, style.titleFg, style.titleBg)
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
func (screen *BrowserScreen) drawFooter(style Style) {
|
2015-09-17 16:52:02 +00:00
|
|
|
if screen.messageTimeout > 0 && time.Since(screen.messageTime) > screen.messageTimeout {
|
2015-05-14 15:17:43 +00:00
|
|
|
screen.clearMessage()
|
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
_, height := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(screen.message, 0, height-1, style.defaultFg, style.defaultBg)
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
func (screen *BrowserScreen) drawLeftPane(style Style) {
|
|
|
|
w, h := termbox.Size()
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-04-30 16:22:37 +00:00
|
|
|
w = w / 2
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.viewPort.numberOfRows = h - 2
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.FillWithChar('=', 0, 1, w, 1, style.defaultFg, style.defaultBg)
|
2015-05-02 03:17:31 +00:00
|
|
|
y := 2
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.viewPort.firstRow = y
|
|
|
|
if len(screen.currentPath) == 0 {
|
|
|
|
screen.currentPath = screen.db.getNextVisiblePath(nil)
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// So we know how much of the tree _wants_ to be visible
|
2015-09-17 16:52:02 +00:00
|
|
|
// we only have screen.viewPort.numberOfRows of space though
|
|
|
|
curPathSpot := 0
|
|
|
|
visSlice, err := screen.db.buildVisiblePathSlice()
|
2015-04-30 16:22:37 +00:00
|
|
|
if err == nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
for i := range visSlice {
|
|
|
|
if strings.Join(screen.currentPath, "/") == visSlice[i] {
|
|
|
|
curPathSpot = i
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
treeOffset := 0
|
|
|
|
maxCursor := screen.viewPort.numberOfRows * 2 / 3
|
|
|
|
if curPathSpot > maxCursor {
|
|
|
|
treeOffset = curPathSpot - maxCursor
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
|
|
|
|
for i := range screen.db.buckets {
|
|
|
|
// The drawBucket function returns how many lines it took up
|
2015-09-17 16:52:02 +00:00
|
|
|
bktH := screen.drawBucket(&screen.db.buckets[i], style, (y - treeOffset))
|
|
|
|
y += bktH
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
func (screen *BrowserScreen) drawRightPane(style Style) {
|
2015-05-02 03:17:31 +00:00
|
|
|
w, h := termbox.Size()
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-05-02 03:17:31 +00:00
|
|
|
// Screen is wide enough, split it
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.FillWithChar('=', 0, 1, w, 1, style.defaultFg, style.defaultBg)
|
|
|
|
termbox_util.FillWithChar('|', (w / 2), screen.viewPort.firstRow-1, (w / 2), h, style.defaultFg, style.defaultBg)
|
2015-05-02 03:17:31 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, err := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-02 03:17:31 +00:00
|
|
|
if err == nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
startX := (w / 2) + 2
|
|
|
|
startY := 2
|
2015-05-02 03:17:31 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(b.GetPath(), "/")), startX, startY, style.defaultFg, style.defaultBg)
|
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Buckets: %d", len(b.buckets)), startX, startY+1, style.defaultFg, style.defaultBg)
|
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Pairs: %d", len(b.pairs)), startX, startY+2, style.defaultFg, style.defaultBg)
|
2015-05-02 03:17:31 +00:00
|
|
|
} else if p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(p.GetPath(), "/")), startX, startY, style.defaultFg, style.defaultBg)
|
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Key: %s", p.key), startX, startY+1, style.defaultFg, style.defaultBg)
|
|
|
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Value: %s", p.val), startX, startY+2, style.defaultFg, style.defaultBg)
|
2015-04-30 16:22:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
/* drawBucket
|
|
|
|
* @bkt *BoltBucket - The bucket to draw
|
|
|
|
* @style Style - The style to use
|
|
|
|
* @w int - The Width of the lines
|
|
|
|
* @y int - The Y position to start drawing
|
|
|
|
* return - The number of lines used
|
|
|
|
*/
|
|
|
|
func (screen *BrowserScreen) drawBucket(bkt *BoltBucket, style Style, y int) int {
|
|
|
|
w, _ := termbox.Size()
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-04-30 16:22:37 +00:00
|
|
|
w = w / 2
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
usedLines := 0
|
|
|
|
bucketFg := style.defaultFg
|
|
|
|
bucketBg := style.defaultBg
|
|
|
|
if comparePaths(screen.currentPath, bkt.GetPath()) {
|
|
|
|
bucketFg = style.cursorFg
|
|
|
|
bucketBg = style.cursorBg
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
bktString := strings.Repeat(" ", len(bkt.GetPath())*2) //screen.db.getDepthFromPath(bkt.GetPath())*2)
|
2015-04-28 15:05:24 +00:00
|
|
|
if bkt.expanded {
|
2015-09-17 16:52:02 +00:00
|
|
|
bktString = bktString + "- " + bkt.name + " "
|
|
|
|
bktString = fmt.Sprintf("%s%s", bktString, strings.Repeat(" ", (w-len(bktString))))
|
2015-04-30 16:22:37 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(bktString, 0, (y + usedLines), bucketFg, bucketBg)
|
|
|
|
usedLines++
|
2015-04-24 22:53:33 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
for i := range bkt.buckets {
|
2015-09-17 16:52:02 +00:00
|
|
|
usedLines += screen.drawBucket(&bkt.buckets[i], style, y+usedLines)
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-04-30 16:22:37 +00:00
|
|
|
for i := range bkt.pairs {
|
2015-09-17 16:52:02 +00:00
|
|
|
usedLines += screen.drawPair(&bkt.pairs[i], style, y+usedLines)
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
bktString = bktString + "+ " + bkt.name
|
|
|
|
bktString = fmt.Sprintf("%s%s", bktString, strings.Repeat(" ", (w-len(bktString))))
|
|
|
|
termbox_util.DrawStringAtPoint(bktString, 0, (y + usedLines), bucketFg, bucketBg)
|
|
|
|
usedLines++
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
return usedLines
|
2015-04-28 15:05:24 +00:00
|
|
|
}
|
2015-04-24 22:53:33 +00:00
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
func (screen *BrowserScreen) drawPair(bp *BoltPair, style Style, y int) int {
|
|
|
|
w, _ := termbox.Size()
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-04-30 16:22:37 +00:00
|
|
|
w = w / 2
|
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
bucketFg := style.defaultFg
|
|
|
|
bucketBg := style.defaultBg
|
|
|
|
if comparePaths(screen.currentPath, bp.GetPath()) {
|
|
|
|
bucketFg = style.cursorFg
|
|
|
|
bucketBg = style.cursorBg
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|
2015-04-28 15:05:24 +00:00
|
|
|
|
2015-09-17 16:52:02 +00:00
|
|
|
pairString := strings.Repeat(" ", len(bp.GetPath())*2) //screen.db.getDepthFromPath(bp.GetPath())*2)
|
|
|
|
pairString = fmt.Sprintf("%s%s: %s", pairString, bp.key, bp.val)
|
|
|
|
if w-len(pairString) > 0 {
|
|
|
|
pairString = fmt.Sprintf("%s%s", pairString, strings.Repeat(" ", (w-len(pairString))))
|
2015-05-15 21:07:05 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
termbox_util.DrawStringAtPoint(pairString, 0, y, bucketFg, bucketBg)
|
2015-04-30 16:22:37 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2015-05-04 18:50:41 +00:00
|
|
|
func (screen *BrowserScreen) startDeleteItem() bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-04 18:50:41 +00:00
|
|
|
if e == nil {
|
|
|
|
w, h := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH := (w / 2), 6
|
|
|
|
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
|
|
|
|
mod := termbox_util.CreateConfirmModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
|
2015-05-04 18:50:41 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Delete Bucket '%s'?", b.name), inpW-1, termbox_util.ALIGN_CENTER))
|
2015-05-04 18:50:41 +00:00
|
|
|
} else if p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Delete Pair '%s'?", p.key), inpW-1, termbox_util.ALIGN_CENTER))
|
2015-05-04 18:50:41 +00:00
|
|
|
}
|
2015-05-05 01:17:41 +00:00
|
|
|
mod.Show()
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetText(termbox_util.AlignText("This cannot be undone!", inpW-1, termbox_util.ALIGN_CENTER))
|
|
|
|
screen.confirmModal = mod
|
|
|
|
screen.mode = modeDelete
|
2015-05-04 18:50:41 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) startEditItem() bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
_, p, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-15 21:07:05 +00:00
|
|
|
if e == nil {
|
|
|
|
w, h := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH := (w / 2), 6
|
|
|
|
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
|
|
|
|
mod := termbox_util.CreateInputModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
|
2015-05-15 21:07:05 +00:00
|
|
|
if p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Input new value for '%s'", p.key), inpW, termbox_util.ALIGN_CENTER))
|
2015-05-15 21:07:05 +00:00
|
|
|
mod.SetValue(p.val)
|
|
|
|
}
|
|
|
|
mod.Show()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.inputModal = mod
|
|
|
|
screen.mode = modeChangeVal
|
2015-05-15 21:07:05 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) startRenameItem() bool {
|
2015-09-17 16:52:02 +00:00
|
|
|
b, p, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-02 03:17:31 +00:00
|
|
|
if e == nil {
|
|
|
|
w, h := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH := (w / 2), 6
|
|
|
|
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
|
|
|
|
mod := termbox_util.CreateInputModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
|
2015-05-02 03:17:31 +00:00
|
|
|
if b != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Rename Bucket '%s' to:", b.name), inpW, termbox_util.ALIGN_CENTER))
|
2015-05-03 23:57:37 +00:00
|
|
|
mod.SetValue(b.name)
|
2015-05-02 03:17:31 +00:00
|
|
|
} else if p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
mod.SetTitle(termbox_util.AlignText(fmt.Sprintf("Rename Key '%s' to:", p.key), inpW, termbox_util.ALIGN_CENTER))
|
2015-05-15 21:07:05 +00:00
|
|
|
mod.SetValue(p.key)
|
2015-05-02 03:17:31 +00:00
|
|
|
}
|
2015-05-05 01:17:41 +00:00
|
|
|
mod.Show()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.inputModal = mod
|
|
|
|
screen.mode = modeChangeKey
|
2015-05-02 03:17:31 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2015-05-04 22:41:47 +00:00
|
|
|
func (screen *BrowserScreen) startInsertItemAtParent(tp BoltType) bool {
|
|
|
|
w, h := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH := w-1, 7
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH = (w / 2), 7
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
|
|
|
|
mod := termbox_util.CreateInputModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
|
|
|
|
screen.inputModal = mod
|
|
|
|
if len(screen.currentPath) <= 0 {
|
2015-05-04 22:41:47 +00:00
|
|
|
// in the root directory
|
2015-09-17 16:52:02 +00:00
|
|
|
if tp == typeBucket {
|
|
|
|
mod.SetTitle(termbox_util.AlignText("Create Root Bucket", inpW, termbox_util.ALIGN_CENTER))
|
|
|
|
screen.mode = modeInsertBucket | modeModToParent
|
2015-05-05 01:17:41 +00:00
|
|
|
mod.Show()
|
2015-05-04 22:41:47 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
var insPath string
|
|
|
|
_, p, e := screen.db.getGenericFromPath(screen.currentPath[:len(screen.currentPath)-1])
|
2015-05-14 15:17:43 +00:00
|
|
|
if e == nil && p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
insPath = strings.Join(screen.currentPath[:len(screen.currentPath)-2], "/") + "/"
|
2015-05-14 15:17:43 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
insPath = strings.Join(screen.currentPath[:len(screen.currentPath)-1], "/") + "/"
|
2015-05-14 15:17:43 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
titlePrfx := ""
|
|
|
|
if tp == typeBucket {
|
|
|
|
titlePrfx = "New Bucket: "
|
|
|
|
} else if tp == typePair {
|
|
|
|
titlePrfx = "New Pair: "
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
titleText := titlePrfx + insPath
|
|
|
|
if len(titleText) > inpW {
|
|
|
|
truncW := len(titleText) - inpW
|
|
|
|
titleText = titlePrfx + "..." + insPath[truncW+3:]
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
if tp == typeBucket {
|
|
|
|
mod.SetTitle(termbox_util.AlignText(titleText, inpW, termbox_util.ALIGN_CENTER))
|
|
|
|
screen.mode = modeInsertBucket | modeModToParent
|
2015-05-05 01:17:41 +00:00
|
|
|
mod.Show()
|
2015-05-04 22:41:47 +00:00
|
|
|
return true
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if tp == typePair {
|
|
|
|
mod.SetTitle(termbox_util.AlignText(titleText, inpW, termbox_util.ALIGN_CENTER))
|
2015-05-05 01:17:41 +00:00
|
|
|
mod.Show()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeInsertPair | modeModToParent
|
2015-05-04 22:41:47 +00:00
|
|
|
return true
|
|
|
|
}
|
2015-05-03 23:57:37 +00:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2015-05-04 22:41:47 +00:00
|
|
|
func (screen *BrowserScreen) startInsertItem(tp BoltType) bool {
|
2015-05-02 03:17:31 +00:00
|
|
|
w, h := termbox.Size()
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH := w-1, 7
|
2015-05-18 13:49:47 +00:00
|
|
|
if w > 80 {
|
2015-09-17 16:52:02 +00:00
|
|
|
inpW, inpH = (w / 2), 7
|
2015-05-18 13:49:47 +00:00
|
|
|
}
|
2015-09-17 16:52:02 +00:00
|
|
|
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
|
|
|
|
mod := termbox_util.CreateInputModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
|
|
|
|
screen.inputModal = mod
|
|
|
|
var insPath string
|
|
|
|
_, p, e := screen.db.getGenericFromPath(screen.currentPath)
|
2015-05-14 15:17:43 +00:00
|
|
|
if e == nil && p != nil {
|
2015-09-17 16:52:02 +00:00
|
|
|
insPath = strings.Join(screen.currentPath[:len(screen.currentPath)-1], "/") + "/"
|
2015-05-14 15:17:43 +00:00
|
|
|
} else {
|
2015-09-17 16:52:02 +00:00
|
|
|
insPath = strings.Join(screen.currentPath, "/") + "/"
|
|
|
|
}
|
|
|
|
titlePrfx := ""
|
|
|
|
if tp == typeBucket {
|
|
|
|
titlePrfx = "New Bucket: "
|
|
|
|
} else if tp == typePair {
|
|
|
|
titlePrfx = "New Pair: "
|
|
|
|
}
|
|
|
|
titleText := titlePrfx + insPath
|
|
|
|
if len(titleText) > inpW {
|
|
|
|
truncW := len(titleText) - inpW
|
|
|
|
titleText = titlePrfx + "..." + insPath[truncW+3:]
|
|
|
|
}
|
|
|
|
if tp == typeBucket {
|
|
|
|
mod.SetTitle(termbox_util.AlignText(titleText, inpW, termbox_util.ALIGN_CENTER))
|
|
|
|
screen.mode = modeInsertBucket
|
2015-05-08 15:14:02 +00:00
|
|
|
mod.Show()
|
|
|
|
return true
|
2015-09-17 16:52:02 +00:00
|
|
|
} else if tp == typePair {
|
|
|
|
mod.SetTitle(termbox_util.AlignText(titleText, inpW, termbox_util.ALIGN_CENTER))
|
2015-05-12 21:04:49 +00:00
|
|
|
mod.Show()
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.mode = modeInsertPair
|
2015-05-12 21:04:49 +00:00
|
|
|
return true
|
2015-05-04 22:41:47 +00:00
|
|
|
}
|
2015-05-02 03:17:31 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2015-05-14 15:17:43 +00:00
|
|
|
func (screen *BrowserScreen) setMessage(msg string) {
|
|
|
|
screen.message = msg
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.messageTime = time.Now()
|
|
|
|
screen.messageTimeout = time.Second * 2
|
2015-05-14 15:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* setMessageWithTimeout lets you specify the timeout for the message
|
|
|
|
* setting it to -1 means it won't timeout
|
|
|
|
*/
|
|
|
|
func (screen *BrowserScreen) setMessageWithTimeout(msg string, timeout time.Duration) {
|
|
|
|
screen.message = msg
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.messageTime = time.Now()
|
|
|
|
screen.messageTimeout = timeout
|
2015-05-14 15:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (screen *BrowserScreen) clearMessage() {
|
|
|
|
screen.message = ""
|
2015-09-17 16:52:02 +00:00
|
|
|
screen.messageTimeout = -1
|
2015-05-14 15:17:43 +00:00
|
|
|
}
|
|
|
|
|
2015-05-08 15:14:02 +00:00
|
|
|
func (screen *BrowserScreen) refreshDatabase() {
|
|
|
|
shadowDB := screen.db
|
|
|
|
screen.db = screen.db.refreshDatabase()
|
|
|
|
screen.db.syncOpenBuckets(shadowDB)
|
|
|
|
}
|
|
|
|
|
2015-04-30 16:22:37 +00:00
|
|
|
func comparePaths(p1, p2 []string) bool {
|
|
|
|
return strings.Join(p1, "/") == strings.Join(p2, "/")
|
2015-04-24 22:53:33 +00:00
|
|
|
}
|