leksah-0.8: src/IDE/Pane/Errors.hs
{-# OPTIONS_GHC -XRecordWildCards -XTypeSynonymInstances -XMultiParamTypeClasses
-XDeriveDataTypeable #-}
-----------------------------------------------------------------------------
--
-- Module : IDE.Pane.Errors
-- Copyright : 2007-2010 Juergen Nicklisch-Franken, Hamish Mackenzie
-- License : GPL
--
-- Maintainer : maintainer@leksah.org
-- Stability : provisional
-- Portability :
--
-- | A pane which displays a list of errors
--
-----------------------------------------------------------------------------
module IDE.Pane.Errors (
IDEErrors
, ErrorsState
, fillErrorList
, selectError
, getErrors
) where
import Graphics.UI.Gtk
import Data.Typeable (Typeable(..))
import IDE.Core.State
import Control.Monad.Reader
import Graphics.UI.Gtk.General.Enums
(Click(..), MouseButton(..))
import Graphics.UI.Gtk.Gdk.Events (Event(..))
import IDE.ImportTool (addImport,parseNotInScope, addAllImports)
import Data.List (elemIndex)
import IDE.LogRef (showSourceSpan)
-- | A breakpoints pane description
--
data IDEErrors = IDEErrors {
scrolledView :: ScrolledWindow
, treeView :: TreeView
, errorStore :: TreeStore ErrColumn
} deriving Typeable
data ErrColumn = ErrColumn {logRef :: LogRef, string :: String, index :: Int}
data ErrorsState = ErrorsState {
} deriving(Eq,Ord,Read,Show,Typeable)
instance Pane IDEErrors IDEM
where
primPaneName _ = "Errors"
getTopWidget = castToWidget . scrolledView
paneId b = "*Errors"
instance RecoverablePane IDEErrors ErrorsState IDEM where
saveState p = do
return (Just ErrorsState)
recoverState pp ErrorsState = do
nb <- getNotebook pp
p <- buildPane pp nb builder
fillErrorList
return p
builder = builder'
builder' :: PanePath ->
Notebook ->
Window ->
IDEM (Maybe IDEErrors, Connections)
builder' pp nb windows = reifyIDE $ \ ideR -> do
errorStore <- treeStoreNew []
treeView <- treeViewNew
treeViewSetModel treeView errorStore
rendererA <- cellRendererTextNew
colA <- treeViewColumnNew
treeViewColumnSetTitle colA "Location"
treeViewColumnSetSizing colA TreeViewColumnAutosize
treeViewColumnSetResizable colA True
treeViewColumnSetReorderable colA True
treeViewAppendColumn treeView colA
cellLayoutPackStart colA rendererA False
cellLayoutSetAttributes colA rendererA errorStore
$ \row -> [cellText := if index row == 0 then showSourceSpan (logRef row) else "",
cellTextForeground := if (logRefType (logRef row)) == WarningRef
then "green"
else "red" ]
rendererB <- cellRendererTextNew
colB <- treeViewColumnNew
treeViewColumnSetTitle colB "Description"
treeViewColumnSetSizing colB TreeViewColumnAutosize
treeViewColumnSetResizable colB True
treeViewColumnSetReorderable colB True
treeViewAppendColumn treeView colB
cellLayoutPackStart colB rendererB False
cellLayoutSetAttributes colB rendererB errorStore
$ \row -> [ cellText := string row]
treeViewSetHeadersVisible treeView True
selB <- treeViewGetSelection treeView
treeSelectionSetMode selB SelectionSingle
scrolledView <- scrolledWindowNew Nothing Nothing
containerAdd scrolledView treeView
scrolledWindowSetPolicy scrolledView PolicyAutomatic PolicyAutomatic
let pane = IDEErrors scrolledView treeView errorStore
treeView `onButtonPress` (errorViewPopup ideR errorStore treeView)
cid1 <- treeView `afterFocusIn`
(\_ -> do reflectIDE (makeActive pane) ideR ; return True)
return (Just pane,[ConnectC cid1])
getErrors :: Maybe PanePath -> IDEM IDEErrors
getErrors Nothing = forceGetPane (Right "*Errors")
getErrors (Just pp) = forceGetPane (Left pp)
fillErrorList :: IDEAction
fillErrorList = do
mbErrors <- getPane
case mbErrors of
Nothing -> return ()
Just pane -> do
refs <- readIDE errorRefs
liftIO $ do
treeStoreClear (errorStore pane)
mapM_ (insertError (errorStore pane)) (zip refs [0..length refs])
where
insertError treeStore (lr,index) =
case {--lines--} [refDescription lr] of
[] -> treeStoreInsert treeStore [] index (ErrColumn lr "" 0)
h:t -> do
treeStoreInsert treeStore [] index (ErrColumn lr h 0)
mapM_ (\(line,subind) ->
treeStoreInsert treeStore [index] subind (ErrColumn lr line (subind + 1)))
(zip t [0..length t])
getSelectedError :: TreeView
-> TreeStore ErrColumn
-> IO (Maybe LogRef)
getSelectedError treeView treeStore = do
treeSelection <- treeViewGetSelection treeView
paths <- treeSelectionGetSelectedRows treeSelection
case paths of
a:r -> do
val <- treeStoreGetValue treeStore a
return (Just (logRef val))
_ -> return Nothing
selectError :: Maybe LogRef -> IDEAction
selectError mbLogRef = do
errorRefs' <- readIDE errorRefs
errors <- getErrors Nothing
liftIO $ do
selection <- treeViewGetSelection (treeView errors)
case mbLogRef of
Nothing -> treeSelectionUnselectAll selection
Just lr -> case lr `elemIndex` errorRefs' of
Nothing -> return ()
Just ind -> treeSelectionSelectPath selection [ind]
errorViewPopup :: IDERef
-> TreeStore ErrColumn
-> TreeView
-> Event
-> IO Bool
errorViewPopup ideR store treeView (Button _ click _ _ _ _ button _ _)
= do
if button == RightButton
then do
mbSel <- getSelectedError treeView store
theMenu <- menuNew
item0 <- menuItemNewWithLabel "Add all imports"
item0 `onActivateLeaf` do
reflectIDE addAllImports ideR
menuShellAppend theMenu item0
case mbSel of
Just sel ->
case parseNotInScope (refDescription sel) of
Nothing -> do
return ()
Just _ -> do
item1 <- menuItemNewWithLabel "Add import"
item1 `onActivateLeaf` do
reflectIDE (addImport sel [] (\ _ -> return ())) ideR
menuShellAppend theMenu item1
Nothing -> return ()
menuPopup theMenu Nothing
widgetShowAll theMenu
return True
else if button == LeftButton && click == DoubleClick
then liftIO $ do
sel <- getSelectedError treeView store
case sel of
Just ref -> reflectIDE (setCurrentError (Just ref)) ideR
otherwise -> sysMessage Normal "Error>> errorViewPopup: no selection2"
return True
else return False
errorViewPopup _ _ _ _ = throwIDE "errorViewPopup wrong event type"