ui: historical/period toggle, help updates

accounts and register screens can now switch between "historical"
(default) and "period" modes

title header wording is clearer

quick help footer now indicates historical/period and tree/flat modes,
saving space in the title

help screen is more explanatory

the enter key has been reserved for later and is no longer an alias
for right/l
This commit is contained in:
Simon Michael 2016-08-12 17:44:55 -07:00
parent f3bcf570e5
commit 4e3c0cc936
5 changed files with 142 additions and 96 deletions

View File

@ -79,7 +79,13 @@ asInit d reset ui@UIState{
valuedate = fromMaybe d $ queryEndDate False q
-- run the report
(items,_total) = convert $ singleBalanceReport ropts' q j
(items,_total) = convert $ report ropts' q j
where
-- still using the old balanceReport for change reports as it
-- does not include every account from before the report period
report | balancetype_ ropts == HistoricalBalance = singleBalanceReport
| otherwise = balanceReport
-- pre-render the list items
displayitem (fullacct, shortacct, indent, bal) =
@ -118,7 +124,7 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
maxacctwidthseen =
-- ltrace "maxacctwidthseen" $
V.maximum $
V.map (\AccountsScreenItem{..} -> asItemIndentLevel*2 + textWidth asItemDisplayAccountName) $
V.map (\AccountsScreenItem{..} -> asItemIndentLevel + textWidth asItemDisplayAccountName) $
-- V.filter (\(indent,_,_,_) -> (indent-1) <= fromMaybe 99999 mdepth) $
displayitems
maxbalwidthseen =
@ -145,14 +151,17 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
render $ defaultLayout toplabel bottomlabel $ renderList (asDrawItem colwidths) True (_asList s)
where
ishistorical = balancetype_ ropts == HistoricalBalance
toplabel =
files
-- <+> withAttr (borderAttr <> "query") (str (if flat_ ropts then " flat" else ""))
<+> nonzero
<+> str " accounts"
<+> withAttr (borderAttr <> "query") (str (if flat_ ropts then " (flat)" else ""))
<+> str (if ishistorical then " accounts" else " account changes")
-- <+> str (if ishistorical then " balances" else " changes")
<+> borderPeriodStr (if ishistorical then "at end of" else "in") (period_ ropts)
<+> borderQueryStr querystr
<+> togglefilters
<+> borderPeriodStr (period_ ropts)
<+> borderDepthStr mdepth
<+> str " ("
<+> cur
@ -176,7 +185,7 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
,if real_ ropts then ["real"] else []
] of
[] -> str ""
fs -> str " with " <+> withAttr (borderAttr <> "query") (str $ intercalate ", " fs) <+> str " txns"
fs -> str " from " <+> withAttr (borderAttr <> "query") (str $ intercalate ", " fs) <+> str " txns"
nonzero | empty_ ropts = str ""
| otherwise = withAttr (borderAttr <> "query") (str " nonzero")
cur = str (case _asList s ^. listSelectedL of
@ -188,17 +197,25 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
Minibuffer ed -> minibuffer ed
_ -> quickhelp
where
quickhelp = borderKeysStr [
("?", "help")
,("right", "register")
,("F", "flat?")
,("-+0123456789", "depth")
selectedstr = withAttr (borderAttr <> "query") . str
quickhelp = borderKeysStr' [
("?", str "help")
,("right", str "register")
,("H"
,if ishistorical
then selectedstr "historical" <+> str "/period"
else str "historical" <+> selectedstr "/period")
,("F"
,if flat_ ropts
then str "tree/" <+> selectedstr "flat"
else selectedstr "tree" <+> str "/flat")
,("-+", str "depth")
--,("/", "filter")
--,("DEL", "unfilter")
--,("ESC", "cancel/top")
,("a", "add")
,("g", "reload")
,("q", "quit")
,("a", str "add")
-- ,("g", "reload")
,("q", str "quit")
]
asDraw _ = error "draw function called with wrong screen type, should not happen"
@ -210,7 +227,7 @@ asDrawItem (acctwidth, balwidth) selected AccountsScreenItem{..} =
-- let showitem = intercalate "\n" . balanceReportItemAsText defreportopts fmt
render $
addamts asItemRenderedAmounts $
str (T.unpack $ fitText (Just acctwidth) (Just acctwidth) True True $ T.replicate (2*asItemIndentLevel) " " <> asItemDisplayAccountName) <+>
str (T.unpack $ fitText (Just acctwidth) (Just acctwidth) True True $ T.replicate (asItemIndentLevel) " " <> asItemDisplayAccountName) <+>
str " " <+>
str (balspace asItemRenderedAmounts)
where
@ -287,6 +304,7 @@ asHandle ui0@UIState{
EvKey (KChar '_') [] -> continue $ regenerateScreens j d $ decDepth ui
EvKey (KChar c) [] | c `elem` ['+','='] -> continue $ regenerateScreens j d $ incDepth ui
EvKey (KChar 't') [] -> continue $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui
EvKey (KChar 'H') [] -> continue $ regenerateScreens j d $ toggleHistorical ui
EvKey (KChar 'F') [] -> continue $ regenerateScreens j d $ toggleFlat ui
EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui)
EvKey (KChar 'C') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleCleared ui)
@ -298,8 +316,8 @@ asHandle ui0@UIState{
EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod ui
EvKey (KChar '/') [] -> continue $ regenerateScreens j d $ showMinibuffer ui
EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui)
EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KChar 'l', KEnter] -> scrollTopRegister >> continue (screenEnter d scr ui)
EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KChar 'l'] -> scrollTopRegister >> continue (screenEnter d scr ui)
where
scr = rsSetAccount selacct isdepthclipped registerScreen
isdepthclipped = case getDepth ui of

