-- Copyright: 2009 Betty Diegel -- License: BSD3 (see LICENSE) -- Author: Betty Diegel import Graphics.UI.WX import Graphics.UI.WXCore import Shop.Data.Item import Data.Map hiding (map, filter, (\\)) import Data.List import System.Environment import System.FilePath addSelections :: MultiListBox a -> MultiListBox a -> IO () addSelections w1 w2 = do ss <- getSelections w1 -- mapM_ logMessage ss addItems w2 ss removeItems w1 ss indices <- getIndices w2 ss set w2 [selections := indices ] -- select (ListItemSelected 1) w2 addItems :: MultiListBox a -> [ String ] -> IO () addItems w ss = do mapM_ (itemAppend w ) ss unsortedItems <- get w items set w [ items := sort unsortedItems ] removeItems :: MultiListBox a -> [ String ] -> IO () removeItems w ss = do allItems <- get w items let lessItems = allItems \\ ss set w [ items := sort lessItems ] delSelections :: MultiListBox a -> MultiListBox a -> IO () delSelections w1 w2 = putStrLn "test2" getSelections :: MultiListBox a -> IO [ String ] getSelections w = do indices <- get w selections mapM (\i -> get w (item i)) indices getIndices :: MultiListBox a -> [ String ] -> IO [ Int ] getIndices w ss = do itemsW <- get w items let ts = zip itemsW [0..] let ts' = filter ( \(s, _) -> s `elem` ss ) ts return $ map snd ts' onSave :: [ String ] -> IO () onSave ss = do let s = unlines ss writeFile "/tmp/shoplist-out" s onSaveAs :: Window a -> [ String ] -> IO () onSaveAs w ss = do let s = unlines ss homeDir <- getEnv "HOME" fp <- fileSaveDialog w True True "Open image" [("Text file",["*.txt"])] homeDir "grocery.txt" maybe (return ()) (\filePath -> writeFile filePath s) fp loadShopList :: Window a -> MultiListBox b -> MultiListBox b -> IO () loadShopList w mb1 mb2 = do homeDir <- getEnv "HOME" fp <- fileOpenDialog w True True "Load list" [("Test file",["*.txt"])] homeDir "grocery.txt" s <- maybe (return []) readFile fp let ss = lines s set mb1 [ items := ss ] removeItems mb2 ss --logSelect :: MultiListBox a -> Point b -> IO () logSelect w pt = do ss <- getSelections w logMessage ("selected items: " ++ show ss ) addNewItem :: MultiListBox a -> IO () addNewItem w = do s <- textDialog w "Add item" "Enter name of item:" "" addItems w [ s ] main :: IO () main = do start mainWindow mainWindow :: IO () mainWindow = do dataDir <- getEnv "HOME" let itemsFile = dataDir "shoplist-new" itemsList <- loadItemList itemsFile let names = keys $ createItemMap itemsList -- putStr $ show itemsList -- application frame -- f <- frame [ text := "Shopping List" ] -- file menu -- file <- menuPane [ text := "&File" ] load <- menuItem file [ text := "&Load\tCtrl+L" ] menuLine file save <- menuItem file [ text := "&Save\tCtrl+S" ] saveAs <- menuItem file [ text := "Save &As..\tCtrl+A" ] menuLine file quit <- menuQuit file [ help := "Exit application" ] -- set the appliacion menus -- set f [ menuBar := [ file ] ] -- left list -- --itemsListBox <- multiListBox f [ items := names, on select ::= logSelect, sorted := True ] itemsListBox <- multiListBox f [ items := names, sorted := True ] -- right list -- shopListBox <- multiListBox f [ items := [] ] -- button controls -- buttonPanel <- panel f [] addButton <- button buttonPanel [ text := ">>" , on command := addSelections itemsListBox shopListBox ] delButton <- button buttonPanel [ text := "<<" , on command := delSelections shopListBox itemsListBox ] -- doublClick: moves item from left list to right list -- set itemsListBox [ on doubleClick := (\pt -> addSelections itemsListBox shopListBox) ] set shopListBox [on (charKey 'n') ::= addNewItem ] -- layout -- set f [ layout := margin 20 $ column 10 [ grid 10 10 [ [ fill $ widget itemsListBox , container buttonPanel $ floatCentre $ column 5 [ widget addButton , widget delButton ] , fill $ widget shopListBox ] ] ] ] -- add mneu event handlers -- set f [ on (menu load) := loadShopList f shopListBox itemsListBox , on (menu save) := get shopListBox items >>= onSave , on (menu saveAs) := get shopListBox items >>= onSaveAs f , on (menu quit) := close f ] return ()