From a4cf2333126c4f28f6f0824d7e0843aafb7ceeb2 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sat, 13 Aug 2016 08:08:43 -0700 Subject: [PATCH] ui: keep next/previous period within the journal's date span --- hledger-lib/Hledger/Data/Period.hs | 22 ++++++++++++++++++++++ hledger-ui/Hledger/UI/AccountsScreen.hs | 5 +++-- hledger-ui/Hledger/UI/RegisterScreen.hs | 5 +++-- hledger-ui/Hledger/UI/UIState.hs | 14 +++++++------- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/hledger-lib/Hledger/Data/Period.hs b/hledger-lib/Hledger/Data/Period.hs index 45f126561..38ccfa46a 100644 --- a/hledger-lib/Hledger/Data/Period.hs +++ b/hledger-lib/Hledger/Data/Period.hs @@ -165,6 +165,28 @@ periodPrevious (QuarterPeriod y q) = QuarterPeriod y (q-1) periodPrevious (YearPeriod y) = YearPeriod (y-1) periodPrevious p = p +-- | Move a period to the following period of same duration, staying within enclosing dates. +periodNextIn :: DateSpan -> Period -> Period +periodNextIn (DateSpan _ (Just e)) p = + case mb of + Just b -> if b < e then p' else p + _ -> p + where + p' = periodNext p + mb = periodStart p' +periodNextIn _ p = periodNext p + +-- | Move a period to the preceding period of same duration, staying within enclosing dates. +periodPreviousIn :: DateSpan -> Period -> Period +periodPreviousIn (DateSpan (Just b) _) p = + case me of + Just e -> if e > b then p' else p + _ -> p + where + p' = periodPrevious p + me = periodEnd p' +periodPreviousIn _ p = periodPrevious p + -- | Enlarge a standard period to the next larger enclosing standard period, if there is one. -- Eg, a day becomes the enclosing week. -- A week becomes whichever month the week's thursday falls into. diff --git a/hledger-ui/Hledger/UI/AccountsScreen.hs b/hledger-ui/Hledger/UI/AccountsScreen.hs index fd9795003..6ee6b32dc 100644 --- a/hledger-ui/Hledger/UI/AccountsScreen.hs +++ b/hledger-ui/Hledger/UI/AccountsScreen.hs @@ -312,8 +312,8 @@ asHandle ui0@UIState{ EvKey (KChar 'R') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleReal ui) EvKey (KDown) [MShift] -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui EvKey (KUp) [MShift] -> continue $ regenerateScreens j d $ growReportPeriod d ui - EvKey (KRight) [MShift] -> continue $ regenerateScreens j d $ nextReportPeriod ui - EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod ui + EvKey (KRight) [MShift] -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui + EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod journalspan 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 @@ -344,6 +344,7 @@ asHandle ui0@UIState{ -- XXX better: scroll so selection is in middle of screen ? scrollTop = vScrollToBeginning $ viewportScroll AccountsViewport scrollTopRegister = vScrollToBeginning $ viewportScroll RegisterViewport + journalspan = journalDateSpan False j asHandle _ _ = error "event handler called with wrong screen type, should not happen" diff --git a/hledger-ui/Hledger/UI/RegisterScreen.hs b/hledger-ui/Hledger/UI/RegisterScreen.hs index 9ff8409fc..f5138ffba 100644 --- a/hledger-ui/Hledger/UI/RegisterScreen.hs +++ b/hledger-ui/Hledger/UI/RegisterScreen.hs @@ -282,8 +282,8 @@ rsHandle ui@UIState{ EvKey (KChar '/') [] -> (continue $ regenerateScreens j d $ showMinibuffer ui) EvKey (KDown) [MShift] -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui EvKey (KUp) [MShift] -> continue $ regenerateScreens j d $ growReportPeriod d ui - EvKey (KRight) [MShift] -> continue $ regenerateScreens j d $ nextReportPeriod ui - EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod ui + EvKey (KRight) [MShift] -> continue $ regenerateScreens j d $ nextReportPeriod journalspan ui + EvKey (KLeft) [MShift] -> continue $ regenerateScreens j d $ previousReportPeriod journalspan 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'] -> do @@ -310,5 +310,6 @@ rsHandle ui@UIState{ where -- Encourage a more stable scroll position when toggling list items (cf AccountsScreen.hs) scrollTop = vScrollToBeginning $ viewportScroll RegisterViewport + journalspan = journalDateSpan False j rsHandle _ _ = error "event handler called with wrong screen type, should not happen" diff --git a/hledger-ui/Hledger/UI/UIState.hs b/hledger-ui/Hledger/UI/UIState.hs index 6112833c2..0f23433cb 100644 --- a/hledger-ui/Hledger/UI/UIState.hs +++ b/hledger-ui/Hledger/UI/UIState.hs @@ -87,14 +87,14 @@ shrinkReportPeriod d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{report ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodShrink d $ period_ ropts}}}} -- | Step the report start/end dates to the next period of same duration. -nextReportPeriod :: UIState -> UIState -nextReportPeriod ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = - ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodNext p}}}} +nextReportPeriod :: DateSpan -> UIState -> UIState +nextReportPeriod journalspan ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = + ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodNextIn journalspan p}}}} -- | Step the report start/end dates to the next period of same duration. -previousReportPeriod :: UIState -> UIState -previousReportPeriod ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = - ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodPrevious p}}}} +previousReportPeriod :: DateSpan -> UIState -> UIState +previousReportPeriod journalspan ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = + ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodPreviousIn journalspan p}}}} -- | Set the report period. setReportPeriod :: Period -> UIState -> UIState @@ -115,7 +115,7 @@ resetFilter ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=rop ,clearedstatus_=Nothing ,real_=False ,query_="" - ,period_=PeriodAll + --,period_=PeriodAll }}}} resetDepth :: UIState -> UIState