View File

@ -62,7 +62,6 @@ rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajo
thisacctq = Acct $ (if inclusive then accountNameToAccountRegex else accountNameToAccountOnlyRegex) rsAccount
ropts' = ropts{
depth_=Nothing
,balancetype_=HistoricalBalance
}
q = queryFromOpts d ropts'
-- reportq = filterQuery (not . queryIsDepth) q
@ -158,14 +157,18 @@ rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
render $ defaultLayout toplabel bottomlabel $ renderList (rsDrawItem colwidths) True rsList
where
ishistorical = balancetype_ ropts == HistoricalBalance
inclusive = not (flat_ ropts) || rsForceInclusive
toplabel =
withAttr ("border" <> "bold") (str $ T.unpack $ replaceHiddenAccountsNameWith "All" rsAccount)
<+> withAttr (borderAttr <> "query") (str $ if inclusive then "" else " exclusive")
-- <+> withAttr (borderAttr <> "query") (str $ if inclusive then "" else " exclusive")
<+> togglefilters
<+> str " transactions"
-- <+> str (if ishistorical then " historical total" else " period total")
<+> borderQueryStr (query_ ropts)
-- <+> str " and subs"
<+> borderPeriodStr (period_ ropts)
<+> borderPeriodStr "in" (period_ ropts)
<+> str " ("
<+> cur
<+> str "/"
@ -173,7 +176,6 @@ rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
<+> str ")"
<+> (if ignore_assertions_ copts then withAttr (borderAttr <> "query") (str " ignoring balance assertions") else str "")
where
inclusive = not (flat_ ropts) || rsForceInclusive
togglefilters =
case concat [
uiShowClearedStatus $ clearedstatus_ ropts
@ -193,16 +195,22 @@ rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
Minibuffer ed -> minibuffer ed
_ -> quickhelp
where
quickhelp = borderKeysStr [
("?", "help")
,("left", "back")
,("right", "transaction")
,("/", "filter")
,("DEL", "unfilter")
--,("ESC", "reset")
,("a", "add")
,("g", "reload")
,("q", "quit")
selectedstr = withAttr (borderAttr <> "query") . str
quickhelp = borderKeysStr' [
("?", str "help")
,("left", str "back")
,("right", str "transaction")
,("H"
,if ishistorical
then selectedstr "historical" <+> str "/period"
else str "historical" <+> selectedstr "/period")
,("F"
,if inclusive
then selectedstr "inclusive" <+> str "/exclusive"
else str "inclusive/" <+> selectedstr "exclusive")
-- ,("a", "add")
-- ,("g", "reload")
-- ,("q", "quit")
]
rsDraw _ = error "draw function called with wrong screen type, should not happen"
@ -265,6 +273,7 @@ rsHandle ui@UIState{
(pos,f) = case listSelectedElement rsList of
Nothing -> (endPos, journalFilePath j)
Just (_, RegisterScreenItem{rsItemTransaction=Transaction{tsourcepos=GenericSourcePos f l c}}) -> (Just (l, Just c),f)
EvKey (KChar 'H') [] -> continue $ regenerateScreens j d $ toggleHistorical ui
EvKey (KChar 'F') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleFlat ui)
EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui)
EvKey (KChar 'C') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleCleared ui)
@ -276,8 +285,8 @@ rsHandle ui@UIState{
EvKey (KRight) [MShift] -> continue $ regenerateScreens j d $ nextReportPeriod ui
EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod ui
EvKey k [] | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui)
EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KChar 'l', KEnter] -> do
EvKey k [] | k `elem` [KLeft, KChar 'h'] -> continue $ popScreen ui
EvKey k [] | k `elem` [KRight, KChar 'l'] -> do
case listSelectedElement rsList of
Just (_, RegisterScreenItem{rsItemTransaction=t}) ->
let

