imp: ui: at --debug=2, do lots of logging to debug.log
This commit is contained in:
		
							parent
							
								
									b7b09f991a
								
							
						
					
					
						commit
						67cd6be424
					
				| @ -54,7 +54,7 @@ asInit d reset ui@UIState{ | |||||||
|   aopts=UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}}, |   aopts=UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}}, | ||||||
|   ajournal=j, |   ajournal=j, | ||||||
|   aScreen=s@AccountsScreen{} |   aScreen=s@AccountsScreen{} | ||||||
|   } = |   } = dlogUiTrace "asInit 1" $ | ||||||
|   ui{aScreen=s & asList .~ newitems'} |   ui{aScreen=s & asList .~ newitems'} | ||||||
|    where |    where | ||||||
|     newitems = list AccountsList (V.fromList $ displayitems ++ blankitems) 1 |     newitems = list AccountsList (V.fromList $ displayitems ++ blankitems) 1 | ||||||
| @ -97,7 +97,7 @@ asInit d reset ui@UIState{ | |||||||
|     displayitems = map displayitem items |     displayitems = map displayitem items | ||||||
|     -- blanks added for scrolling control, cf RegisterScreen. |     -- blanks added for scrolling control, cf RegisterScreen. | ||||||
|     -- XXX Ugly. Changing to 0 helps when debugging. |     -- XXX Ugly. Changing to 0 helps when debugging. | ||||||
|     blankitems = replicate 100 |     blankitems = replicate uiNumBlankItems | ||||||
|       AccountsScreenItem{asItemIndentLevel        = 0 |       AccountsScreenItem{asItemIndentLevel        = 0 | ||||||
|                         ,asItemAccountName        = "" |                         ,asItemAccountName        = "" | ||||||
|                         ,asItemDisplayAccountName = "" |                         ,asItemDisplayAccountName = "" | ||||||
| @ -105,14 +105,14 @@ asInit d reset ui@UIState{ | |||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| asInit _ _ _ = error "init function called with wrong screen type, should not happen"  -- PARTIAL: | asInit _ _ _ = dlogUiTrace "asInit 2" $ errorWrongScreenType "init function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| asDraw :: UIState -> [Widget Name] | asDraw :: UIState -> [Widget Name] | ||||||
| asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | ||||||
|               ,ajournal=j |               ,ajournal=j | ||||||
|               ,aScreen=s@AccountsScreen{} |               ,aScreen=s@AccountsScreen{} | ||||||
|               ,aMode=mode |               ,aMode=mode | ||||||
|               } = |               } = dlogUiTrace "asDraw 1" $ | ||||||
|     case mode of |     case mode of | ||||||
|       Help       -> [helpDialog copts, maincontent] |       Help       -> [helpDialog copts, maincontent] | ||||||
|       -- Minibuffer e -> [minibuffer e, maincontent] |       -- Minibuffer e -> [minibuffer e, maincontent] | ||||||
| @ -203,7 +203,7 @@ asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | |||||||
|               ,("q", str "quit") |               ,("q", str "quit") | ||||||
|               ] |               ] | ||||||
| 
 | 
 | ||||||
| asDraw _ = error "draw function called with wrong screen type, should not happen"  -- PARTIAL: | asDraw _ =  dlogUiTrace "asDraw 2" $ errorWrongScreenType "draw function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| asDrawItem :: (Int,Int) -> Bool -> AccountsScreenItem -> Widget Name | asDrawItem :: (Int,Int) -> Bool -> AccountsScreenItem -> Widget Name | ||||||
| asDrawItem (acctwidth, balwidth) selected AccountsScreenItem{..} = | asDrawItem (acctwidth, balwidth) selected AccountsScreenItem{..} = | ||||||
| @ -227,7 +227,8 @@ asDrawItem (acctwidth, balwidth) selected AccountsScreenItem{..} = | |||||||
| 
 | 
 | ||||||
| asHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | asHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | ||||||
| asHandle ev = do | asHandle ev = do | ||||||
|   ui0 <- get |   ui0 <- get' | ||||||
|  |   dlogUiTraceM "asHandle 1" | ||||||
|   case ui0 of |   case ui0 of | ||||||
|     ui1@UIState{ |     ui1@UIState{ | ||||||
|       aScreen=scr@AccountsScreen{..} |       aScreen=scr@AccountsScreen{..} | ||||||
| @ -250,8 +251,8 @@ asHandle ev = do | |||||||
|       case mode of |       case mode of | ||||||
|         Minibuffer _ ed -> |         Minibuffer _ ed -> | ||||||
|           case ev of |           case ev of | ||||||
|             VtyEvent (EvKey KEsc   []) -> put $ closeMinibuffer ui |             VtyEvent (EvKey KEsc   []) -> put' $ closeMinibuffer ui | ||||||
|             VtyEvent (EvKey KEnter []) -> put $ regenerateScreens j d $ |             VtyEvent (EvKey KEnter []) -> put' $ regenerateScreens j d $ | ||||||
|                 case setFilter s $ closeMinibuffer ui of |                 case setFilter s $ closeMinibuffer ui of | ||||||
|                   Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui |                   Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui | ||||||
|                   Right ui' -> ui' |                   Right ui' -> ui' | ||||||
| @ -260,7 +261,7 @@ asHandle ev = do | |||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|             VtyEvent ev -> do |             VtyEvent ev -> do | ||||||
|               ed' <- nestEventM' ed $ handleEditorEvent (VtyEvent ev) |               ed' <- nestEventM' ed $ handleEditorEvent (VtyEvent ev) | ||||||
|               put ui{aMode=Minibuffer "filter" ed'} |               put' ui{aMode=Minibuffer "filter" ed'} | ||||||
|             AppEvent _  -> return () |             AppEvent _  -> return () | ||||||
|             MouseDown{} -> return () |             MouseDown{} -> return () | ||||||
|             MouseUp{}   -> return () |             MouseUp{}   -> return () | ||||||
| @ -276,36 +277,36 @@ asHandle ev = do | |||||||
|           case ev of |           case ev of | ||||||
|             VtyEvent (EvKey (KChar 'q') []) -> halt |             VtyEvent (EvKey (KChar 'q') []) -> halt | ||||||
|             -- EvKey (KChar 'l') [MCtrl] -> do |             -- EvKey (KChar 'l') [MCtrl] -> do | ||||||
|             VtyEvent (EvKey KEsc        []) -> put $ resetScreens d ui |             VtyEvent (EvKey KEsc        []) -> put' $ resetScreens d ui | ||||||
|             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put $ setMode Help ui |             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put' $ setMode Help ui | ||||||
|             -- XXX AppEvents currently handled only in Normal mode |             -- XXX AppEvents currently handled only in Normal mode | ||||||
|             -- XXX be sure we don't leave unconsumed events piling up |             -- XXX be sure we don't leave unconsumed events piling up | ||||||
|             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> |             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> | ||||||
|               put $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui |               put' $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui | ||||||
|               where |               where | ||||||
|                 p = reportPeriod ui |                 p = reportPeriod ui | ||||||
|             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> |             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> | ||||||
|               liftIO (uiReloadJournal copts d ui) >>= put |               liftIO (uiReloadJournal copts d ui) >>= put' | ||||||
|             VtyEvent (EvKey (KChar 'I') []) -> put $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) |             VtyEvent (EvKey (KChar 'I') []) -> put' $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) | ||||||
|             VtyEvent (EvKey (KChar 'a') []) -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'a') []) -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui | ||||||
|             VtyEvent (EvKey (KChar 'A') []) -> suspendAndResume $ void (runIadd (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'A') []) -> suspendAndResume $ void (runIadd (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui | ||||||
|             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor endPosition (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor endPosition (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui | ||||||
|             VtyEvent (EvKey (KChar 'B') []) -> put $ regenerateScreens j d $ toggleConversionOp ui |             VtyEvent (EvKey (KChar 'B') []) -> put' $ regenerateScreens j d $ toggleConversionOp ui | ||||||
|             VtyEvent (EvKey (KChar 'V') []) -> put $ regenerateScreens j d $ toggleValue ui |             VtyEvent (EvKey (KChar 'V') []) -> put' $ regenerateScreens j d $ toggleValue ui | ||||||
|             VtyEvent (EvKey (KChar '0') []) -> put $ regenerateScreens j d $ setDepth (Just 0) ui |             VtyEvent (EvKey (KChar '0') []) -> put' $ regenerateScreens j d $ setDepth (Just 0) ui | ||||||
|             VtyEvent (EvKey (KChar '1') []) -> put $ regenerateScreens j d $ setDepth (Just 1) ui |             VtyEvent (EvKey (KChar '1') []) -> put' $ regenerateScreens j d $ setDepth (Just 1) ui | ||||||
|             VtyEvent (EvKey (KChar '2') []) -> put $ regenerateScreens j d $ setDepth (Just 2) ui |             VtyEvent (EvKey (KChar '2') []) -> put' $ regenerateScreens j d $ setDepth (Just 2) ui | ||||||
|             VtyEvent (EvKey (KChar '3') []) -> put $ regenerateScreens j d $ setDepth (Just 3) ui |             VtyEvent (EvKey (KChar '3') []) -> put' $ regenerateScreens j d $ setDepth (Just 3) ui | ||||||
|             VtyEvent (EvKey (KChar '4') []) -> put $ regenerateScreens j d $ setDepth (Just 4) ui |             VtyEvent (EvKey (KChar '4') []) -> put' $ regenerateScreens j d $ setDepth (Just 4) ui | ||||||
|             VtyEvent (EvKey (KChar '5') []) -> put $ regenerateScreens j d $ setDepth (Just 5) ui |             VtyEvent (EvKey (KChar '5') []) -> put' $ regenerateScreens j d $ setDepth (Just 5) ui | ||||||
|             VtyEvent (EvKey (KChar '6') []) -> put $ regenerateScreens j d $ setDepth (Just 6) ui |             VtyEvent (EvKey (KChar '6') []) -> put' $ regenerateScreens j d $ setDepth (Just 6) ui | ||||||
|             VtyEvent (EvKey (KChar '7') []) -> put $ regenerateScreens j d $ setDepth (Just 7) ui |             VtyEvent (EvKey (KChar '7') []) -> put' $ regenerateScreens j d $ setDepth (Just 7) ui | ||||||
|             VtyEvent (EvKey (KChar '8') []) -> put $ regenerateScreens j d $ setDepth (Just 8) ui |             VtyEvent (EvKey (KChar '8') []) -> put' $ regenerateScreens j d $ setDepth (Just 8) ui | ||||||
|             VtyEvent (EvKey (KChar '9') []) -> put $ regenerateScreens j d $ setDepth (Just 9) ui |             VtyEvent (EvKey (KChar '9') []) -> put' $ regenerateScreens j d $ setDepth (Just 9) ui | ||||||
|             VtyEvent (EvKey (KChar '-') []) -> put $ regenerateScreens j d $ decDepth ui |             VtyEvent (EvKey (KChar '-') []) -> put' $ regenerateScreens j d $ decDepth ui | ||||||
|             VtyEvent (EvKey (KChar '_') []) -> put $ regenerateScreens j d $ decDepth ui |             VtyEvent (EvKey (KChar '_') []) -> put' $ regenerateScreens j d $ decDepth ui | ||||||
|             VtyEvent (EvKey (KChar c)   []) | c `elem` ['+','='] -> put $ regenerateScreens j d $ incDepth ui |             VtyEvent (EvKey (KChar c)   []) | c `elem` ['+','='] -> put' $ regenerateScreens j d $ incDepth ui | ||||||
|             VtyEvent (EvKey (KChar 'T') []) -> put $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui |             VtyEvent (EvKey (KChar 'T') []) -> put' $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui | ||||||
| 
 | 
 | ||||||
|             -- display mode/query toggles |             -- display mode/query toggles | ||||||
|             VtyEvent (EvKey (KChar 'H') []) -> modify (regenerateScreens j d . toggleHistorical) >> asCenterAndContinue |             VtyEvent (EvKey (KChar 'H') []) -> modify (regenerateScreens j d . toggleHistorical) >> asCenterAndContinue | ||||||
| @ -317,13 +318,13 @@ asHandle ev = do | |||||||
|             VtyEvent (EvKey (KChar 'C') []) -> modify (regenerateScreens j d . toggleCleared) >> asCenterAndContinue |             VtyEvent (EvKey (KChar 'C') []) -> modify (regenerateScreens j d . toggleCleared) >> asCenterAndContinue | ||||||
|             VtyEvent (EvKey (KChar 'F') []) -> modify (regenerateScreens j d . toggleForecast d) |             VtyEvent (EvKey (KChar 'F') []) -> modify (regenerateScreens j d . toggleForecast d) | ||||||
| 
 | 
 | ||||||
|             VtyEvent (EvKey (KDown)     [MShift]) -> put $ regenerateScreens j d $ shrinkReportPeriod d ui |             VtyEvent (EvKey (KDown)     [MShift]) -> put' $ regenerateScreens j d $ shrinkReportPeriod d ui | ||||||
|             VtyEvent (EvKey (KUp)       [MShift]) -> put $ regenerateScreens j d $ growReportPeriod d ui |             VtyEvent (EvKey (KUp)       [MShift]) -> put' $ regenerateScreens j d $ growReportPeriod d ui | ||||||
|             VtyEvent (EvKey (KRight)    [MShift]) -> put $ regenerateScreens j d $ nextReportPeriod journalspan ui |             VtyEvent (EvKey (KRight)    [MShift]) -> put' $ regenerateScreens j d $ nextReportPeriod journalspan ui | ||||||
|             VtyEvent (EvKey (KLeft)     [MShift]) -> put $ regenerateScreens j d $ previousReportPeriod journalspan ui |             VtyEvent (EvKey (KLeft)     [MShift]) -> put' $ regenerateScreens j d $ previousReportPeriod journalspan ui | ||||||
|             VtyEvent (EvKey (KChar '/') []) -> put $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui |             VtyEvent (EvKey (KChar '/') []) -> put' $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui | ||||||
|             VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (put $ regenerateScreens j d $ resetFilter ui) |             VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (put' $ regenerateScreens j d $ resetFilter ui) | ||||||
|             VtyEvent e | e `elem` moveLeftEvents -> put $ popScreen ui |             VtyEvent e | e `elem` moveLeftEvents -> put' $ popScreen ui | ||||||
|             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw |             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw | ||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
| 
 | 
 | ||||||
| @ -335,7 +336,7 @@ asHandle ev = do | |||||||
|             -- MouseDown is sometimes duplicated, https://github.com/jtdaugherty/brick/issues/347 |             -- MouseDown is sometimes duplicated, https://github.com/jtdaugherty/brick/issues/347 | ||||||
|             -- just use it to move the selection |             -- just use it to move the selection | ||||||
|             MouseDown _n BLeft _mods Location{loc=(_x,y)} | not $ (=="") clickedacct -> do |             MouseDown _n BLeft _mods Location{loc=(_x,y)} | not $ (=="") clickedacct -> do | ||||||
|               put ui{aScreen=scr}  -- XXX does this do anything ? |               put' ui{aScreen=scr}  -- XXX does this do anything ? | ||||||
|               where clickedacct = maybe "" asItemAccountName $ listElements _asList !? y |               where clickedacct = maybe "" asItemAccountName $ listElements _asList !? y | ||||||
|             -- and on MouseUp, enter the subscreen |             -- and on MouseUp, enter the subscreen | ||||||
|             MouseUp _n (Just BLeft) Location{loc=(_x,y)} | not $ (=="") clickedacct -> do |             MouseUp _n (Just BLeft) Location{loc=(_x,y)} | not $ (=="") clickedacct -> do | ||||||
| @ -352,7 +353,7 @@ asHandle ev = do | |||||||
|             MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do |             MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do | ||||||
|               let scrollamt = if btn==BScrollUp then -1 else 1 |               let scrollamt = if btn==BScrollUp then -1 else 1 | ||||||
|               list' <- nestEventM' _asList $ listScrollPushingSelection name (asListSize _asList) scrollamt |               list' <- nestEventM' _asList $ listScrollPushingSelection name (asListSize _asList) scrollamt | ||||||
|               put ui{aScreen=scr{_asList=list'}} |               put' ui{aScreen=scr{_asList=list'}} | ||||||
| 
 | 
 | ||||||
|             -- if page down or end leads to a blank padding item, stop at last non-blank |             -- if page down or end leads to a blank padding item, stop at last non-blank | ||||||
|             VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do |             VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do | ||||||
| @ -361,20 +362,20 @@ asHandle ev = do | |||||||
|               then do |               then do | ||||||
|                 let list' = listMoveTo lastnonblankidx list |                 let list' = listMoveTo lastnonblankidx list | ||||||
|                 scrollSelectionToMiddle list' |                 scrollSelectionToMiddle list' | ||||||
|                 put ui{aScreen=scr{_asList=list'}} |                 put' ui{aScreen=scr{_asList=list'}} | ||||||
|               else |               else | ||||||
|                 put ui{aScreen=scr{_asList=list}} |                 put' ui{aScreen=scr{_asList=list}} | ||||||
| 
 | 
 | ||||||
|             -- fall through to the list's event handler (handles up/down) |             -- fall through to the list's event handler (handles up/down) | ||||||
|             VtyEvent ev -> do |             VtyEvent ev -> do | ||||||
|               list' <- nestEventM' _asList $ handleListEvent (normaliseMovementKeys ev) |               list' <- nestEventM' _asList $ handleListEvent (normaliseMovementKeys ev) | ||||||
|               put $ ui{aScreen=scr & asList .~ list' & asSelectedAccount .~ selacct } |               put' $ ui{aScreen=scr & asList .~ list' & asSelectedAccount .~ selacct } | ||||||
| 
 | 
 | ||||||
|             MouseDown{} -> put ui |             MouseDown{} -> put ui | ||||||
|             MouseUp{}   -> put ui |             MouseUp{}   -> put ui | ||||||
|             AppEvent _  -> put ui |             AppEvent _  -> put ui | ||||||
| 
 | 
 | ||||||
|     _ -> errorWrongScreenType |     _ -> dlogUiTraceM "asHandle 2" >> errorWrongScreenType "event handler" | ||||||
| 
 | 
 | ||||||
| asEnterRegister d selacct ui = do | asEnterRegister d selacct ui = do | ||||||
|   rsCenterAndContinue $ |   rsCenterAndContinue $ | ||||||
| @ -393,7 +394,7 @@ isBlankElement mel = ((asItemAccountName . snd) <$> mel) == Just "" | |||||||
| 
 | 
 | ||||||
| asCenterAndContinue :: EventM Name UIState () | asCenterAndContinue :: EventM Name UIState () | ||||||
| asCenterAndContinue = do | asCenterAndContinue = do | ||||||
|   ui <- get |   ui <- get' | ||||||
|   scrollSelectionToMiddle (_asList $ aScreen ui) |   scrollSelectionToMiddle (_asList $ aScreen ui) | ||||||
| 
 | 
 | ||||||
| asListSize = V.length . V.takeWhile ((/="").asItemAccountName) . listElements | asListSize = V.length . V.takeWhile ((/="").asItemAccountName) . listElements | ||||||
|  | |||||||
| @ -114,7 +114,7 @@ esHandle ev = do | |||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|             _ -> return () |             _ -> return () | ||||||
| 
 | 
 | ||||||
|     _ -> errorWrongScreenType |     _ -> errorWrongScreenType "event handler" | ||||||
| 
 | 
 | ||||||
| -- | Parse the file name, line and column number from a hledger parse error message, if possible. | -- | Parse the file name, line and column number from a hledger parse error message, if possible. | ||||||
| -- Temporary, we should keep the original parse error location. XXX | -- Temporary, we should keep the original parse error location. XXX | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ import Hledger.UI.UITypes | |||||||
| import Hledger.UI.Theme | import Hledger.UI.Theme | ||||||
| import Hledger.UI.AccountsScreen | import Hledger.UI.AccountsScreen | ||||||
| import Hledger.UI.RegisterScreen | import Hledger.UI.RegisterScreen | ||||||
|  | import Hledger.UI.UIUtils (dlogUiTrace) | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| @ -62,7 +63,8 @@ main = do | |||||||
|     _                                         -> withJournalDo copts' (runBrickUi opts) |     _                                         -> withJournalDo copts' (runBrickUi opts) | ||||||
| 
 | 
 | ||||||
| runBrickUi :: UIOpts -> Journal -> IO () | runBrickUi :: UIOpts -> Journal -> IO () | ||||||
| runBrickUi uopts@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=_iopts,reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}} j = do | runBrickUi uopts@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=_iopts,reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}} j = | ||||||
|  |   dlogUiTrace "========= runBrickUi" $ do | ||||||
|   let |   let | ||||||
|     today = copts^.rsDay |     today = copts^.rsDay | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ module Hledger.UI.RegisterScreen | |||||||
|  (registerScreen |  (registerScreen | ||||||
|  ,rsHandle |  ,rsHandle | ||||||
|  ,rsSetAccount |  ,rsSetAccount | ||||||
|  ,rsCenterAndContinue |  ,rsCenterSelection | ||||||
|  ) |  ) | ||||||
| where | where | ||||||
| 
 | 
 | ||||||
| @ -59,6 +59,7 @@ rsSetAccount _ _ scr = scr | |||||||
| 
 | 
 | ||||||
| rsInit :: Day -> Bool -> UIState -> UIState | rsInit :: Day -> Bool -> UIState -> UIState | ||||||
| rsInit d reset ui@UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}}, ajournal=j, aScreen=s@RegisterScreen{..}} = | rsInit d reset ui@UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}}, ajournal=j, aScreen=s@RegisterScreen{..}} = | ||||||
|  |   dlogUiTrace "rsInit 1" $ | ||||||
|   ui{aScreen=s{rsList=newitems'}} |   ui{aScreen=s{rsList=newitems'}} | ||||||
|   where |   where | ||||||
|     -- gather arguments and queries |     -- gather arguments and queries | ||||||
| @ -101,7 +102,7 @@ rsInit d reset ui@UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec | |||||||
|             where showamt = showMixedAmountB oneLine{displayMaxWidth=Just 32} |             where showamt = showMixedAmountB oneLine{displayMaxWidth=Just 32} | ||||||
|     -- blank items are added to allow more control of scroll position; we won't allow movement over these. |     -- blank items are added to allow more control of scroll position; we won't allow movement over these. | ||||||
|     -- XXX Ugly. Changing to 0 helps when debugging. |     -- XXX Ugly. Changing to 0 helps when debugging. | ||||||
|     blankitems = replicate 100  -- "100 ought to be enough for anyone" |     blankitems = replicate uiNumBlankItems | ||||||
|           RegisterScreenItem{rsItemDate          = "" |           RegisterScreenItem{rsItemDate          = "" | ||||||
|                             ,rsItemStatus        = Unmarked |                             ,rsItemStatus        = Unmarked | ||||||
|                             ,rsItemDescription   = "" |                             ,rsItemDescription   = "" | ||||||
| @ -136,13 +137,13 @@ rsInit d reset ui@UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec | |||||||
|                 ts = map rsItemTransaction displayitems |                 ts = map rsItemTransaction displayitems | ||||||
|         endidx = max 0 $ length displayitems - 1 |         endidx = max 0 $ length displayitems - 1 | ||||||
| 
 | 
 | ||||||
| rsInit _ _ _ = error "init function called with wrong screen type, should not happen"  -- PARTIAL: | rsInit _ _ _ = dlogUiTrace "rsInit 2" $ errorWrongScreenType "init function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| rsDraw :: UIState -> [Widget Name] | rsDraw :: UIState -> [Widget Name] | ||||||
| rsDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | rsDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | ||||||
|               ,aScreen=RegisterScreen{..} |               ,aScreen=RegisterScreen{..} | ||||||
|               ,aMode=mode |               ,aMode=mode | ||||||
|               } = |               } = dlogUiTrace "rsDraw 1" $ | ||||||
|   case mode of |   case mode of | ||||||
|     Help       -> [helpDialog copts, maincontent] |     Help       -> [helpDialog copts, maincontent] | ||||||
|     -- Minibuffer e -> [minibuffer e, maincontent] |     -- Minibuffer e -> [minibuffer e, maincontent] | ||||||
| @ -250,7 +251,7 @@ rsDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}} | |||||||
| --               ,("q", "quit") | --               ,("q", "quit") | ||||||
|               ] |               ] | ||||||
| 
 | 
 | ||||||
| rsDraw _ = error "draw function called with wrong screen type, should not happen"  -- PARTIAL: | rsDraw _ = dlogUiTrace "rsDraw 2" $ errorWrongScreenType "draw function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| rsDrawItem :: (Int,Int,Int,Int,Int) -> Bool -> RegisterScreenItem -> Widget Name | rsDrawItem :: (Int,Int,Int,Int,Int) -> Bool -> RegisterScreenItem -> Widget Name | ||||||
| rsDrawItem (datewidth,descwidth,acctswidth,changewidth,balwidth) selected RegisterScreenItem{..} = | rsDrawItem (datewidth,descwidth,acctswidth,changewidth,balwidth) selected RegisterScreenItem{..} = | ||||||
| @ -279,7 +280,8 @@ rsDrawItem (datewidth,descwidth,acctswidth,changewidth,balwidth) selected Regist | |||||||
| 
 | 
 | ||||||
| rsHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | rsHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | ||||||
| rsHandle ev = do | rsHandle ev = do | ||||||
|   ui0 <- get |   ui0 <- get' | ||||||
|  |   dlogUiTraceM "rsHandle 1" | ||||||
|   case ui0 of |   case ui0 of | ||||||
|     ui@UIState{ |     ui@UIState{ | ||||||
|       aScreen=s@RegisterScreen{..} |       aScreen=s@RegisterScreen{..} | ||||||
| @ -297,17 +299,17 @@ rsHandle ev = do | |||||||
|         Minibuffer _ ed -> |         Minibuffer _ ed -> | ||||||
|           case ev of |           case ev of | ||||||
|             VtyEvent (EvKey KEsc   []) -> modify closeMinibuffer |             VtyEvent (EvKey KEsc   []) -> modify closeMinibuffer | ||||||
|             VtyEvent (EvKey KEnter []) -> put $ regenerateScreens j d $ |             VtyEvent (EvKey KEnter []) -> put' $ regenerateScreens j d $ | ||||||
|                 case setFilter s $ closeMinibuffer ui of |                 case setFilter s $ closeMinibuffer ui of | ||||||
|                   Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui |                   Left bad -> showMinibuffer "Cannot compile regular expression" (Just bad) ui | ||||||
|                   Right ui' -> ui' |                   Right ui' -> ui' | ||||||
|               where s = chomp . unlines . map strip $ getEditContents ed |               where s = chomp . unlines . map strip $ getEditContents ed | ||||||
|             -- VtyEvent (EvKey (KChar '/') []) -> put $ regenerateScreens j d $ showMinibuffer ui |             -- VtyEvent (EvKey (KChar '/') []) -> put' $ regenerateScreens j d $ showMinibuffer ui | ||||||
|             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw |             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw | ||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|             VtyEvent ev -> do |             VtyEvent ev -> do | ||||||
|               ed' <- nestEventM' ed $ handleEditorEvent (VtyEvent ev) |               ed' <- nestEventM' ed $ handleEditorEvent (VtyEvent ev) | ||||||
|               put ui{aMode=Minibuffer "filter" ed'} |               put' ui{aMode=Minibuffer "filter" ed'} | ||||||
|             AppEvent _  -> return () |             AppEvent _  -> return () | ||||||
|             MouseDown{} -> return () |             MouseDown{} -> return () | ||||||
|             MouseUp{}   -> return () |             MouseUp{}   -> return () | ||||||
| @ -322,18 +324,18 @@ rsHandle ev = do | |||||||
|         Normal -> |         Normal -> | ||||||
|           case ev of |           case ev of | ||||||
|             VtyEvent (EvKey (KChar 'q') []) -> halt |             VtyEvent (EvKey (KChar 'q') []) -> halt | ||||||
|             VtyEvent (EvKey KEsc        []) -> put $ resetScreens d ui |             VtyEvent (EvKey KEsc        []) -> put' $ resetScreens d ui | ||||||
|             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put $ setMode Help ui |             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put' $ setMode Help ui | ||||||
|             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> |             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> | ||||||
|               put $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui |               put' $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui | ||||||
|               where |               where | ||||||
|                 p = reportPeriod ui |                 p = reportPeriod ui | ||||||
|             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> |             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> | ||||||
|               liftIO (uiReloadJournal copts d ui) >>= put |               liftIO (uiReloadJournal copts d ui) >>= put' | ||||||
|             VtyEvent (EvKey (KChar 'I') []) -> put $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) |             VtyEvent (EvKey (KChar 'I') []) -> put' $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) | ||||||
|             VtyEvent (EvKey (KChar 'a') []) -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'a') []) -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui | ||||||
|             VtyEvent (EvKey (KChar 'A') []) -> suspendAndResume $ void (runIadd (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'A') []) -> suspendAndResume $ void (runIadd (journalFilePath j)) >> uiReloadJournalIfChanged copts d j ui | ||||||
|             VtyEvent (EvKey (KChar 'T') []) -> put $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui |             VtyEvent (EvKey (KChar 'T') []) -> put' $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui | ||||||
|             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui | ||||||
|               where |               where | ||||||
|                 (pos,f) = case listSelectedElement rsList of |                 (pos,f) = case listSelectedElement rsList of | ||||||
| @ -342,53 +344,53 @@ rsHandle ev = do | |||||||
|                               rsItemTransaction=Transaction{tsourcepos=(SourcePos f l c,_)}}) -> (Just (unPos l, Just $ unPos c),f) |                               rsItemTransaction=Transaction{tsourcepos=(SourcePos f l c,_)}}) -> (Just (unPos l, Just $ unPos c),f) | ||||||
| 
 | 
 | ||||||
