mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-12 19:08:34 +03:00
111 lines
4.0 KiB
Haskell
111 lines
4.0 KiB
Haskell
-- The error screen, showing a current error condition (such as a parse error after reloading the journal)
|
|
|
|
{-# LANGUAGE OverloadedStrings, FlexibleContexts, RecordWildCards #-}
|
|
|
|
module Hledger.UI.ErrorScreen
|
|
(errorScreen
|
|
,stReloadJournalIfChanged
|
|
)
|
|
where
|
|
|
|
-- import Lens.Micro.Platform ((^.))
|
|
import Control.Monad.IO.Class (liftIO)
|
|
import Data.Monoid
|
|
-- import Data.Maybe
|
|
import Data.Time.Calendar (Day)
|
|
import Graphics.Vty as Vty
|
|
import Brick
|
|
-- import Brick.Widgets.List
|
|
-- import Brick.Widgets.Border
|
|
-- import Brick.Widgets.Border.Style
|
|
-- import Brick.Widgets.Center
|
|
-- import Text.Printf
|
|
|
|
-- import Hledger
|
|
import Hledger.Cli hiding (progname,prognameandversion,green)
|
|
import Hledger.UI.UIOptions
|
|
-- import Hledger.UI.Theme
|
|
import Hledger.UI.UITypes
|
|
import Hledger.UI.UIUtils
|
|
|
|
errorScreen :: Screen
|
|
errorScreen = ErrorScreen{
|
|
sInit = esInit
|
|
,sDraw = esDraw
|
|
,sHandle = esHandle
|
|
,esError = ""
|
|
}
|
|
|
|
esInit :: Day -> Bool -> AppState -> AppState
|
|
esInit _ _ st@AppState{aScreen=ErrorScreen{}} = st
|
|
esInit _ _ _ = error "init function called with wrong screen type, should not happen"
|
|
|
|
esDraw :: AppState -> [Widget]
|
|
esDraw AppState{ -- aopts=_uopts@UIOpts{cliopts_=_copts@CliOpts{reportopts_=_ropts@ReportOpts{query_=querystr}}},
|
|
aScreen=ErrorScreen{..}
|
|
,aMode=mode} =
|
|
case mode of
|
|
Help -> [helpDialog, maincontent]
|
|
-- Minibuffer e -> [minibuffer e, maincontent]
|
|
_ -> [maincontent]
|
|
where
|
|
toplabel = withAttr ("border" <> "bold") (str "Oops. Please fix this problem then press g to reload")
|
|
maincontent = Widget Greedy Greedy $ do
|
|
render $ defaultLayout toplabel bottomlabel $ withAttr "error" $ str $ esError
|
|
where
|
|
bottomlabel = case mode of
|
|
-- Minibuffer ed -> minibuffer ed
|
|
_ -> quickhelp
|
|
quickhelp = borderKeysStr [
|
|
("h", "help")
|
|
,("ESC", "cancel/top")
|
|
,("g", "reload")
|
|
,("q", "quit")
|
|
]
|
|
|
|
esDraw _ = error "draw function called with wrong screen type, should not happen"
|
|
|
|
esHandle :: AppState -> Vty.Event -> EventM (Next AppState)
|
|
esHandle st@AppState{
|
|
aScreen=s@ErrorScreen{}
|
|
,aopts=UIOpts{cliopts_=copts}
|
|
,ajournal=j
|
|
,aMode=mode
|
|
} ev =
|
|
case mode of
|
|
Help ->
|
|
case ev of
|
|
Vty.EvKey (Vty.KChar 'q') [] -> halt st
|
|
_ -> helpHandle st ev
|
|
|
|
_ -> do
|
|
d <- liftIO getCurrentDay
|
|
case ev of
|
|
Vty.EvKey (Vty.KChar 'q') [] -> halt st
|
|
Vty.EvKey Vty.KEsc [] -> continue $ resetScreens d st
|
|
Vty.EvKey k [] | k `elem` [Vty.KChar 'h', Vty.KChar '?'] -> continue $ setMode Help st
|
|
Vty.EvKey (Vty.KChar 'g') [] -> do
|
|
(ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
|
case ej of
|
|
Left err -> continue st{aScreen=s{esError=err}} -- show latest parse error
|
|
Right j' -> continue $ regenerateScreens j' d $ popScreen st -- return to previous screen, and reload it
|
|
|
|
-- Vty.EvKey (Vty.KLeft) [] -> continue $ popScreen st
|
|
-- Vty.EvKey (Vty.KRight) [] -> error (show curItem) where curItem = listSelectedElement is
|
|
-- fall through to the list's event handler (handles [pg]up/down)
|
|
_ -> do continue st
|
|
-- is' <- handleEvent ev is
|
|
-- continue st{aScreen=s{rsState=is'}}
|
|
-- continue =<< handleEventLensed st someLens e
|
|
esHandle _ _ = error "event handler called with wrong screen type, should not happen"
|
|
|
|
-- If journal file(s) have changed, reload the journal and regenerate all screens.
|
|
-- This is here so it can reference the error screen.
|
|
stReloadJournalIfChanged :: CliOpts -> Day -> Journal -> AppState -> IO AppState
|
|
stReloadJournalIfChanged copts d j st = do
|
|
(ej, _) <- journalReloadIfChanged copts d j
|
|
return $ case ej of
|
|
Right j' -> regenerateScreens j' d st
|
|
Left err -> screenEnter d errorScreen{esError=err} st
|
|
|