View File

@ -56,6 +56,14 @@ toggleFlat ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropt
toggleFlatMode ropts@ReportOpts{accountlistmode_=ALFlat} = ropts{accountlistmode_=ALTree}
toggleFlatMode ropts = ropts{accountlistmode_=ALFlat}
-- | Toggle between historical balances and period balances.
toggleHistorical :: UIState -> UIState
toggleHistorical ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{balancetype_=b}}}}
where
b | balancetype_ ropts == HistoricalBalance = PeriodChange
| otherwise = HistoricalBalance
-- | Toggle between showing all and showing only real (non-virtual) items.
toggleReal :: UIState -> UIState
toggleReal ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =

View File

@ -8,7 +8,7 @@ where
import Brick
import Brick.Widgets.Border
import Brick.Widgets.Border.Style
import Brick.Widgets.Center
-- import Brick.Widgets.Center
import Brick.Widgets.Dialog
import Brick.Widgets.Edit
import Data.List
@ -48,9 +48,9 @@ helpDialog =
padLeftRight 1 $
vBox [
str "NAVIGATION"
,renderKey ("UP/k/DOWN/j/PGUP/PGDN/HOME/END", "")
,renderKey ("UP/DOWN/k/j/PGUP/PGDN/HOME/END", "")
,str " move selection"
,renderKey ("RIGHT/l/ENTER", "drill down")
,renderKey ("RIGHT/l", "more detail")
,renderKey ("LEFT/h", "previous screen")
,renderKey ("ESC", "cancel / reset")
,str " "
@ -61,40 +61,50 @@ helpDialog =
,renderKey ("g", "reload data")
,renderKey ("I", "toggle balance assertions")
,renderKey ("q", "quit")
]
,str " "
,str "MANUAL"
,str "from help dialog:"
,renderKey ("t", "text")
,renderKey ("m", "man page")
,renderKey ("i", "info")
]
,padLeftRight 1 $
vBox [
str "FILTERING"
,renderKey ("/", "set a filter query")
,renderKey ("C", "toggle cleared filter")
,renderKey ("U", "toggle uncleared filter")
,renderKey ("R", "toggle real filter")
,renderKey ("Z", "toggle nonzero filter")
,renderKey ("F", "toggle flat/exclusive mode")
,renderKey ("SHIFT-DOWN/UP", "shrink/grow report period")
,renderKey ("SHIFT-RIGHT/LEFT", "next/previous report period")
,renderKey ("t", "set report period to today")
,str " "
,renderKey ("t", " set report period to today")
,renderKey ("d/u", "decrease/increase report period")
,renderKey ("n/p", "next/previous report period")
,renderKey ("/", "set a filter query")
,renderKey ("C", "toggle cleared/all")
,renderKey ("U", "toggle uncleared/all")
,renderKey ("R", "toggle real/all")
,renderKey ("Z", "toggle nonzero/all")
,renderKey ("DEL/BS", "remove filters")
,str " "
,str "accounts screen:"
,renderKey ("-+0123456789", "set depth limit")
,renderKey ("H", "toggle period balance (shows change) or\nhistorical balance (includes older postings)")
,renderKey ("F", "toggle tree (amounts include subaccounts) or\nflat mode (amounts exclude subaccounts\nexcept when account is depth-clipped)")
,str " "
,renderKey ("DEL/BS", "remove filters")
,str "register screen:"
,renderKey ("H", "toggle period or historical total")
,renderKey ("F", "toggle subaccount transaction inclusion\n(and tree/flat mode)")
]
]
,vBox [
str " "
,hCenter $ padLeftRight 1 $
hCenter (str "MANUAL")
<=>
hCenter (hBox [
renderKey ("t", "text")
,str " "
,renderKey ("m", "man page")
,str " "
,renderKey ("i", "info")
])
]
-- ,vBox [
-- str " "
-- ,hCenter $ padLeftRight 1 $
-- hCenter (str "MANUAL")
-- <=>
-- hCenter (hBox [
-- renderKey ("t", "text")
-- ,str " "
-- ,renderKey ("m", "man page")
-- ,str " "
-- ,renderKey ("i", "info")
-- ])
-- ]
]
where
renderKey (key,desc) = withAttr (borderAttr <> "keys") (str key) <+> str " " <+> str desc
@ -104,10 +114,12 @@ helpHandle :: UIState -> Event -> EventM Name (Next UIState)
helpHandle ui ev =
case ev of
EvKey k [] | k `elem` [KEsc, KLeft, KChar 'h', KChar '?'] -> continue $ setMode Normal ui
EvKey (KChar 't') [] -> suspendAndResume $ runHelp >> return (setMode Normal ui)
EvKey (KChar 'm') [] -> suspendAndResume $ runMan >> return (setMode Normal ui)
EvKey (KChar 'i') [] -> suspendAndResume $ runInfo >> return (setMode Normal ui)
EvKey (KChar 't') [] -> suspendAndResume $ runHelp >> return ui'
EvKey (KChar 'm') [] -> suspendAndResume $ runMan >> return ui'
EvKey (KChar 'i') [] -> suspendAndResume $ runInfo >> return ui'
_ -> continue ui
where
ui' = setMode Normal ui
-- | Draw the minibuffer.
minibuffer :: Editor Name -> Widget Name
@ -133,15 +145,18 @@ borderDepthStr :: Maybe Int -> Widget Name
borderDepthStr Nothing = str ""
borderDepthStr (Just d) = str " to " <+> withAttr (borderAttr <> "query") (str $ "depth "++show d)
borderPeriodStr :: Period -> Widget Name
borderPeriodStr PeriodAll = str ""
borderPeriodStr p = str " in " <+> withAttr (borderAttr <> "query") (str $ showPeriod p)
borderPeriodStr :: String -> Period -> Widget Name
borderPeriodStr _ PeriodAll = str ""
borderPeriodStr preposition p = str (" "++preposition++" ") <+> withAttr (borderAttr <> "query") (str $ showPeriod p)
borderKeysStr :: [(String,String)] -> Widget Name
borderKeysStr keydescs =
borderKeysStr = borderKeysStr' . map (\(a,b) -> (a, str b))
borderKeysStr' :: [(String,Widget Name)] -> Widget Name
borderKeysStr' keydescs =
hBox $
intersperse sep $
[withAttr (borderAttr <> "keys") (str keys) <+> str ":" <+> str desc | (keys, desc) <- keydescs]
[withAttr (borderAttr <> "keys") (str keys) <+> str ":" <+> desc | (keys, desc) <- keydescs]
where
-- sep = str " | "
sep = str " "

