packages feed

hpage 0.4.8 → 0.5

raw patch · 5 files changed

+244/−83 lines, 5 files

Files

hpage.cabal view
@@ -1,5 +1,5 @@ name: hpage-version: 0.4.8+version: 0.5 cabal-version: >=1.6 build-type: Custom license: BSD3@@ -49,5 +49,5 @@     main-is: Main.hs     buildable: True     hs-source-dirs: src-    other-modules:  HPage.GUI.IDs, HPage.GUI.FreeTextWindow, HPage.GUI.Dialogs, HPage.Control, HPage.Server, HPage.Utils.Log+    other-modules:  HPage.GUI.IDs, HPage.GUI.FreeTextWindow, HPage.GUI.Dialogs, HPage.Control, HPage.Server, HPage.Utils.Log, HPage.GUI.Constants     ghc-options: -fwarn-unused-imports -fwarn-missing-fields -fwarn-incomplete-patterns
+ src/HPage/GUI/Constants.hs view
@@ -0,0 +1,8 @@+        +module HPage.GUI.Constants where++bottomString = "\10200"+bottomChar   = "\724"++charTimeout :: Int+charTimeout  = 1000
src/HPage/GUI/Dialogs.hs view
@@ -15,6 +15,33 @@                           ghcOptions :: String}     deriving (Eq, Show) +hayooDialog :: Window a -> String -> IO ()+hayooDialog win query =+    do+        dlg <- dialog win [text := "Hayoo! - work in progress"]+        htmlw <- htmlWindowCreate dlg idAny (rect (point 0 0) (sz 640 480)) 0 ""+        htmlWindowSetPage htmlw $ "<body>Waiting for Timo & Sebastian to integrate" +++                                  " \955Page and <a target=\"_blank\"" +++                                  " href=\"http://holumbus.fh-wedel.de/hayoo/hayoo.html\">Hayoo!</a> :)" +++                                  "</body>"+        set dlg [layout := fill $ widget htmlw,+                 visible := True,+                 clientSize := sz 640 480]+        return ()+--TODO: Use this or something similar:+--    htmlDialog win "Hayoo!" $ "http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:" ++ query++htmlDialog :: Window a -> String -> String -> IO ()+htmlDialog win caption url =+    do+        dlg <- dialog win [text := caption]+        htmlw <- htmlWindowCreate dlg idAny (rect (point 0 0) (sz 640 480)) 0 ""+        htmlWindowLoadPage htmlw url+        set dlg [layout := fill $ widget htmlw,+                 visible := True,+                 clientSize := sz 640 480]+        return ()+ preferencesDialog :: Window a -> String -> Preferences -> IO (Maybe Preferences) preferencesDialog win caption currentPrefs =     do
src/HPage/GUI/FreeTextWindow.hs view
@@ -9,6 +9,7 @@  import Prelude hiding (catch) import Control.Exception+import Control.Concurrent.MVar import Control.Concurrent.Process import System.FilePath import System.Directory@@ -30,6 +31,7 @@ import qualified HPage.Server as HPS import HPage.GUI.Dialogs import HPage.GUI.IDs+import HPage.GUI.Constants import HPage.Utils.Log  import Paths_hpage -- cabal locations of data files@@ -46,20 +48,24 @@ helpFile :: IO FilePath helpFile = getDataFileName "res/help/helpPage.hs" +data GUIBottom = GUIBtm { bottomDesc :: String,+                          bottomSource :: String }+ data GUIResults = GUIRes { resButton :: Button (),                            resLabel :: StaticText (),                            resValue :: TextCtrl (),                            res4Dots :: StaticText (),-                           resType  :: TextCtrl () }+                           resType  :: TextCtrl (),+                           resErrors :: Var [GUIBottom] } -data GUIContext  = GUICtx { guiWin :: Frame (),-                            guiPages :: SingleListBox (),-                            guiModules :: (Var Int, ListCtrl ()),-                            guiCode :: TextCtrl (),-                            guiResults :: GUIResults,-                            guiStatus :: StatusField,-                            guiTimer :: Var (TimerEx ()),-                            guiSearch :: FindReplaceData ()} +data GUIContext = GUICtx { guiWin :: Frame (),+                           guiPages :: SingleListBox (),+                           guiModules :: (Var Int, ListCtrl ()),+                           guiCode :: TextCtrl (),+                           guiResults :: GUIResults,+                           guiStatus :: StatusField,+                           guiTimer :: Var (TimerEx ()),+                           guiSearch :: FindReplaceData ()}   gui :: IO () gui =@@ -67,7 +73,7 @@         -- Server context         model <- HPS.start         -        win <- frame [text := "λPage"]+        win <- frame [text := "\955Page"]         imageFile "icon/hpage.tif" >>= topLevelWindowSetIconFromFile win                   set win [on closing := HPS.stop model >> propagateEvent]@@ -97,6 +103,7 @@         -- Results panel         pnlRes <- panel win []         txtValue <- textEntry pnlRes [style := wxTE_READONLY]+        varErrors <- varCreate []         txtType <- textEntry pnlRes [style := wxTE_READONLY]         btnInterpret <- button pnlRes [text := "Interpret"]         lblInterpret <- staticText pnlRes [text := "Value:"]@@ -109,7 +116,7 @@                                        fill $ widget txtType]]          -- Status bar...-        status <- statusField [text := "hello... this is λPage! type in your instructions :)"]+        status <- statusField [text := "hello... this is \955Page! type in your instructions :)"]         set win [statusBar := [status]]          -- Timer ...@@ -119,7 +126,7 @@         -- Search ...         search <- findReplaceDataCreate wxFR_DOWN         -        let guiRes = GUIRes btnInterpret lblInterpret txtValue lbl4Dots txtType+        let guiRes = GUIRes btnInterpret lblInterpret txtValue lbl4Dots txtType varErrors         let guiCtx = GUICtx win lstPages (varModsSel, lstModules) txtCode guiRes status varTimer search          let onCmd name acc = traceIO ("onCmd", name) >> acc model guiCtx @@ -133,6 +140,12 @@                                             MouseLeftDClick _ _ -> onCmd "mouseEvent" restartTimer >> propagateEvent                                             MouseRightDown _ _ -> onCmd "textContextMenu" textContextMenu                                             _ -> propagateEvent]+        set txtValue [on mouse := \e -> case e of+                                            MouseRightDown _ _ -> onCmd "valueContextMenu" valueContextMenu+                                            _ -> propagateEvent]+        set txtType [on mouse := \e -> case e of+                                            MouseRightDown _ _ -> onCmd "typeContextMenu" typeContextMenu+                                            _ -> propagateEvent]         set lstModules [on listEvent := \e -> case e of                                                 ListItemSelected idx -> varSet varModsSel idx                                                 ListItemRightClick idx -> varSet varModsSel idx >> onCmd "moduleContextMenu" moduleContextMenu@@ -166,7 +179,7 @@         menuAppend mnuEdit wxId_PREFERENCES "&Preferences...\tCtrl-," "Preferences" False          mnuHask <- menuPane [text := "Haskell"]-        menuAppend mnuHask wxId_HASK_LOAD_PKG "Load &package...\tCtrl-Shift-l" "Load Cabal Package" False+        menuAppend mnuHask wxId_HASK_LOAD_PKG "Load &package...\tCtrl-Alt-l" "Load Cabal Package" False         menuAppendSeparator mnuHask         menuAppend mnuHask wxId_HASK_LOAD "&Load modules...\tCtrl-l" "Load Modules" False         menuAppend mnuHask wxId_HASK_LOADNAME "Load modules by &name...\tCtrl-Shift-l" "Load Modules by Name" False@@ -174,10 +187,11 @@         menuAppend mnuHask wxId_HASK_RELOAD "&Reload\tCtrl-r" "Reload Modules" False         menuAppendSeparator mnuHask         menuAppend mnuHask wxId_HASK_INTERPRET "&Interpret\tCtrl-i" "Interpret the Current Expression" False+        menuAppend mnuHask wxId_HASK_NAVIGATE "Search on Ha&yoo!\tCtrl-y" "Search the Current Selection on Hayoo!" False                  mnuHelp <- menuHelp []         menuAppend mnuHelp wxId_HELP "&Help page\tCtrl-h" "Open the Help Page" False-        menuAbout mnuHelp [on command := infoDialog win "About λPage" "Author: Fernando Brujo Benavides"]+        menuAbout mnuHelp [on command := infoDialog win "About \955Page" "Author: Fernando Brujo Benavides\nWebsite: http://haskell.hpage.com"]                  set win [menuBar := [mnuPage, mnuEdit, mnuHask, mnuHelp]]         evtHandlerOnMenuCommand win wxId_NEW $ onCmd "runHP' addPage" $ runHP' HP.addPage@@ -203,6 +217,10 @@         evtHandlerOnMenuCommand win wxId_HASK_RELOAD $ onCmd "reloadModules" reloadModules         evtHandlerOnMenuCommand win wxId_PREFERENCES $ onCmd "preferences" configure         evtHandlerOnMenuCommand win wxId_HASK_INTERPRET $ onCmd "interpret" interpret+        evtHandlerOnMenuCommand win wxId_HASK_NAVIGATE $ onCmd "hayoo" hayoo+        evtHandlerOnMenuCommand win wxId_HASK_COPY $ onCmd "copyResult" copyResult+        evtHandlerOnMenuCommand win wxId_HASK_COPY_TYPE $ onCmd "copyType" copyType+        evtHandlerOnMenuCommand win wxId_HASK_EXPLAIN $ onCmd "explain" explain         evtHandlerOnMenuCommand win wxId_HELP $ onCmd "help" openHelpPage                  -- Tool bar...@@ -252,10 +270,10 @@  -- EVENT HANDLERS -------------------------------------------------------------- refreshPage, savePageAs, savePage, openPage,-    pageChange, copy, cut, paste,+    pageChange, copy, copyResult, copyType, cut, paste,     justFind, justFindNext, justFindPrev, findReplace,-    textContextMenu, moduleContextMenu,-    restartTimer, killTimer,+    textContextMenu, moduleContextMenu, valueContextMenu,+    restartTimer, killTimer, interpret, hayoo, explain,     loadPackage, loadModules, importModules, loadModulesByName, loadModulesByNameFast, reloadModules,     configure, openHelpPage :: HPS.ServerHandle -> GUIContext -> IO () @@ -271,7 +289,6 @@             i ->                 do                     itm <- get lstModules $ item i-                    debugIO ("the item", itm)                     case itm of                         [_, "Package"] ->                             menuAppend contextMenu wxId_HASK_LOAD_FAST "&Load" "Load Module" False@@ -291,39 +308,62 @@                         menuAppend browseMenu idAny err "Error" False                     Right mes ->                         flip mapM_ mes $ createMenuItem browseMenu+                menuItem contextMenu [text := "To Clipboard",+                                      on command := addToClipboard mn]+                menuAppendSeparator contextMenu                 menuAppendSub contextMenu wxId_HASK_BROWSE "&Browse" browseMenu ""-          createMenuItem m fn@(HP.MEFun _ _) =+          addToClipboard txt =             do-                item <- menuItemCreate-                menuItemSetCheckable item False-                menuItemSetText item $ show fn-                menuItemSetId item wxId_HASK_MENUELEM-                menuAppendItem m item +                tdo <- textDataObjectCreate txt+                cb <- clipboardCreate+                opened <- clipboardOpen cb+                if opened+                    then do+                        r <- clipboardSetData cb tdo+                        if r+                            then return ()+                            else errorDialog win "Error" "Clipboard operation failed"+                        clipboardClose cb+                    else+                        errorDialog win "Error" "Clipboard not ready"+          createMenuItem m fn@HP.MEFun{HP.funName = fname} =+            do+                itemMenu <- createBasicMenuItem fname+                menuAppendSub m wxId_HASK_MENUELEM (show fn) itemMenu ""           createMenuItem m HP.MEClass{HP.clsName = cn, HP.clsFuns = []} =             do-                item <- menuItemCreate-                menuItemSetCheckable item False-                menuItemSetText item $ "class " ++ cn-                menuItemSetId item wxId_HASK_MENUELEM-                menuAppendItem m item+                itemMenu <- createBasicMenuItem cn+                menuAppendSub m wxId_HASK_MENUELEM ("class " ++ cn) itemMenu ""           createMenuItem m HP.MEClass{HP.clsName = cn, HP.clsFuns = cfs} =             do                 subMenu <- menuPane []+                menuItem subMenu [text := "To Clipboard",+                                  on command := addToClipboard cn]+                menuAppendSeparator subMenu                 flip mapM_ cfs $ createMenuItem subMenu                 menuAppendSub m wxId_HASK_MENUELEM ("class " ++ cn) subMenu ""           createMenuItem m HP.MEData{HP.datName = dn, HP.datCtors = []} =             do-                item <- menuItemCreate-                menuItemSetCheckable item False-                menuItemSetText item $ "data " ++ dn-                menuItemSetId item wxId_HASK_MENUELEM-                menuAppendItem m item+                itemMenu <- createBasicMenuItem dn+                menuAppendSub m wxId_HASK_MENUELEM ("data " ++ dn) itemMenu ""           createMenuItem m HP.MEData{HP.datName = dn, HP.datCtors = dcs} =             do                 subMenu <- menuPane []+                menuItem subMenu [text := "To Clipboard",+                                  on command := addToClipboard dn]+                menuAppendSeparator subMenu                 flip mapM_ dcs $ createMenuItem subMenu                 menuAppendSub m wxId_HASK_MENUELEM ("data " ++ dn) subMenu ""+          createBasicMenuItem name =+            do+                itemMenu <- menuPane []+                menuItem itemMenu [text := "To Clipboard",+                                   on command := addToClipboard name]+                menuItem itemMenu [text := "Search on Hayoo!",+                                   on command := hayooDialog win name]+                return itemMenu + textContextMenu model guiCtx@GUICtx{guiWin = win, guiCode = txtCode} =     do         contextMenu <- menuPane []@@ -337,13 +377,50 @@                         menuAppend contextMenu wxId_COPY "&Copy\tCtrl-c" "Copy" False                         menuAppend contextMenu wxId_PASTE "&Paste\tCtrl-v" "Paste" False                         menuAppendSeparator contextMenu+                        menuAppend contextMenu wxId_HASK_NAVIGATE "Search on Ha&yoo!\tCtrl-y" "Search the Current Selection on Hayoo!" False         menuAppend contextMenu wxId_HASK_INTERPRET "&Interpret\tCtrl-i" "Interpret the Current Expression" False-                 propagateEvent         pointWithinWindow <- windowGetMousePosition win         menuPopup contextMenu pointWithinWindow win         objectDelete contextMenu +valueContextMenu model guiCtx@GUICtx{guiWin = win,+                                     guiResults = GUIRes{resValue = txtValue}} =+    do+        contextMenu <- menuPane []+        sel <- textCtrlGetStringSelection txtValue+        case sel of+            "" ->+                return ()+            _ ->+                menuAppend contextMenu wxId_HASK_COPY "Copy" "Copy" False+        if sel == bottomChar || sel == bottomString+            then menuAppend contextMenu wxId_HASK_EXPLAIN "Explain" "Explain" False+            else return ()+        propagateEvent+        pointWithinWindow <- windowGetMousePosition win+        menuPopup contextMenu pointWithinWindow win+        objectDelete contextMenu+        +typeContextMenu model guiCtx@GUICtx{guiWin = win,+                                    guiResults = GUIRes{resType = txtType}} =+    do+        contextMenu <- menuPane []+        sel <- textCtrlGetStringSelection txtType+        case sel of+            "" ->+                do+                    propagateEvent+                    objectDelete contextMenu+            _ ->+                do+                    menuAppend contextMenu wxId_HASK_COPY_TYPE "Copy" "Copy" False+                    propagateEvent+                    pointWithinWindow <- windowGetMousePosition win+                    menuPopup contextMenu pointWithinWindow win+                    objectDelete contextMenu++ pageChange model guiCtx@GUICtx{guiPages = lstPages} =     do         i <- get lstPages selection@@ -391,10 +468,14 @@  copy _model GUICtx{guiCode = txtCode} = textCtrlCopy txtCode -cut model guiCtx@GUICtx{guiCode = txtCode} = textCtrlCut txtCode >> refreshPage model guiCtx+copyResult _model GUICtx{guiResults = GUIRes{resValue = txtValue}} = textCtrlCopy txtValue -paste model guiCtx@GUICtx{guiCode = txtCode} = textCtrlPaste txtCode >> refreshPage model guiCtx+copyType _model GUICtx{guiResults = GUIRes{resType = txtType}} = textCtrlCopy txtType +cut model guiCtx@GUICtx{guiCode = txtCode} = textCtrlCut txtCode >> refreshExpr model guiCtx++paste model guiCtx@GUICtx{guiCode = txtCode} = textCtrlPaste txtCode >> refreshExpr model guiCtx+ justFind model guiCtx = openFindDialog model guiCtx "Find..." dialogDefaultStyle  justFindNext model guiCtx@GUICtx{guiSearch = search} =@@ -436,7 +517,7 @@                                     absPath <- canonicalizePath setupConfig                                     let dir = joinPath . reverse . drop 2 . reverse $ splitDirectories absPath                                     setCurrentDirectory dir-                                    frameSetTitle win $ "λPage - " ++ prettyShow pkg+                                    frameSetTitle win $ "\955Page - " ++ prettyShow pkg                         refreshPage model guiCtx   where prettyShow PackageIdentifier{pkgName = PackageName pkgname,                                      pkgVersion = pkgvsn} = pkgname ++ "-" ++ showVersion pkgvsn@@ -521,7 +602,7 @@         txt <- readFile f         set txtCode [text := txt]         -- Refresh the current expression box-        refreshExpr model guiCtx True+        refreshExpr model guiCtx  refreshPage model guiCtx@GUICtx{guiWin = win,                                 guiPages = lstPages,@@ -568,7 +649,6 @@                         pms' = map (\m -> (3, [m, "Package"])) $                                         flip filter pms $ \pm -> all (\xm -> HP.modName xm /= pm) ms                         allms = zip [0..] (ims' ++ ms' ++ pms')-                    debugIO ("allms", allms)                     itemsDelete lstModules                     (flip mapM) allms $ \(idx, (img, m@(mn:_))) ->                                                 listCtrlInsertItemWithLabel lstModules idx mn img >>                                                @@ -582,7 +662,7 @@                     set status [text := ""]                                          -- Refresh the current expression box-                    refreshExpr model guiCtx True+                    refreshExpr model guiCtx  runHP' ::  HP.HPage () -> HPS.ServerHandle -> GUIContext -> IO () runHP' a = runHP $ a >>= return . Right@@ -597,24 +677,48 @@             Right () ->                 refreshPage model guiCtx -interpret model guiCtx@GUICtx{guiResults = GUIRes{resLabel = lblInterpret,+explain model guiCtx@GUICtx{guiWin = win,+                            guiResults = GUIRes{resValue = txtValue,+                                                resErrors = varErrors}} =+    do+        sel <- textCtrlGetStringSelection txtValue+        if sel == bottomChar || sel == bottomString+            then do+                    txt <- get txtValue text+                    ip <- textCtrlGetInsertionPoint txtValue+                    errs <- varGet varErrors+                    let prevTxt = take ip txt+                        isBottom c = [c] == bottomChar || [c] == bottomString+                        errNo = length $ filter isBottom prevTxt+                        err = if length errs > errNo+                                then bottomDesc $ errs !! errNo+                                else "Unknown"+                    if sel == bottomChar+                        then errorDialog win "Bottom Char" err+                        else errorDialog win "Bottom String" err+            else return ()++hayoo model guiCtx@GUICtx{guiCode = txtCode, guiWin = win} =+    textCtrlGetStringSelection txtCode >>= hayooDialog win++interpret model guiCtx@GUICtx{guiResults = GUIRes{resLabel  = lblInterpret,                                                   resButton = btnInterpret,-                                                  resValue = txtValue,-                                                  res4Dots = lbl4Dots,-                                                  resType = txtType},+                                                  resValue  = txtValue,+                                                  res4Dots  = lbl4Dots,+                                                  resType   = txtType,+                                                  resErrors = varErrors},                               guiCode = txtCode, guiWin = win} =     do         sel <- textCtrlGetStringSelection txtCode         let runner = case sel of                         "" -> tryIn                         sl -> runTxtHPSelection sl-        refreshExpr model guiCtx False+        refreshExpr model guiCtx         res <- runner model HP.interpret         case res of             Left err ->                 do                     warningDialog win "Error" err-                    set btnInterpret [enabled := True]             Right interp ->                 if HP.isIntType interp                     then do@@ -627,38 +731,60 @@                         set txtType [visible := True, text := HP.intType interp]                         set lblInterpret [text := "Value:"]                         -- now we fill the textbox --+                        varSet varErrors []                         set txtValue [text := ""]-                        prevOnCmd <- get btnInterpret $ on command-                        prevText  <- get btnInterpret text-                        let prevAttrs = [on command := prevOnCmd,-                                         text := prevText]-                        debugIO "++> Spawning the value filler..."-                        vfHandle <- spawn . valueFiller $ HP.intValue interp-                        debugIO "++> Value filler spawned"-                        set btnInterpret [text := "Cancel",-                                          on command := kill vfHandle >> set btnInterpret prevAttrs]+                        spawn . valueFiller $ HP.intValue interp+                        return ()     where valueFiller :: String -> Process a ()           valueFiller val =               do-                    let bottomString = "_|_"-                        bottomChar   = "_i_"-                    liftDebugIO "++> starting loop..."+                    prevOnCmd <- liftIO $ get btnInterpret $ on command+                    myself <- self+                    let revert = set btnInterpret [on command := prevOnCmd,+                                                   text := "Interpret"]+                    liftIO $ set btnInterpret [text := "Cancel",+                                               on command := do+                                                                spawn $ liftIO revert >> kill myself+                                                                return ()]                     h <- liftIO $ try (case val of                                             [] -> return []                                             (c:_) -> return [c])-                    --liftDebugIO ("++> h =", h)                     case h of                         Left (ErrorCall desc) ->-                            liftIO $ debugIO ("++> Left", desc) >> addText bottomString >> return ()+                            liftIO $ do+                                        varUpdate varErrors (++ [GUIBtm desc val])+                                        addText bottomString+                                        revert                         Right [] ->-                            liftIO $ debugIO "++> done" >> return ()+                            liftIO revert                         Right t ->                             do-                                liftIO $ catch (addText t) $ \(ErrorCall _desc) -> addText bottomChar-                                liftDebugIO "++> restarting"+                                ready <- liftIO newEmptyMVar+                                cfh <- liftIO . spawn $ charFiller t ready+                                let killCmd =+                                        do+                                            stillRunning <- isEmptyMVar ready+                                            if stillRunning+                                                then do+                                                        kill cfh+                                                        varUpdate varErrors (++ [GUIBtm "Timed Out" t])+                                                        addText bottomChar+                                                        tryPutMVar ready ()+                                                        return ()+                                                else+                                                    return ()+                                timeKiller <- liftIO $ timer win [interval := charTimeout,+                                                                  on command := killCmd]+                                liftIO $ readMVar ready+                                liftIO $ timerOnCommand timeKiller $ return ()                                 valueFiller $ tail val+          charFiller :: String -> MVar () -> Process a ()+          charFiller t r = liftIO $ do+                                     catch (addText t) $ \(ErrorCall desc) ->+                                                            varUpdate varErrors (++ [GUIBtm desc t]) >>+                                                            addText bottomChar+                                     putMVar r ()           addText t = do-                        debugIO ("Adding", t)                         orig <- get txtValue text                         set txtValue [text := orig ++ t]  @@ -666,7 +792,6 @@                      HP.HPage (Either HP.InterpreterError HP.Interpretation) -> IO (Either ErrorString HP.Interpretation) runTxtHPSelection s model hpacc =     do-        debugIO ("evaluating selection", s)         piRes <- tryIn' model HP.getPageIndex         added <- tryIn' model $ HP.addPage         case added of@@ -682,11 +807,9 @@                         tryIn' model $ HP.closePage >> HP.setPageIndex cpi                          return res -refreshExpr :: HPS.ServerHandle -> GUIContext -> Bool -> IO ()-refreshExpr model guiCtx@GUICtx{guiResults = GUIRes{resValue = txtValue,-                                                    resType = txtType},-                                guiCode = txtCode,-                                guiWin = win} forceClear =+refreshExpr :: HPS.ServerHandle -> GUIContext -> IO ()+refreshExpr model guiCtx@GUICtx{guiCode = txtCode,+                                guiWin = win} =    do         txt <- get txtCode text         ip <- textCtrlGetInsertionPoint txtCode@@ -696,10 +819,8 @@         case res of             Left err ->                 warningDialog win "Error" err-            Right changed ->-                if changed || forceClear-                    then mapM_ (flip set [text := ""]) [txtValue, txtType]-                    else debugIO "dummy refreshExpr"+            Right _ ->+                debugIO "refreshExpr done"                  killTimer model guiCtx @@ -708,7 +829,7 @@ restartTimer model guiCtx@GUICtx{guiWin = win, guiTimer = varTimer} =     do         newRefreshTimer <- timer win [interval := 1000,-                                      on command := refreshExpr model guiCtx False]+                                      on command := refreshExpr model guiCtx]         refreshTimer <- varSwap varTimer newRefreshTimer         timerOnCommand refreshTimer $ return () @@ -778,7 +899,7 @@             Just ip ->                 do                     textCtrlSetSelection txtCode (length s + ip) ip-                    refreshExpr model guiCtx False +                    refreshExpr model guiCtx   findReplaceButton model guiCtx@GUICtx{guiCode = txtCode,                                       guiWin = win,@@ -796,7 +917,7 @@                 do                     textCtrlReplace txtCode ip (length s + ip) r                     textCtrlSetSelection txtCode (length r + ip) ip-                    refreshExpr model guiCtx False+                    refreshExpr model guiCtx          findReplaceAllButton _model GUICtx{guiCode = txtCode,                                    guiSearch = search} =
src/HPage/GUI/IDs.hs view
@@ -32,8 +32,9 @@ wxId_CLOSE_ALL      = 5018  wxId_HASK_LOAD, wxId_HASK_LOADNAME, wxId_HASK_LOAD_FAST, wxId_HASK_RELOAD,-    wxId_HASK_INTERPRET,-    wxId_HASK_ADD, wxId_HASK_LOAD_PKG, wxId_HASK_MENUELEM, wxId_HASK_BROWSE :: Int+    wxId_HASK_INTERPRET, wxId_HASK_NAVIGATE,+    wxId_HASK_ADD, wxId_HASK_LOAD_PKG, wxId_HASK_MENUELEM, wxId_HASK_BROWSE,+    wxId_HASK_COPY, wxId_HASK_COPY_TYPE, wxId_HASK_EXPLAIN :: Int wxId_HASK_LOAD      = 5300 wxId_HASK_LOADNAME  = 5301 wxId_HASK_RELOAD    = 5302@@ -42,4 +43,8 @@ wxId_HASK_LOAD_PKG  = 5305 wxId_HASK_LOAD_FAST = 5306 wxId_HASK_BROWSE    = 5307-wxId_HASK_MENUELEM  = 5310+wxId_HASK_COPY      = 5308+wxId_HASK_COPY_TYPE = 5309+wxId_HASK_EXPLAIN   = 5310+wxId_HASK_NAVIGATE  = 5311+wxId_HASK_MENUELEM  = 5320