mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-07 21:15:19 +03:00
lib,ui: Make sure ReportSpec is updated when updating ReportOpts.
This commit is contained in:
parent
3caf82c003
commit
74ce7be556
@ -18,6 +18,7 @@ module Hledger.Reports.ReportOptions (
|
||||
rawOptsToReportOpts,
|
||||
defreportspec,
|
||||
reportOptsToSpec,
|
||||
updateReportSpecFromOpts,
|
||||
rawOptsToReportSpec,
|
||||
flat_,
|
||||
tree_,
|
||||
@ -244,6 +245,10 @@ reportOptsToSpec day ropts = do
|
||||
, rsQueryOpts = queryopts
|
||||
}
|
||||
|
||||
-- | Regenerate a ReportSpec after updating ReportOpts.
|
||||
updateReportSpecFromOpts :: (ReportOpts -> ReportOpts) -> ReportSpec -> Either String ReportSpec
|
||||
updateReportSpecFromOpts f rspec = reportOptsToSpec (rsToday rspec) . f $ rsOpts rspec
|
||||
|
||||
-- | Generate a ReportSpec from RawOpts and the current date.
|
||||
rawOptsToReportSpec :: RawOpts -> IO ReportSpec
|
||||
rawOptsToReportSpec rawopts = do
|
||||
|
@ -53,14 +53,16 @@ uiShowStatus copts ss =
|
||||
showstatus Unmarked = "unmarked"
|
||||
|
||||
reportSpecToggleStatusSomehow :: Status -> CliOpts -> ReportSpec -> ReportSpec
|
||||
reportSpecToggleStatusSomehow s copts rspec = rspec{rsOpts=ropts}
|
||||
reportSpecToggleStatusSomehow s copts =
|
||||
either (error "reportSpecToggleStatusSomehow: updating Status should not result in an error") id -- PARTIAL:
|
||||
. updateReportSpecFromOpts update
|
||||
where
|
||||
ropts = case maybeposintopt "status-toggles" $ rawopts_ copts of
|
||||
Just 2 -> reportOptsToggleStatus2 s ropts
|
||||
Just 3 -> reportOptsToggleStatus3 s ropts
|
||||
-- Just 4 -> reportOptsToggleStatus4 s ropts
|
||||
-- Just 5 -> reportOptsToggleStatus5 s ropts
|
||||
_ -> reportOptsToggleStatus1 s ropts
|
||||
update = case maybeposintopt "status-toggles" $ rawopts_ copts of
|
||||
Just 2 -> reportOptsToggleStatus2 s
|
||||
Just 3 -> reportOptsToggleStatus3 s
|
||||
-- Just 4 -> reportOptsToggleStatus4 s
|
||||
-- Just 5 -> reportOptsToggleStatus5 s
|
||||
_ -> reportOptsToggleStatus1 s
|
||||
|
||||
-- 1 UPC toggles only X/all
|
||||
reportOptsToggleStatus1 s ropts@ReportOpts{statuses_=ss}
|
||||
@ -186,10 +188,11 @@ toggleForecast d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec
|
||||
|
||||
-- | Toggle between showing all and showing only real (non-virtual) items.
|
||||
toggleReal :: UIState -> UIState
|
||||
toggleReal ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=toggleReal ropts}}}}
|
||||
toggleReal ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}
|
||||
where
|
||||
toggleReal ropts = ropts{real_=not $ real_ ropts}
|
||||
update = either (error "toggleReal: updating Real should not result in an error") id -- PARTIAL:
|
||||
. updateReportSpecFromOpts (\ropts -> ropts{real_=not $ real_ ropts})
|
||||
|
||||
-- | Toggle the ignoring of balance assertions.
|
||||
toggleIgnoreBalanceAssertions :: UIState -> UIState
|
||||
@ -198,52 +201,53 @@ toggleIgnoreBalanceAssertions ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOp
|
||||
|
||||
-- | Step through larger report periods, up to all.
|
||||
growReportPeriod :: Day -> UIState -> UIState
|
||||
growReportPeriod _d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=periodGrow $ period_ ropts}}}}}
|
||||
growReportPeriod _d = updateReportPeriod periodGrow
|
||||
|
||||
-- | Step through smaller report periods, down to a day.
|
||||
shrinkReportPeriod :: Day -> UIState -> UIState
|
||||
shrinkReportPeriod d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=periodShrink d $ period_ ropts}}}}}
|
||||
shrinkReportPeriod d = updateReportPeriod (periodShrink d)
|
||||
|
||||
-- | Step the report start/end dates to the next period of same duration,
|
||||
-- remaining inside the given enclosing span.
|
||||
nextReportPeriod :: DateSpan -> UIState -> UIState
|
||||
nextReportPeriod enclosingspan ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts@ReportOpts{period_=p}}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=periodNextIn enclosingspan p}}}}}
|
||||
nextReportPeriod enclosingspan = updateReportPeriod (periodNextIn enclosingspan)
|
||||
|
||||
-- | Step the report start/end dates to the next period of same duration,
|
||||
-- remaining inside the given enclosing span.
|
||||
previousReportPeriod :: DateSpan -> UIState -> UIState
|
||||
previousReportPeriod enclosingspan ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts@ReportOpts{period_=p}}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=periodPreviousIn enclosingspan p}}}}}
|
||||
previousReportPeriod enclosingspan = updateReportPeriod (periodPreviousIn enclosingspan)
|
||||
|
||||
-- | If a standard report period is set, step it forward/backward if needed so that
|
||||
-- it encloses the given date.
|
||||
moveReportPeriodToDate :: Day -> UIState -> UIState
|
||||
moveReportPeriodToDate d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts@ReportOpts{period_=p}}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=periodMoveTo d p}}}}}
|
||||
moveReportPeriodToDate d = updateReportPeriod (periodMoveTo d)
|
||||
|
||||
-- | Get the report period.
|
||||
reportPeriod :: UIState -> Period
|
||||
reportPeriod UIState{aopts=UIOpts{cliopts_=CliOpts{reportspec_=ReportSpec{rsOpts=ReportOpts{period_=p}}}}} =
|
||||
p
|
||||
reportPeriod = period_ . rsOpts . reportspec_ . cliopts_ . aopts
|
||||
|
||||
-- | Set the report period.
|
||||
setReportPeriod :: Period -> UIState -> UIState
|
||||
setReportPeriod p ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{period_=p}}}}}
|
||||
setReportPeriod p = updateReportPeriod (const p)
|
||||
|
||||
-- | Clear any report period limits.
|
||||
resetReportPeriod :: UIState -> UIState
|
||||
resetReportPeriod = setReportPeriod PeriodAll
|
||||
|
||||
-- | Update report period by a applying a function.
|
||||
updateReportPeriod :: (Period -> Period) -> UIState -> UIState
|
||||
updateReportPeriod updatePeriod ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}
|
||||
where
|
||||
update = either (error "updateReportPeriod: updating period should not result in an error") id -- PARTIAL:
|
||||
. updateReportSpecFromOpts (\ropts -> ropts{period_=updatePeriod $ period_ ropts})
|
||||
|
||||
-- | Apply a new filter query.
|
||||
setFilter :: String -> UIState -> UIState
|
||||
setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=newrspec}}}
|
||||
setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}
|
||||
where
|
||||
newrspec = either (const rspec) id $ reportOptsToSpec (rsToday rspec) ropts{querystring_=querystring}
|
||||
update = either (const rspec) id . updateReportSpecFromOpts (\ropts -> ropts{querystring_=querystring})
|
||||
querystring = words'' prefixes $ T.pack s
|
||||
|
||||
-- | Reset some filters & toggles.
|
||||
@ -266,8 +270,7 @@ resetOpts :: UIState -> UIState
|
||||
resetOpts ui@UIState{astartupopts} = ui{aopts=astartupopts}
|
||||
|
||||
resetDepth :: UIState -> UIState
|
||||
resetDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{depth_=Nothing}}}}}
|
||||
resetDepth = updateReportDepth (const Nothing)
|
||||
|
||||
-- | Get the maximum account depth in the current journal.
|
||||
maxDepth :: UIState -> Int
|
||||
@ -276,8 +279,7 @@ maxDepth UIState{ajournal=j} = maximum $ map accountNameLevel $ journalAccountNa
|
||||
-- | Decrement the current depth limit towards 0. If there was no depth limit,
|
||||
-- set it to one less than the maximum account depth.
|
||||
decDepth :: UIState -> UIState
|
||||
decDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts@ReportOpts{..}}}}}
|
||||
= ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{depth_=dec depth_}}}}}
|
||||
decDepth ui = updateReportDepth dec ui
|
||||
where
|
||||
dec (Just d) = Just $ max 0 (d-1)
|
||||
dec Nothing = Just $ maxDepth ui - 1
|
||||
@ -285,28 +287,29 @@ decDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@
|
||||
-- | Increment the current depth limit. If this makes it equal to the
|
||||
-- the maximum account depth, remove the depth limit.
|
||||
incDepth :: UIState -> UIState
|
||||
incDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts@ReportOpts{..}}}}}
|
||||
= ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{depth_=inc depth_}}}}}
|
||||
where
|
||||
inc (Just d) | d < (maxDepth ui - 1) = Just $ d+1
|
||||
inc _ = Nothing
|
||||
incDepth = updateReportDepth (fmap succ)
|
||||
|
||||
-- | Set the current depth limit to the specified depth, or remove the depth limit.
|
||||
-- Also remove the depth limit if the specified depth is greater than the current
|
||||
-- maximum account depth. If the specified depth is negative, reset the depth limit
|
||||
-- to whatever was specified at uiartup.
|
||||
setDepth :: Maybe Int -> UIState -> UIState
|
||||
setDepth mdepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}}
|
||||
= ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{depth_=mdepth'}}}}}
|
||||
where
|
||||
mdepth' = case mdepth of
|
||||
Nothing -> Nothing
|
||||
Just d | d < 0 -> depth_ ropts
|
||||
| d >= maxDepth ui -> Nothing
|
||||
| otherwise -> mdepth
|
||||
setDepth mdepth = updateReportDepth (const mdepth)
|
||||
|
||||
getDepth :: UIState -> Maybe Int
|
||||
getDepth UIState{aopts=UIOpts{cliopts_=CliOpts{reportspec_=rspec}}} = depth_ $ rsOpts rspec
|
||||
getDepth = depth_ . rsOpts . reportspec_ . cliopts_ . aopts
|
||||
|
||||
-- | Update report depth by a applying a function. If asked to set a depth less
|
||||
-- than zero, it will leave it unchanged.
|
||||
updateReportDepth :: (Maybe Int -> Maybe Int) -> UIState -> UIState
|
||||
updateReportDepth updateDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =
|
||||
ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}
|
||||
where
|
||||
update = either (error "updateReportDepth: updating depth should not result in an error") id -- PARTIAL:
|
||||
. updateReportSpecFromOpts (\ropts -> ropts{depth_=updateDepth (depth_ ropts) >>= clipDepth ropts})
|
||||
clipDepth ropts d | d < 0 = depth_ ropts
|
||||
| d >= maxDepth ui = Nothing
|
||||
| otherwise = Just d
|
||||
|
||||
-- | Open the minibuffer, setting its content to the current query with the cursor at the end.
|
||||
showMinibuffer :: UIState -> UIState
|
||||
|
Loading…
Reference in New Issue
Block a user