View File

@ -137,9 +137,17 @@ To see less detail, set a depth limit by pressing a number key, `1` to `9`.
`-` and `+` (or `=`) decrease and increase the depth limit.
To remove the depth limit, set it higher than the maximum account depth, or press `ESCAPE`.
`F` toggles flat mode on and off. In flat mode, accounts are listed without indentation,
and show their subaccount-excluding balances, except for accounts which have been clipped
by a depth limit, which show their inclusive balances (as with hledger's balance command).
`F` toggles flat mode, in which accounts are shown as a flat list, with their full names.
In this mode, account balances exclude subaccounts, except for accounts at the depth limit
(as with hledger's balance command).
`H` toggles between showing historical balances or period balances.
Historical balances (the default) are ending balances at the end of the report period,
taking into account all transactions before that date (filtered by the filter query if any),
including transactions before the start of the report period. In other words, historical
balances are what you would see on a bank statement for that account (unless disturbed by
a filter query). Period balances ignore transactions before the report start date, so they
show the change in balance during the report period. They are more useful eg when viewing a time log.
`C` toggles cleared mode, in which
[uncleared transactions and postings](/journal.html#transactions) are
@ -166,32 +174,20 @@ Each line represents one transaction and shows:
- the overall change to the current account's balance;
positive for an inflow to this account, negative for an outflow.
- the current account's historic balance (if no query other than a date limit is in effect)
or the running total starting from zero (otherwise), after the transaction.
Eg, these will show historic balances:
- the running historical total or period total for the current account, after the transaction.
This can be toggled with `H`.
Similar to the accounts screen, the historical total is affected by transactions
(filtered by the filter query) before the report start date, while the period total is not.
If the historical total is not disturbed by a filter query, it will be the
running historical balance you would see on a bank register for the current account.
```
$ hledger-ui
$ hledger-ui --begin 'this month'
$ hledger-ui --register checking date:2015/10
```
while these will show a running total, since the queries are not just date limits:
```
$ hledger-ui checking
$ hledger-ui --begin 'this month' desc:market
$ hledger-ui --register checking --cleared
```
The register screen normally shows transactions in the current account
and any of its subaccounts (inclusive mode).
If it was entered from the accounts screen in flat mode, where the
selected account was not depth-clipped and therefore was showing its
subaccount-excluding balance, the register too will omit the transactions
of subaccounts (exclusive mode). This means the register always shows
the transactions responsible for the balance being displayed on the
accounts screen.
If the accounts screen was in tree mode,
the register screen will include transactions from both the current account and its subaccounts.
If the accounts screen was in flat mode, and a non-depth-clipped account was selected,
the register screen will exclude transactions from subaccounts.
In other words, the register always shows the transactions responsible for the period balance
shown on the accounts screen.
As on the accounts screen, this can be toggled with `F`.
`C` toggles cleared mode, in which
[uncleared transactions and postings](/journal.html#transactions) are