|             -- display mode/query toggles |             -- display mode/query toggles | ||||||
|             VtyEvent (EvKey (KChar 'B') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleConversionOp ui |             VtyEvent (EvKey (KChar 'B') []) -> rsCenterSelection $ regenerateScreens j d $ toggleConversionOp ui | ||||||
|             VtyEvent (EvKey (KChar 'V') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleValue ui |             VtyEvent (EvKey (KChar 'V') []) -> rsCenterSelection $ regenerateScreens j d $ toggleValue ui | ||||||
|             VtyEvent (EvKey (KChar 'H') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleHistorical ui |             VtyEvent (EvKey (KChar 'H') []) -> rsCenterSelection $ regenerateScreens j d $ toggleHistorical ui | ||||||
|             VtyEvent (EvKey (KChar 't') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleTree ui |             VtyEvent (EvKey (KChar 't') []) -> rsCenterSelection $ regenerateScreens j d $ toggleTree ui | ||||||
|             VtyEvent (EvKey (KChar c) []) | c `elem` ['z','Z'] -> rsCenterAndContinue $ regenerateScreens j d $ toggleEmpty ui |             VtyEvent (EvKey (KChar c) []) | c `elem` ['z','Z'] -> rsCenterSelection $ regenerateScreens j d $ toggleEmpty ui | ||||||
|             VtyEvent (EvKey (KChar 'R') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleReal ui |             VtyEvent (EvKey (KChar 'R') []) -> rsCenterSelection $ regenerateScreens j d $ toggleReal ui | ||||||
|             VtyEvent (EvKey (KChar 'U') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleUnmarked ui |             VtyEvent (EvKey (KChar 'U') []) -> rsCenterSelection $ regenerateScreens j d $ toggleUnmarked ui | ||||||
|             VtyEvent (EvKey (KChar 'P') []) -> rsCenterAndContinue $ regenerateScreens j d $ togglePending ui |             VtyEvent (EvKey (KChar 'P') []) -> rsCenterSelection $ regenerateScreens j d $ togglePending ui | ||||||
|             VtyEvent (EvKey (KChar 'C') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleCleared ui |             VtyEvent (EvKey (KChar 'C') []) -> rsCenterSelection $ regenerateScreens j d $ toggleCleared ui | ||||||
|             VtyEvent (EvKey (KChar 'F') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleForecast d ui |             VtyEvent (EvKey (KChar 'F') []) -> rsCenterSelection $ regenerateScreens j d $ toggleForecast d ui | ||||||
| 
 | 
 | ||||||
|             VtyEvent (EvKey (KChar '/') []) -> put $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui |             VtyEvent (EvKey (KChar '/') []) -> put' $ regenerateScreens j d $ showMinibuffer "filter" Nothing ui | ||||||
|             VtyEvent (EvKey (KDown)     [MShift]) -> put $ regenerateScreens j d $ shrinkReportPeriod d ui |             VtyEvent (EvKey (KDown)     [MShift]) -> put' $ regenerateScreens j d $ shrinkReportPeriod d ui | ||||||
|             VtyEvent (EvKey (KUp)       [MShift]) -> put $ regenerateScreens j d $ growReportPeriod d ui |             VtyEvent (EvKey (KUp)       [MShift]) -> put' $ regenerateScreens j d $ growReportPeriod d ui | ||||||
|             VtyEvent (EvKey (KRight)    [MShift]) -> put $ regenerateScreens j d $ nextReportPeriod journalspan ui |             VtyEvent (EvKey (KRight)    [MShift]) -> put' $ regenerateScreens j d $ nextReportPeriod journalspan ui | ||||||
|             VtyEvent (EvKey (KLeft)     [MShift]) -> put $ regenerateScreens j d $ previousReportPeriod journalspan ui |             VtyEvent (EvKey (KLeft)     [MShift]) -> put' $ regenerateScreens j d $ previousReportPeriod journalspan ui | ||||||
|             VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (put $ regenerateScreens j d $ resetFilter ui) |             VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (put' $ regenerateScreens j d $ resetFilter ui) | ||||||
|             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle rsList >> redraw |             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle rsList >> redraw | ||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
| 
 | 
 | ||||||
|             -- exit screen on LEFT |             -- exit screen on LEFT | ||||||
|             VtyEvent e | e `elem` moveLeftEvents  -> put $ popScreen ui |             VtyEvent e | e `elem` moveLeftEvents  -> put' $ popScreen ui | ||||||
|             -- or on a click in the app's left margin. This is a VtyEvent since not in a clickable widget. |             -- or on a click in the app's left margin. This is a VtyEvent since not in a clickable widget. | ||||||
|             VtyEvent (EvMouseUp x _y (Just BLeft)) | x==0 -> put $ popScreen ui |             VtyEvent (EvMouseUp x _y (Just BLeft)) | x==0 -> put' $ popScreen ui | ||||||
|             -- or on clicking a blank list item. |             -- or on clicking a blank list item. | ||||||
|             MouseUp _ (Just BLeft) Location{loc=(_,y)} | clickeddate == "" -> put $ popScreen ui |             MouseUp _ (Just BLeft) Location{loc=(_,y)} | clickeddate == "" -> put' $ popScreen ui | ||||||
|               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y |               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y | ||||||
| 
 | 
 | ||||||
|             -- enter transaction screen on RIGHT |             -- enter transaction screen on RIGHT | ||||||
|             VtyEvent e | e `elem` moveRightEvents -> |             VtyEvent e | e `elem` moveRightEvents -> | ||||||
|               case listSelectedElement rsList of |               case listSelectedElement rsList of | ||||||
|                 Just _  -> put $ screenEnter d transactionScreen{tsAccount=rsAccount} ui |                 Just _  -> put' $ screenEnter d transactionScreen{tsAccount=rsAccount} ui | ||||||
|                 Nothing -> put ui |                 Nothing -> put' ui | ||||||
|             -- or on transaction click |             -- or on transaction click | ||||||
|             -- MouseDown is sometimes duplicated, https://github.com/jtdaugherty/brick/issues/347 |             -- MouseDown is sometimes duplicated, https://github.com/jtdaugherty/brick/issues/347 | ||||||
|             -- just use it to move the selection |             -- just use it to move the selection | ||||||
|             MouseDown _n BLeft _mods Location{loc=(_x,y)} | not $ (=="") clickeddate -> do |             MouseDown _n BLeft _mods Location{loc=(_x,y)} | not $ (=="") clickeddate -> do | ||||||
|               put $ ui{aScreen=s{rsList=listMoveTo y rsList}} |               put' $ ui{aScreen=s{rsList=listMoveTo y rsList}} | ||||||
|               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y |               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y | ||||||
|             -- and on MouseUp, enter the subscreen |             -- and on MouseUp, enter the subscreen | ||||||
|             MouseUp _n (Just BLeft) Location{loc=(_x,y)} | not $ (=="") clickeddate -> do |             MouseUp _n (Just BLeft) Location{loc=(_x,y)} | not $ (=="") clickeddate -> do | ||||||
|               put $ screenEnter d transactionScreen{tsAccount=rsAccount} ui |               put' $ screenEnter d transactionScreen{tsAccount=rsAccount} ui | ||||||
|               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y |               where clickeddate = maybe "" rsItemDate $ listElements rsList !? y | ||||||
| 
 | 
 | ||||||
|             -- when selection is at the last item, DOWN scrolls instead of moving, until maximally scrolled |             -- when selection is at the last item, DOWN scrolls instead of moving, until maximally scrolled | ||||||
|             VtyEvent e | e `elem` moveDownEvents, isBlankElement mnextelement -> do |             VtyEvent e | e `elem` moveDownEvents, isBlankElement mnextelement -> do | ||||||
|               vScrollBy (viewportScroll $ rsList ^. listNameL) 1 >> put ui |               vScrollBy (viewportScroll $ rsList ^. listNameL) 1 >> put' ui | ||||||
|               where mnextelement = listSelectedElement $ listMoveDown rsList |               where mnextelement = listSelectedElement $ listMoveDown rsList | ||||||
| 
 | 
 | ||||||
|             -- mouse scroll wheel scrolls the viewport up or down to its maximum extent, |             -- mouse scroll wheel scrolls the viewport up or down to its maximum extent, | ||||||
| @ -396,7 +398,7 @@ rsHandle ev = do | |||||||
|             MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do |             MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do | ||||||
|               let scrollamt = if btn==BScrollUp then -1 else 1 |               let scrollamt = if btn==BScrollUp then -1 else 1 | ||||||
|               list' <- nestEventM' rsList $ listScrollPushingSelection name (rsListSize rsList) scrollamt |               list' <- nestEventM' rsList $ listScrollPushingSelection name (rsListSize rsList) scrollamt | ||||||
|               put ui{aScreen=s{rsList=list'}} |               put' ui{aScreen=s{rsList=list'}} | ||||||
| 
 | 
 | ||||||
|             -- if page down or end leads to a blank padding item, stop at last non-blank |             -- if page down or end leads to a blank padding item, stop at last non-blank | ||||||
|             VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do |             VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do | ||||||
| @ -405,21 +407,21 @@ rsHandle ev = do | |||||||
|               then do |               then do | ||||||
|                 let list' = listMoveTo lastnonblankidx list |                 let list' = listMoveTo lastnonblankidx list | ||||||
|                 scrollSelectionToMiddle list' |                 scrollSelectionToMiddle list' | ||||||
|                 put ui{aScreen=s{rsList=list'}} |                 put' ui{aScreen=s{rsList=list'}} | ||||||
|               else |               else | ||||||
|                 put ui{aScreen=s{rsList=list}} |                 put' ui{aScreen=s{rsList=list}} | ||||||
| 
 | 
 | ||||||
|             -- fall through to the list's event handler (handles other [pg]up/down events) |             -- fall through to the list's event handler (handles other [pg]up/down events) | ||||||
|             VtyEvent ev -> do |             VtyEvent ev -> do | ||||||
|               let ev' = normaliseMovementKeys ev |               let ev' = normaliseMovementKeys ev | ||||||
|               newitems <- nestEventM' rsList $ handleListEvent ev' |               newitems <- nestEventM' rsList $ handleListEvent ev' | ||||||
|               put ui{aScreen=s{rsList=newitems}} |               put' ui{aScreen=s{rsList=newitems}} | ||||||
| 
 | 
 | ||||||
|             MouseDown{}       -> put ui |             MouseDown{}       -> put' ui | ||||||
|             MouseUp{}         -> put ui |             MouseUp{}         -> put' ui | ||||||
|             AppEvent _        -> put ui |             AppEvent _        -> put' ui | ||||||
| 
 | 
 | ||||||
|     _ -> errorWrongScreenType |     _ -> dlogUiTrace "rsHandle 2" $ errorWrongScreenType "event handler" | ||||||
| 
 | 
 | ||||||
| isBlankElement mel = ((rsItemDate . snd) <$> mel) == Just "" | isBlankElement mel = ((rsItemDate . snd) <$> mel) == Just "" | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ tsInit _d _reset ui@UIState{aopts=UIOpts{} | |||||||
|             seltxn = maybe nulltransaction (rsItemTransaction . snd) $ listSelectedElement xs |             seltxn = maybe nulltransaction (rsItemTransaction . snd) $ listSelectedElement xs | ||||||
|             nonblanks = V.toList . V.takeWhile (not . T.null . rsItemDate) $ xs ^. listElementsL |             nonblanks = V.toList . V.takeWhile (not . T.null . rsItemDate) $ xs ^. listElementsL | ||||||
|         _                           -> (t, nts) |         _                           -> (t, nts) | ||||||
| tsInit _ _ _ = error "init function called with wrong screen type, should not happen"  -- PARTIAL: | tsInit _ _ _ = errorWrongScreenType "init function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| -- Render a transaction suitably for the transaction screen. | -- Render a transaction suitably for the transaction screen. | ||||||
| showTxn :: ReportOpts -> ReportSpec -> Journal -> Transaction -> T.Text | showTxn :: ReportOpts -> ReportSpec -> Journal -> Transaction -> T.Text | ||||||
| @ -139,11 +139,11 @@ tsDraw UIState{aopts=UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec | |||||||
|               ,("q", "quit") |               ,("q", "quit") | ||||||
|               ] |               ] | ||||||
| 
 | 
 | ||||||
| tsDraw _ = error "draw function called with wrong screen type, should not happen"  -- PARTIAL: | tsDraw _ = errorWrongScreenType "draw function"  -- PARTIAL: | ||||||
| 
 | 
 | ||||||
| tsHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | tsHandle :: BrickEvent Name AppEvent -> EventM Name UIState () | ||||||
| tsHandle ev = do | tsHandle ev = do | ||||||
|   ui0 <- get |   ui0 <- get' | ||||||
|   case ui0 of |   case ui0 of | ||||||
|     ui@UIState{aScreen=TransactionScreen{tsTransaction=(i,t), tsTransactions=nts} |     ui@UIState{aScreen=TransactionScreen{tsTransaction=(i,t), tsTransactions=nts} | ||||||
|                     ,aopts=UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}} |                     ,aopts=UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec@ReportSpec{_rsReportOpts=ropts}}} | ||||||
| @ -165,48 +165,48 @@ tsHandle ev = do | |||||||
|             (inext,tnext) = maybe (i,t) ((i+1),) $ lookup (i+1) nts |             (inext,tnext) = maybe (i,t) ((i+1),) $ lookup (i+1) nts | ||||||
|           case ev of |           case ev of | ||||||
|             VtyEvent (EvKey (KChar 'q') []) -> halt |             VtyEvent (EvKey (KChar 'q') []) -> halt | ||||||
|             VtyEvent (EvKey KEsc        []) -> put $ resetScreens d ui |             VtyEvent (EvKey KEsc        []) -> put' $ resetScreens d ui | ||||||
|             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put $ setMode Help ui |             VtyEvent (EvKey (KChar c)   []) | c == '?' -> put' $ setMode Help ui | ||||||
|             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui |             VtyEvent (EvKey (KChar 'E') []) -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui | ||||||
|               where |               where | ||||||
|                 (pos,f) = case tsourcepos t of |                 (pos,f) = case tsourcepos t of | ||||||
|                             (SourcePos f l1 c1,_) -> (Just (unPos l1, Just $ unPos c1),f) |                             (SourcePos f l1 c1,_) -> (Just (unPos l1, Just $ unPos c1),f) | ||||||
|             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> |             AppEvent (DateChange old _) | isStandardPeriod p && p `periodContainsDate` old -> | ||||||
|               put $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui |               put' $ regenerateScreens j d $ setReportPeriod (DayPeriod d) ui | ||||||
|               where |               where | ||||||
|                 p = reportPeriod ui |                 p = reportPeriod ui | ||||||
|             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> do |             e | e `elem` [VtyEvent (EvKey (KChar 'g') []), AppEvent FileChange] -> do | ||||||
|               -- plog (if e == AppEvent FileChange then "file change" else "manual reload") "" `seq` return () |               -- plog (if e == AppEvent FileChange then "file change" else "manual reload") "" `seq` return () | ||||||
|               ej <- liftIO . runExceptT $ journalReload copts |               ej <- liftIO . runExceptT $ journalReload copts | ||||||
|               case ej of |               case ej of | ||||||
|                 Left err -> put $ screenEnter d errorScreen{esError=err} ui |                 Left err -> put' $ screenEnter d errorScreen{esError=err} ui | ||||||
|                 Right j' -> put $ regenerateScreens j' d ui |                 Right j' -> put' $ regenerateScreens j' d ui | ||||||
|             VtyEvent (EvKey (KChar 'I') []) -> put $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) |             VtyEvent (EvKey (KChar 'I') []) -> put' $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) | ||||||
| 
 | 
 | ||||||
|             -- for toggles that may change the current/prev/next transactions, |             -- for toggles that may change the current/prev/next transactions, | ||||||
|             -- we must regenerate the transaction list, like the g handler above ? with regenerateTransactions ? TODO WIP |             -- we must regenerate the transaction list, like the g handler above ? with regenerateTransactions ? TODO WIP | ||||||
|             -- EvKey (KChar 'E') [] -> put $ regenerateScreens j d $ stToggleEmpty ui |             -- EvKey (KChar 'E') [] -> put' $ regenerateScreens j d $ stToggleEmpty ui | ||||||
|             -- EvKey (KChar 'C') [] -> put $ regenerateScreens j d $ stToggleCleared ui |             -- EvKey (KChar 'C') [] -> put' $ regenerateScreens j d $ stToggleCleared ui | ||||||
|             -- EvKey (KChar 'R') [] -> put $ regenerateScreens j d $ stToggleReal ui |             -- EvKey (KChar 'R') [] -> put' $ regenerateScreens j d $ stToggleReal ui | ||||||
|             VtyEvent (EvKey (KChar 'B') []) -> put . regenerateScreens j d $ toggleConversionOp ui |             VtyEvent (EvKey (KChar 'B') []) -> put' . regenerateScreens j d $ toggleConversionOp ui | ||||||
|             VtyEvent (EvKey (KChar 'V') []) -> put . regenerateScreens j d $ toggleValue ui |             VtyEvent (EvKey (KChar 'V') []) -> put' . regenerateScreens j d $ toggleValue ui | ||||||
| 
 | 
 | ||||||
|             VtyEvent e | e `elem` moveUpEvents   -> put $ tsSelect iprev tprev ui |             VtyEvent e | e `elem` moveUpEvents   -> put' $ tsSelect iprev tprev ui | ||||||
|             VtyEvent e | e `elem` moveDownEvents -> put $ tsSelect inext tnext ui |             VtyEvent e | e `elem` moveDownEvents -> put' $ tsSelect inext tnext ui | ||||||
| 
 | 
 | ||||||
|             -- exit screen on LEFT |             -- exit screen on LEFT | ||||||
|             VtyEvent e | e `elem` moveLeftEvents -> put . popScreen $ tsSelect i t ui  -- Probably not necessary to tsSelect here, but it's safe. |             VtyEvent e | e `elem` moveLeftEvents -> put' . popScreen $ tsSelect i t ui  -- Probably not necessary to tsSelect here, but it's safe. | ||||||
|             -- or on a click in the app's left margin. |             -- or on a click in the app's left margin. | ||||||
|             VtyEvent (EvMouseUp x _y (Just BLeft)) | x==0 -> put . popScreen $ tsSelect i t ui |             VtyEvent (EvMouseUp x _y (Just BLeft)) | x==0 -> put' . popScreen $ tsSelect i t ui | ||||||
|             -- or on clicking the blank area below the transaction. |             -- or on clicking the blank area below the transaction. | ||||||
|             MouseUp _ (Just BLeft) Location{loc=(_,y)} | y+1 > numentrylines -> put . popScreen $ tsSelect i t ui |             MouseUp _ (Just BLeft) Location{loc=(_,y)} | y+1 > numentrylines -> put' . popScreen $ tsSelect i t ui | ||||||
|               where numentrylines = length (T.lines $ showTxn ropts rspec j t) - 1 |               where numentrylines = length (T.lines $ showTxn ropts rspec j t) - 1 | ||||||
| 
 | 
 | ||||||
|             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw |             VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw | ||||||
|             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui |             VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||||
|             _ -> return () |             _ -> return () | ||||||
| 
 | 
 | ||||||
|     _ -> errorWrongScreenType |     _ -> errorWrongScreenType "event handler" | ||||||
| 
 | 
 | ||||||
| -- | Select a new transaction and update the previous register screen | -- | Select a new transaction and update the previous register screen | ||||||
| tsSelect i t ui@UIState{aScreen=s@TransactionScreen{}} = case aPrevScreens ui of | tsSelect i t ui@UIState{aScreen=s@TransactionScreen{}} = case aPrevScreens ui of | ||||||
|  | |||||||
| @ -39,6 +39,8 @@ Brick.defaultMain brickapp st | |||||||
| 
 | 
 | ||||||
| module Hledger.UI.UITypes where | module Hledger.UI.UITypes where | ||||||
| 
 | 
 | ||||||
|  | -- import Control.Concurrent (threadDelay) | ||||||
|  | -- import GHC.IO (unsafePerformIO) | ||||||
| import Data.Text (Text) | import Data.Text (Text) | ||||||
| import Data.Time.Calendar (Day) | import Data.Time.Calendar (Day) | ||||||
| import Brick | import Brick | ||||||
| @ -137,7 +139,10 @@ data Screen = | |||||||
| -- XXX check for ideas: https://github.com/jtdaugherty/brick/issues/379#issuecomment-1191993357 | -- XXX check for ideas: https://github.com/jtdaugherty/brick/issues/379#issuecomment-1191993357 | ||||||
| 
 | 
 | ||||||
| -- | Error message to use in case statements adapting to the different Screen shapes. | -- | Error message to use in case statements adapting to the different Screen shapes. | ||||||
| errorWrongScreenType = error' "handler called with wrong screen type, should not happen" | errorWrongScreenType :: String -> a | ||||||
|  | errorWrongScreenType lbl = | ||||||
|  |   -- unsafePerformIO $ threadDelay 2000000 >>  -- delay to allow console output to be seen | ||||||
|  |   error' (unwords [lbl, "called with wrong screen type, should not happen"]) | ||||||
| 
 | 
 | ||||||
| -- | An item in the accounts screen's list of accounts and balances. | -- | An item in the accounts screen's list of accounts and balances. | ||||||
| data AccountsScreenItem = AccountsScreenItem { | data AccountsScreenItem = AccountsScreenItem { | ||||||
|  | |||||||
| @ -23,10 +23,17 @@ module Hledger.UI.UIUtils ( | |||||||
|   ,renderToggle1 |   ,renderToggle1 | ||||||
|   ,replaceHiddenAccountsNameWith |   ,replaceHiddenAccountsNameWith | ||||||
|   ,scrollSelectionToMiddle |   ,scrollSelectionToMiddle | ||||||
|  |   ,get' | ||||||
|  |   ,put' | ||||||
|  |   ,modify' | ||||||
|   ,suspend |   ,suspend | ||||||
|   ,redraw |   ,redraw | ||||||
|   ,reportSpecSetFutureAndForecast |   ,reportSpecSetFutureAndForecast | ||||||
|   ,listScrollPushingSelection |   ,listScrollPushingSelection | ||||||
|  |   ,dlogUiTrace | ||||||
|  |   ,dlogUiTraceM | ||||||
|  |   ,uiDebugLevel | ||||||
|  |   ,uiNumBlankItems | ||||||
|   ) |   ) | ||||||
| where | where | ||||||
| 
 | 
 | ||||||
| @ -65,6 +72,23 @@ suspendSignal :: IO () | |||||||
| suspendSignal = raiseSignal sigSTOP | suspendSignal = raiseSignal sigSTOP | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | -- Debug logging for UI state changes. | ||||||
|  | 
 | ||||||
|  | get' = do | ||||||
|  |   x <- get | ||||||
|  |   dlogUiTraceM $ "getting state: " ++ (head $ lines $ pshow $ aScreen x) | ||||||
|  |   return x | ||||||
|  | 
 | ||||||
|  | put' x = do | ||||||
|  |   dlogUiTraceM $ "putting state: " ++ (head $ lines $ pshow $ aScreen x) | ||||||
|  |   put x | ||||||
|  | 
 | ||||||
|  | modify' f = do | ||||||
|  |   x <- get | ||||||
|  |   let x' = f x | ||||||
|  |   dlogUiTraceM $ "modifying state: " ++ (head $ lines $ pshow $ aScreen x') | ||||||
|  |   modify f | ||||||
|  | 
 | ||||||
| -- | On posix platforms, suspend the program using the STOP signal, | -- | On posix platforms, suspend the program using the STOP signal, | ||||||
| -- like control-z in bash, returning to the original shell prompt, | -- like control-z in bash, returning to the original shell prompt, | ||||||
| -- and when resumed, continue where we left off. | -- and when resumed, continue where we left off. | ||||||
| @ -170,7 +194,7 @@ helpHandle ev = do | |||||||
|   ui <- get |   ui <- get | ||||||
|   let ui' = setMode Normal ui |   let ui' = setMode Normal ui | ||||||
|   case ev of |   case ev of | ||||||
|     VtyEvent e | e `elem` closeHelpEvents -> put ui' |     VtyEvent e | e `elem` closeHelpEvents -> put' ui' | ||||||
|     VtyEvent (EvKey (KChar 'p') []) -> suspendAndResume $ runPagerForTopic "hledger-ui" Nothing >> return ui' |     VtyEvent (EvKey (KChar 'p') []) -> suspendAndResume $ runPagerForTopic "hledger-ui" Nothing >> return ui' | ||||||
|     VtyEvent (EvKey (KChar 'm') []) -> suspendAndResume $ runManForTopic   "hledger-ui" Nothing >> return ui' |     VtyEvent (EvKey (KChar 'm') []) -> suspendAndResume $ runManForTopic   "hledger-ui" Nothing >> return ui' | ||||||
|     VtyEvent (EvKey (KChar 'i') []) -> suspendAndResume $ runInfoForTopic  "hledger-ui" Nothing >> return ui' |     VtyEvent (EvKey (KChar 'i') []) -> suspendAndResume $ runInfoForTopic  "hledger-ui" Nothing >> return ui' | ||||||
| @ -383,3 +407,24 @@ listScrollPushingSelection name listheight scrollamt = do | |||||||
|               | otherwise = id |               | otherwise = id | ||||||
|         _ -> return list |         _ -> return list | ||||||
|     _ -> return list |     _ -> return list | ||||||
|  | 
 | ||||||
|  | -- | Log a string to ./debug.log before returning the second argument, | ||||||
|  | -- if the global debug level is at or above a standard hledger-ui debug level. | ||||||
|  | -- Uses unsafePerformIO. | ||||||
|  | dlogUiTrace :: String -> a -> a | ||||||
|  | dlogUiTrace = dlogTraceAt uiDebugLevel | ||||||
|  | 
 | ||||||
|  | -- | Like dlogUiTrace, but within the hledger-ui brick event handler monad. | ||||||
|  | dlogUiTraceM :: String -> EventM Name UIState () | ||||||
|  | dlogUiTraceM s = dlogUiTrace s $ return () | ||||||
|  | 
 | ||||||
|  | -- | Log hledger-ui events at this debug level. | ||||||
|  | uiDebugLevel :: Int | ||||||
|  | uiDebugLevel = 2 | ||||||
|  | 
 | ||||||
|  | -- | How many blank items to add to lists to fill the full window height. | ||||||
|  | uiNumBlankItems :: Int | ||||||
|  | uiNumBlankItems | ||||||
|  |   -- | debugLevel >= uiDebugLevel = 0    -- suppress to improve debug output. | ||||||
|  |   -- | otherwise  | ||||||
|  |   = 100  -- 100 ought to be enough for anyone | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user