ui: allow the filter query to be changed

This commit is contained in:
Simon Michael 2016-06-04 11:51:28 -07:00
parent 606036e1a2
commit 9131eb7c67
12 changed files with 193 additions and 88 deletions

View File

@ -25,6 +25,7 @@ import qualified Data.Vector as V
import Graphics.Vty as Vty
import Brick
import Brick.Widgets.List
import Brick.Widgets.Edit
import Brick.Widgets.Border (borderAttr)
-- import Brick.Widgets.Center
@ -103,7 +104,8 @@ initAccountsScreen _ _ = error "init function called with wrong screen type, sho
drawAccountsScreen :: AppState -> [Widget]
drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
,ajournal=j
,aScreen=AccountsScreen{asState=(l,_)}} =
,aScreen=AccountsScreen{asState=(l,_)}
,aMinibuffer=mbuf} =
[ui]
where
toplabel = files
@ -148,11 +150,16 @@ drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
,("C", "cleared?")
,("U", "uncleared?")
,("R", "real?")
,("f", "filter")
,("right/enter", "register")
,("g", "reload")
,("q", "quit")
]
bottomarea = case mbuf of
Nothing -> bottomlabel
Just ed -> minibuffer ed
ui = Widget Greedy Greedy $ do
c <- getContext
let
@ -188,7 +195,7 @@ drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
colwidths = (acctwidth, balwidth)
render $ defaultLayout toplabel bottomlabel $ renderList l (drawAccountsItem colwidths)
render $ defaultLayout toplabel bottomarea $ renderList l (drawAccountsItem colwidths)
drawAccountsScreen _ = error "draw function called with wrong screen type, should not happen"
@ -224,7 +231,8 @@ handleAccountsScreen st@AppState{
aScreen=scr@AccountsScreen{asState=(l,selacct)}
,aopts=UIOpts{cliopts_=copts}
,ajournal=j
} e = do
,aMinibuffer=mbuf
} ev = do
d <- liftIO getCurrentDay
-- c <- getContext
-- let h = c^.availHeightL
@ -238,8 +246,10 @@ handleAccountsScreen st@AppState{
Nothing -> selacct
st' = st{aScreen=scr{asState=(l,selacct')}}
case e of
Vty.EvKey Vty.KEsc [] -> halt st'
case mbuf of
Nothing ->
case ev of
Vty.EvKey (Vty.KChar 'q') [] -> halt st'
-- Vty.EvKey (Vty.KChar 'l') [Vty.MCtrl] -> do
@ -267,6 +277,7 @@ handleAccountsScreen st@AppState{
Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st')
Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st')
Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st')
Vty.EvKey (Vty.KChar 'f') [] -> continue $ reload j d $ stShowMinibuffer st'
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st'
Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do
let
@ -280,6 +291,15 @@ handleAccountsScreen st@AppState{
l' <- handleEvent ev l
continue $ st'{aScreen=scr{asState=(l',selacct')}}
-- continue =<< handleEventLensed st' someLens ev
Just ed ->
case ev of
Vty.EvKey Vty.KEsc [] -> continue $ stHideMinibuffer st'
Vty.EvKey Vty.KEnter [] -> continue $ reload j d $ stFilter s $ stHideMinibuffer st'
where s = chomp $ unlines $ getEditContents ed
ev -> do ed' <- handleEvent ev ed
continue $ st'{aMinibuffer=Just ed'}
where
-- Encourage a more stable scroll position when toggling list items.
-- We scroll to the top, and the viewport will automatically

View File

@ -115,6 +115,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do
,ajournal=j
,aScreen=asSetSelectedAccount acct AS.screen
,aPrevScreens=[]
,aMinibuffer=Nothing
}
st = (sInitFn scr) d
@ -123,6 +124,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do
,ajournal=j
,aScreen=scr
,aPrevScreens=prevscrs
,aMinibuffer=Nothing
}
app :: App (AppState) V.Event

View File

