mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-12 19:08:34 +03:00
ui: indicate real mode and toggle it with R key (#354)
There is a limitation/bug: disabling real mode in the transaction screen won't show the non-real postings if it was entered from a real-mode register screen.
This commit is contained in:
parent
788021f5a4
commit
509f55864d
@ -24,6 +24,7 @@ module Hledger.Data.Journal (
|
|||||||
filterJournalPostings,
|
filterJournalPostings,
|
||||||
filterJournalAmounts,
|
filterJournalAmounts,
|
||||||
filterTransactionAmounts,
|
filterTransactionAmounts,
|
||||||
|
filterTransactionPostings,
|
||||||
filterPostingAmount,
|
filterPostingAmount,
|
||||||
-- * Querying
|
-- * Querying
|
||||||
journalAccountNames,
|
journalAccountNames,
|
||||||
@ -313,6 +314,10 @@ filterTransactionAmounts q t@Transaction{tpostings=ps} = t{tpostings=map (filter
|
|||||||
filterPostingAmount :: Query -> Posting -> Posting
|
filterPostingAmount :: Query -> Posting -> Posting
|
||||||
filterPostingAmount q p@Posting{pamount=Mixed as} = p{pamount=Mixed $ filter (q `matchesAmount`) as}
|
filterPostingAmount q p@Posting{pamount=Mixed as} = p{pamount=Mixed $ filter (q `matchesAmount`) as}
|
||||||
|
|
||||||
|
filterTransactionPostings :: Query -> Transaction -> Transaction
|
||||||
|
filterTransactionPostings m t@Transaction{tpostings=ps} = t{tpostings=filter (m `matchesPosting`) ps}
|
||||||
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- filtering V1
|
-- filtering V1
|
||||||
|
@ -218,9 +218,6 @@ summarisePostingAccounts ps =
|
|||||||
displayps | null realps = ps
|
displayps | null realps = ps
|
||||||
| otherwise = realps
|
| otherwise = realps
|
||||||
|
|
||||||
filterTransactionPostings :: Query -> Transaction -> Transaction
|
|
||||||
filterTransactionPostings m t@Transaction{tpostings=ps} = t{tpostings=filter (m `matchesPosting`) ps}
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- | Split a transactions report whose items may involve several commodities,
|
-- | Split a transactions report whose items may involve several commodities,
|
||||||
|
@ -100,13 +100,15 @@ initAccountsScreen d st@AppState{
|
|||||||
initAccountsScreen _ _ = error "init function called with wrong screen type, should not happen"
|
initAccountsScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||||
|
|
||||||
drawAccountsScreen :: AppState -> [Widget]
|
drawAccountsScreen :: AppState -> [Widget]
|
||||||
drawAccountsScreen _st@AppState{aopts=uopts, ajournal=j, aScreen=AccountsScreen{asState=(l,_)}} =
|
drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||||
|
,ajournal=j
|
||||||
|
,aScreen=AccountsScreen{asState=(l,_)}} =
|
||||||
[ui]
|
[ui]
|
||||||
where
|
where
|
||||||
toplabel = files
|
toplabel = files
|
||||||
<+> str " accounts"
|
<+> str " accounts"
|
||||||
<+> borderQueryStr querystr
|
<+> borderQueryStr querystr
|
||||||
<+> cleared
|
<+> togglefilters
|
||||||
<+> borderDepthStr mdepth
|
<+> borderDepthStr mdepth
|
||||||
<+> str " ("
|
<+> str " ("
|
||||||
<+> cur
|
<+> cur
|
||||||
@ -118,11 +120,15 @@ drawAccountsScreen _st@AppState{aopts=uopts, ajournal=j, aScreen=AccountsScreen{
|
|||||||
f:_ -> withAttr ("border" <> "bold") $ str $ takeFileName f
|
f:_ -> withAttr ("border" <> "bold") $ str $ takeFileName f
|
||||||
-- [f,_:[]] -> (withAttr ("border" <> "bold") $ str $ takeFileName f) <+> str " (& 1 included file)"
|
-- [f,_:[]] -> (withAttr ("border" <> "bold") $ str $ takeFileName f) <+> str " (& 1 included file)"
|
||||||
-- f:fs -> (withAttr ("border" <> "bold") $ str $ takeFileName f) <+> str (" (& " ++ show (length fs) ++ " included files)")
|
-- f:fs -> (withAttr ("border" <> "bold") $ str $ takeFileName f) <+> str (" (& " ++ show (length fs) ++ " included files)")
|
||||||
querystr = query_ $ reportopts_ $ cliopts_ uopts
|
querystr = query_ ropts
|
||||||
mdepth = depth_ $ reportopts_ $ cliopts_ uopts
|
mdepth = depth_ ropts
|
||||||
cleared = if (cleared_ $ reportopts_ $ cliopts_ uopts)
|
togglefilters =
|
||||||
then str " with " <+> withAttr (borderAttr <> "query") (str "cleared") <+> str " txns"
|
case concat [
|
||||||
else str ""
|
if cleared_ ropts then ["cleared"] else []
|
||||||
|
,if real_ ropts then ["real"] else []
|
||||||
|
] of
|
||||||
|
[] -> str ""
|
||||||
|
fs -> str " with " <+> withAttr (borderAttr <> "query") (str $ intercalate ", " fs) <+> str " txns"
|
||||||
cur = str (case l^.listSelectedL of
|
cur = str (case l^.listSelectedL of
|
||||||
Nothing -> "-"
|
Nothing -> "-"
|
||||||
Just i -> show (i + 1))
|
Just i -> show (i + 1))
|
||||||
@ -133,6 +139,7 @@ drawAccountsScreen _st@AppState{aopts=uopts, ajournal=j, aScreen=AccountsScreen{
|
|||||||
("-=1234567890", "depth")
|
("-=1234567890", "depth")
|
||||||
,("F", "flat?")
|
,("F", "flat?")
|
||||||
,("C", "cleared?")
|
,("C", "cleared?")
|
||||||
|
,("R", "real?")
|
||||||
,("right/enter", "register")
|
,("right/enter", "register")
|
||||||
,("g", "reload")
|
,("g", "reload")
|
||||||
,("q", "quit")
|
,("q", "quit")
|
||||||
@ -249,6 +256,7 @@ handleAccountsScreen st@AppState{
|
|||||||
Vty.EvKey (Vty.KChar '0') [] -> continue $ reload j d $ setDepth 0 st'
|
Vty.EvKey (Vty.KChar '0') [] -> continue $ reload j d $ setDepth 0 st'
|
||||||
Vty.EvKey (Vty.KChar 'F') [] -> continue $ reload j d $ stToggleFlat st'
|
Vty.EvKey (Vty.KChar 'F') [] -> continue $ reload j d $ stToggleFlat st'
|
||||||
Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st'
|
Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st'
|
||||||
|
Vty.EvKey (Vty.KChar 'R') [] -> continue $ reload j d $ stToggleReal st'
|
||||||
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st'
|
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st'
|
||||||
Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do
|
Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do
|
||||||
let
|
let
|
||||||
@ -264,15 +272,6 @@ handleAccountsScreen st@AppState{
|
|||||||
-- continue =<< handleEventLensed st' someLens ev
|
-- continue =<< handleEventLensed st' someLens ev
|
||||||
handleAccountsScreen _ _ = error "event handler called with wrong screen type, should not happen"
|
handleAccountsScreen _ _ = error "event handler called with wrong screen type, should not happen"
|
||||||
|
|
||||||
stToggleFlat :: AppState -> AppState
|
|
||||||
stToggleFlat st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
|
||||||
st{aopts=uopts{cliopts_=copts{reportopts_=toggleFlatMode ropts}}}
|
|
||||||
|
|
||||||
-- | Toggle between flat and tree mode. If in the third "default" mode, go to flat mode.
|
|
||||||
toggleFlatMode :: ReportOpts -> ReportOpts
|
|
||||||
toggleFlatMode ropts@ReportOpts{accountlistmode_=ALFlat} = ropts{accountlistmode_=ALTree}
|
|
||||||
toggleFlatMode ropts = ropts{accountlistmode_=ALFlat}
|
|
||||||
|
|
||||||
-- | Get the maximum account depth in the current journal.
|
-- | Get the maximum account depth in the current journal.
|
||||||
maxDepth :: AppState -> Int
|
maxDepth :: AppState -> Int
|
||||||
maxDepth AppState{ajournal=j} = maximum $ map accountNameLevel $ journalAccountNames j
|
maxDepth AppState{ajournal=j} = maximum $ map accountNameLevel $ journalAccountNames j
|
||||||
|
@ -85,11 +85,11 @@ initRegisterScreen d st@AppState{aopts=opts, ajournal=j, aScreen=s@RegisterScree
|
|||||||
initRegisterScreen _ _ = error "init function called with wrong screen type, should not happen"
|
initRegisterScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||||
|
|
||||||
drawRegisterScreen :: AppState -> [Widget]
|
drawRegisterScreen :: AppState -> [Widget]
|
||||||
drawRegisterScreen AppState{aopts=uopts -- @UIOpts{cliopts_=_copts@CliOpts{reportopts_=_ropts@ReportOpts{query_=querystr}}
|
drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||||
,aScreen=RegisterScreen{rsState=(l,acct)}} = [ui]
|
,aScreen=RegisterScreen{rsState=(l,acct)}} = [ui]
|
||||||
where
|
where
|
||||||
toplabel = withAttr ("border" <> "bold") (str $ T.unpack acct)
|
toplabel = withAttr ("border" <> "bold") (str $ T.unpack acct)
|
||||||
<+> cleared
|
<+> togglefilters
|
||||||
<+> str " transactions"
|
<+> str " transactions"
|
||||||
-- <+> borderQueryStr querystr -- no, account transactions report shows all transactions in the acct ?
|
-- <+> borderQueryStr querystr -- no, account transactions report shows all transactions in the acct ?
|
||||||
-- <+> str " and subs"
|
-- <+> str " and subs"
|
||||||
@ -98,9 +98,13 @@ drawRegisterScreen AppState{aopts=uopts -- @UIOpts{cliopts_=_copts@CliOpts{repor
|
|||||||
<+> str "/"
|
<+> str "/"
|
||||||
<+> total
|
<+> total
|
||||||
<+> str ")"
|
<+> str ")"
|
||||||
cleared = if (cleared_ $ reportopts_ $ cliopts_ uopts)
|
togglefilters =
|
||||||
then withAttr (borderAttr <> "query") (str " cleared")
|
case concat [
|
||||||
else str ""
|
if cleared_ ropts then ["cleared"] else []
|
||||||
|
,if real_ ropts then ["real"] else []
|
||||||
|
] of
|
||||||
|
[] -> str ""
|
||||||
|
fs -> withAttr (borderAttr <> "query") (str $ " " ++ intercalate ", " fs)
|
||||||
cur = str $ case l^.listSelectedL of
|
cur = str $ case l^.listSelectedL of
|
||||||
Nothing -> "-"
|
Nothing -> "-"
|
||||||
Just i -> show (i + 1)
|
Just i -> show (i + 1)
|
||||||
@ -158,6 +162,7 @@ drawRegisterScreen AppState{aopts=uopts -- @UIOpts{cliopts_=_copts@CliOpts{repor
|
|||||||
-- ("up/down/pgup/pgdown/home/end", "move")
|
-- ("up/down/pgup/pgdown/home/end", "move")
|
||||||
("left", "back")
|
("left", "back")
|
||||||
,("C", "cleared?")
|
,("C", "cleared?")
|
||||||
|
,("R", "real?")
|
||||||
,("right/enter", "transaction")
|
,("right/enter", "transaction")
|
||||||
,("g", "reload")
|
,("g", "reload")
|
||||||
,("q", "quit")
|
,("q", "quit")
|
||||||
@ -206,6 +211,7 @@ handleRegisterScreen st@AppState{
|
|||||||
Left err -> continue $ screenEnter d ES.screen{esState=err} st
|
Left err -> continue $ screenEnter d ES.screen{esState=err} st
|
||||||
|
|
||||||
Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st
|
Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st
|
||||||
|
Vty.EvKey (Vty.KChar 'R') [] -> continue $ reload j d $ stToggleReal st
|
||||||
|
|
||||||
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st
|
Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ where
|
|||||||
|
|
||||||
-- import Lens.Micro ((^.))
|
-- import Lens.Micro ((^.))
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
-- import Data.List
|
import Data.List
|
||||||
-- import Data.List.Split (splitOn)
|
-- import Data.List.Split (splitOn)
|
||||||
-- import Data.Ord
|
-- import Data.Ord
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
@ -22,7 +22,7 @@ import Graphics.Vty as Vty
|
|||||||
-- import Safe (headDef, lastDef)
|
-- import Safe (headDef, lastDef)
|
||||||
import Brick
|
import Brick
|
||||||
import Brick.Widgets.List (listMoveTo)
|
import Brick.Widgets.List (listMoveTo)
|
||||||
-- import Brick.Widgets.Border
|
import Brick.Widgets.Border (borderAttr)
|
||||||
-- import Brick.Widgets.Border.Style
|
-- import Brick.Widgets.Border.Style
|
||||||
-- import Brick.Widgets.Center
|
-- import Brick.Widgets.Center
|
||||||
-- import Text.Printf
|
-- import Text.Printf
|
||||||
@ -43,12 +43,22 @@ screen = TransactionScreen{
|
|||||||
}
|
}
|
||||||
|
|
||||||
initTransactionScreen :: Day -> AppState -> AppState
|
initTransactionScreen :: Day -> AppState -> AppState
|
||||||
initTransactionScreen _d st@AppState{aopts=_opts, ajournal=_j, aScreen=_s@TransactionScreen{tsState=_}} = st
|
initTransactionScreen d st@AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||||
|
,ajournal=_j
|
||||||
|
,aScreen=s@TransactionScreen{tsState=((n,t),nts,a)}} =
|
||||||
|
st{aScreen=s{tsState=((n, t'),nts,a)}}
|
||||||
|
where
|
||||||
|
-- re-filter the postings, eg because real/virtual was toggled.
|
||||||
|
-- get the original transaction from the list passed from the register screen.
|
||||||
|
t' = case lookup n nts of
|
||||||
|
Just torig -> filterTransactionPostings (queryFromOpts d ropts) torig
|
||||||
|
Nothing -> t -- shouldn't happen
|
||||||
|
|
||||||
initTransactionScreen _ _ = error "init function called with wrong screen type, should not happen"
|
initTransactionScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||||
|
|
||||||
drawTransactionScreen :: AppState -> [Widget]
|
drawTransactionScreen :: AppState -> [Widget]
|
||||||
drawTransactionScreen AppState{ -- aopts=_uopts@UIOpts{cliopts_=_copts@CliOpts{reportopts_=_ropts@ReportOpts{query_=querystr}}},
|
drawTransactionScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||||
aScreen=TransactionScreen{tsState=((i,t),nts,acct)}} = [ui]
|
,aScreen=TransactionScreen{tsState=((i,t),nts,acct)}} = [ui]
|
||||||
where
|
where
|
||||||
-- datedesc = show (tdate t) ++ " " ++ tdescription t
|
-- datedesc = show (tdate t) ++ " " ++ tdescription t
|
||||||
toplabel =
|
toplabel =
|
||||||
@ -59,9 +69,18 @@ drawTransactionScreen AppState{ -- aopts=_uopts@UIOpts{cliopts_=_copts@CliOpts{r
|
|||||||
<+> str " ("
|
<+> str " ("
|
||||||
<+> withAttr ("border" <> "bold") (str $ show i)
|
<+> withAttr ("border" <> "bold") (str $ show i)
|
||||||
<+> str (" of "++show (length nts)++" in "++T.unpack acct++")")
|
<+> str (" of "++show (length nts)++" in "++T.unpack acct++")")
|
||||||
|
<+> togglefilters
|
||||||
|
togglefilters =
|
||||||
|
case concat [
|
||||||
|
if cleared_ ropts then ["cleared"] else []
|
||||||
|
,if real_ ropts then ["real"] else []
|
||||||
|
] of
|
||||||
|
[] -> str ""
|
||||||
|
fs -> withAttr (borderAttr <> "query") (str $ " " ++ intercalate ", " fs) <+> str " postings"
|
||||||
bottomlabel = borderKeysStr [
|
bottomlabel = borderKeysStr [
|
||||||
("left", "back")
|
("left", "back")
|
||||||
,("up/down", "prev/next")
|
,("up/down", "prev/next")
|
||||||
|
,("R", "real?")
|
||||||
,("g", "reload")
|
,("g", "reload")
|
||||||
,("q", "quit")
|
,("q", "quit")
|
||||||
]
|
]
|
||||||
@ -114,6 +133,10 @@ handleTransactionScreen st@AppState{
|
|||||||
|
|
||||||
-- Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st
|
-- Vty.EvKey (Vty.KChar 'C') [] -> continue $ reload j d $ stToggleCleared st
|
||||||
|
|
||||||
|
Vty.EvKey (Vty.KChar 'R') [] ->
|
||||||
|
-- just show/hide the real postings in this transaction, don't bother updating parent screens
|
||||||
|
continue $ reload j d $ stToggleReal st
|
||||||
|
|
||||||
Vty.EvKey (Vty.KUp) [] -> continue $ reload j d st{aScreen=s{tsState=((iprev,tprev),nts,acct)}}
|
Vty.EvKey (Vty.KUp) [] -> continue $ reload j d st{aScreen=s{tsState=((iprev,tprev),nts,acct)}}
|
||||||
Vty.EvKey (Vty.KDown) [] -> continue $ reload j d st{aScreen=s{tsState=((inext,tnext),nts,acct)}}
|
Vty.EvKey (Vty.KDown) [] -> continue $ reload j d st{aScreen=s{tsState=((inext,tnext),nts,acct)}}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ module Hledger.UI.UIUtils (
|
|||||||
,borderKeysStr
|
,borderKeysStr
|
||||||
--
|
--
|
||||||
,stToggleCleared
|
,stToggleCleared
|
||||||
|
,stToggleFlat
|
||||||
|
,stToggleReal
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Lens.Micro ((^.))
|
import Lens.Micro ((^.))
|
||||||
@ -47,6 +49,23 @@ stToggleCleared st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts
|
|||||||
toggleCleared :: ReportOpts -> ReportOpts
|
toggleCleared :: ReportOpts -> ReportOpts
|
||||||
toggleCleared ropts = ropts{cleared_=not $ cleared_ ropts}
|
toggleCleared ropts = ropts{cleared_=not $ cleared_ ropts}
|
||||||
|
|
||||||
|
stToggleFlat :: AppState -> AppState
|
||||||
|
stToggleFlat st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
||||||
|
st{aopts=uopts{cliopts_=copts{reportopts_=toggleFlatMode ropts}}}
|
||||||
|
|
||||||
|
-- | Toggle between flat and tree mode. If in the third "default" mode, go to flat mode.
|
||||||
|
toggleFlatMode :: ReportOpts -> ReportOpts
|
||||||
|
toggleFlatMode ropts@ReportOpts{accountlistmode_=ALFlat} = ropts{accountlistmode_=ALTree}
|
||||||
|
toggleFlatMode ropts = ropts{accountlistmode_=ALFlat}
|
||||||
|
|
||||||
|
stToggleReal :: AppState -> AppState
|
||||||
|
stToggleReal st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
||||||
|
st{aopts=uopts{cliopts_=copts{reportopts_=toggleReal ropts}}}
|
||||||
|
|
||||||
|
-- | Toggle between showing all and showing only real (non-virtual) items.
|
||||||
|
toggleReal :: ReportOpts -> ReportOpts
|
||||||
|
toggleReal ropts = ropts{real_=not $ real_ ropts}
|
||||||
|
|
||||||
-- | Regenerate the content for the current and previous screens, from a new journal and current date.
|
-- | Regenerate the content for the current and previous screens, from a new journal and current date.
|
||||||
reload :: Journal -> Day -> AppState -> AppState
|
reload :: Journal -> Day -> AppState -> AppState
|
||||||
reload j d st@AppState{aScreen=s,aPrevScreens=ss} =
|
reload j d st@AppState{aScreen=s,aPrevScreens=ss} =
|
||||||
|
Loading…
Reference in New Issue
Block a user