@ -21,6 +21,7 @@ import qualified Data.Vector as V
import Graphics.Vty as Vty
import Brick
import Brick.Widgets.List
import Brick.Widgets.Edit
import Brick.Widgets.Border (borderAttr)
-- import Brick.Widgets.Center
-- import Text.Printf
@ -94,12 +95,14 @@ initRegisterScreen _ _ = error "init function called with wrong screen type, sho
drawRegisterScreen :: AppState -> [Widget]
drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
,aScreen=RegisterScreen{rsState=(l,acct)}} = [ui]
,aScreen=RegisterScreen{rsState=(l,acct)}
,aMinibuffer=mbuf}
= [ui]
where
toplabel = withAttr ("border" <> "bold") (str $ T.unpack acct)
<+> togglefilters
<+> str " transactions"
-- <+> borderQueryStr querystr -- no, account transactions report shows all transactions in the acct ?
<+> borderQueryStr (query_ ropts)
-- <+> str " and subs"
<+> str " ("
<+> cur
@ -176,12 +179,17 @@ drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
,("C", "cleared?")
,("U", "uncleared?")
,("R", "real?")
,("f", "filter")
,("right/enter", "transaction")
,("g", "reload")
,("q", "quit")
]
render $ defaultLayout toplabel bottomlabel $ renderList l (drawRegisterItem colwidths)
bottomarea = case mbuf of
Nothing -> bottomlabel
Just ed -> minibuffer ed
render $ defaultLayout toplabel bottomarea $ renderList l (drawRegisterItem colwidths)
drawRegisterScreen _ = error "draw function called with wrong screen type, should not happen"
@ -211,10 +219,13 @@ handleRegisterScreen st@AppState{
aScreen=s@RegisterScreen{rsState=(l,acct)}
,aopts=UIOpts{cliopts_=copts}
,ajournal=j
} e = do
,aMinibuffer=mbuf
} ev = do
d <- liftIO getCurrentDay
case e of
Vty.EvKey Vty.KEsc [] -> halt st
case mbuf of
Nothing ->
case ev of
Vty.EvKey (Vty.KChar 'q') [] -> halt st
Vty.EvKey (Vty.KChar 'g') [] -> do
@ -227,6 +238,7 @@ handleRegisterScreen st@AppState{
Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st)
Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st)
Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st)
Vty.EvKey (Vty.KChar 'f') [] -> (continue $ reload j d $ stShowMinibuffer st)
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st
Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do
@ -245,6 +257,15 @@ handleRegisterScreen st@AppState{
l' <- handleEvent ev l
continue st{aScreen=s{rsState=(l',acct)}}
-- continue =<< handleEventLensed st someLens ev
Just ed ->
case ev of
Vty.EvKey Vty.KEsc [] -> continue $ stHideMinibuffer st
Vty.EvKey Vty.KEnter [] -> continue $ reload j d $ stFilter s $ stHideMinibuffer st
where s = chomp $ unlines $ getEditContents ed
ev -> do ed' <- handleEvent ev ed
continue $ st{aMinibuffer=Just ed'}
where
-- Encourage a more stable scroll position when toggling list items (cf AccountsScreen.hs)
scrollTop = vScrollToBeginning $ viewportScroll "register"

View File

@ -72,6 +72,7 @@ themesList = [
(borderAttr <> "query", cyan `on` black & bold),
(borderAttr <> "depth", yellow `on` black & bold),
(borderAttr <> "keys", white `on` black & bold),
(borderAttr <> "minibuffer", white `on` black & bold),
-- ("normal" , black `on` white),
("list" , black `on` white), -- regular list items
("list" <> "selected" , white `on` blue & bold), -- selected list items

View File

@ -1,9 +1,12 @@
{-# LANGUAGE StandaloneDeriving #-}
module Hledger.UI.UITypes where
import Data.Time.Calendar (Day)
import qualified Graphics.Vty as V
import Brick
import Brick.Widgets.List (List)
import Brick.Widgets.Edit (Editor)
import Text.Show.Functions ()
-- import the Show instance for functions. Warning, this also re-exports it
@ -12,6 +15,10 @@ import Hledger.UI.UIOptions
----------------------------------------------------------------------
instance Show Editor
where
show = const "<Editor>"
-- | hledger-ui's application state. This is part of, but distinct
-- from, brick's App.
data AppState = AppState {
@ -19,6 +26,7 @@ data AppState = AppState {
,ajournal :: Journal -- ^ the journal being viewed
,aScreen :: Screen -- ^ the currently active screen
,aPrevScreens :: [Screen] -- ^ previously visited screens, most recent first
,aMinibuffer :: Maybe Editor -- ^ a compact editor used for data entry, when active
} deriving (Show)
-- | Types of screen available within the app, along with their state.

View File

@ -14,6 +14,7 @@ module Hledger.UI.UIUtils (
,borderQueryStr
,borderDepthStr
,borderKeysStr
,minibuffer
--
,stToggleCleared
,stTogglePending
@ -21,6 +22,9 @@ module Hledger.UI.UIUtils (
,stToggleEmpty
,stToggleFlat
,stToggleReal
,stFilter
,stShowMinibuffer
,stHideMinibuffer
) where
import Lens.Micro ((^.))
@ -29,9 +33,11 @@ import Lens.Micro ((^.))
-- import Data.Default
import Data.List
import Data.Monoid
import Data.Text.Zipper (gotoEOL)
import Data.Time.Calendar (Day)
import Brick
-- import Brick.Widgets.List
import Brick.Widgets.Edit
import Brick.Widgets.Border
import Brick.Widgets.Border.Style
import Graphics.Vty as Vty
@ -87,6 +93,20 @@ stToggleReal st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=r
where
toggleReal ropts = ropts{real_=not $ real_ ropts}
-- | Apply a new filter query.
stFilter :: String -> AppState -> AppState
stFilter s st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
st{aopts=uopts{cliopts_=copts{reportopts_=ropts{query_=s}}}}
-- | Enable the minibuffer, setting its content to the current query with the cursor at the end.
stShowMinibuffer st = st{aMinibuffer=Just e}
where
e = applyEdit gotoEOL $ editor "minibuffer" (str . unlines) (Just 1) oldq
oldq = query_ $ reportopts_ $ cliopts_ $ aopts st
-- | Disable the minibuffer, discarding any edit in progress.
stHideMinibuffer st = st{aMinibuffer=Nothing}
-- | Regenerate the content for the current and previous screens, from a new journal and current date.
reload :: Journal -> Day -> AppState -> AppState
reload j d st@AppState{aScreen=s,aPrevScreens=ss} =
@ -229,3 +249,9 @@ borderKeysStr keydescs =
-- sep = str " | "
sep = str " "
minibuffer :: Editor -> Widget
minibuffer ed =
forceAttr (borderAttr <> "minibuffer") $
hBox $
[txt "filter: ", renderEditor ed]

View File

@ -232,7 +232,14 @@ With large journal files, there can be a noticeable pause.
.PP
\f[C]q\f[] quits the application.
.PP
Some screens have additional key bindings, described below.
\f[C]f\f[] lets you add or change the current filter query which limits
the data shown on most screens.
While editing, you can use typical command\-line edit keys, and press
enter to set the new filter, or escape to cancel.
Note queries which filter by account name may not work well in the
register screen.
.PP
Additional screen\-specific keys are described below.
.SH SCREENS
.SS Accounts screen
.PP

View File

@ -162,7 +162,13 @@ screens). With large journal files, there can be a noticeable pause.
`q' quits the application.
Some screens have additional key bindings, described below.
`f' lets you add or change the current filter query which limits the
data shown on most screens. While editing, you can use typical
command-line edit keys, and press enter to set the new filter, or escape
to cancel. Note queries which filter by account name may not work well
in the register screen.
Additional screen-specific keys are described below.

File: hledger-ui.1.info, Node: SCREENS, Prev: KEYS, Up: Top
@ -303,15 +309,15 @@ Node: OPTIONS714
Ref: #options813
Node: KEYS3689
Ref: #keys3786
Node: SCREENS4209
Ref: #screens4296
Node: Accounts screen4386
Ref: #accounts-screen4516
Node: Register screen5620
Ref: #register-screen5777
Node: Transaction screen7434
Ref: #transaction-screen7594
Node: Error screen8461
Ref: #error-screen8585
Node: SCREENS4506
Ref: #screens4593
Node: Accounts screen4683
Ref: #accounts-screen4813
Node: Register screen5917
Ref: #register-screen6074
Node: Transaction screen7731
Ref: #transaction-screen7891
Node: Error screen8758
Ref: #error-screen8882

End Tag Table

View File

@ -92,7 +92,13 @@ screens). With large journal files, there can be a noticeable pause.
`q` quits the application.
Some screens have additional key bindings, described below.
`f` lets you add or change the current
[filter query](/journal.html#queries) which limits the data shown on
most screens. While editing, you can use typical command-line edit keys,
and press enter to set the new filter, or escape to cancel. Note queries
which filter by account name may not work well in the register screen.
Additional screen-specific keys are described below.
# SCREENS

View File

@ -154,7 +154,13 @@ KKEEYYSS
q quits the application.
Some screens have additional key bindings, described below.
f lets you add or change the current filter query which limits the data
shown on most screens. While editing, you can use typical command-line
edit keys, and press enter to set the new filter, or escape to cancel.
Note queries which filter by account name may not work well in the reg-
ister screen.
Additional screen-specific keys are described below.
SSCCRREEEENNSS
AAccccoouunnttss ssccrreeeenn

View File

@ -84,6 +84,7 @@ executables:
- safe >= 0.2
- split >= 0.1 && < 0.3
- text >= 1.2 && < 1.3
- text-zipper >= 0.4 && < 0.5
- transformers
- vector
- vty >= 5.2 && < 5.5

View File

@ -75,6 +75,7 @@ executable hledger-ui
, safe >= 0.2
, split >= 0.1 && < 0.3
, text >= 1.2 && < 1.3
, text-zipper >= 0.4 && < 0.5
, transformers
, vector
, vty >= 5.2 && < 5.6