vcsgui 0.1.3.0 → 0.2.1.0
raw patch · 17 files changed
+555/−338 lines, 17 filesdep +gi-gtkdep +gi-gtk-hsdep +haskell-gi-basedep −gtkdep −gtk3dep ~basedep ~process
Dependencies added: gi-gtk, gi-gtk-hs, haskell-gi-base
Dependencies removed: gtk, gtk3
Dependency ranges changed: base, process
Files
- src/Main.hs +3/−3
- src/VCSGui/Common/Commit.hs +32/−24
- src/VCSGui/Common/ConflictsResolved.hs +4/−3
- src/VCSGui/Common/Error.hs +13/−2
- src/VCSGui/Common/FilesInConflict.hs +78/−46
- src/VCSGui/Common/GtkHelper.hs +109/−64
- src/VCSGui/Common/Log.hs +38/−18
- src/VCSGui/Common/SetupConfig.hs +33/−14
- src/VCSGui/Git/Commit.hs +28/−18
- src/VCSGui/Git/Log.hs +15/−8
- src/VCSGui/Mercurial/Commit.hs +29/−17
- src/VCSGui/Mercurial/Log.hs +0/−1
- src/VCSGui/Svn/AskPassword.hs +20/−11
- src/VCSGui/Svn/Checkout.hs +3/−2
- src/VCSGui/Svn/Commit.hs +25/−14
- src/exe/askpass/Main.hs +7/−4
- vcsgui.cabal +118/−89
src/Main.hs view
@@ -24,8 +24,8 @@ import qualified VCSGui.Git.Commit as GitCommit import qualified VCSGui.Mercurial.Commit as MercurialCommit import qualified VCSGui.Mercurial.Log as MercurialLog-import Graphics.UI.Gtk import Control.Monad.Trans(liftIO)+import qualified GI.Gtk.Functions as Gtk (main, init) -- --svn --@@ -165,10 +165,10 @@ --{- main = do- initGUI+ Gtk.init Nothing runWithConfig $ MercurialLog.showLogGUI- mainGUI+ Gtk.main where runWithConfig = Wrapper.runVcs $ Wrapper.makeConfig (Just cwdMercurial) Nothing Nothing ---}
src/VCSGui/Common/Commit.hs view
@@ -25,7 +25,6 @@ import qualified VCSWrapper.Common as Wrapper import qualified VCSGui.Common.GtkHelper as H-import Graphics.UI.Gtk import Control.Monad.Trans(liftIO) import Control.Monad import Control.Monad.Reader@@ -33,6 +32,15 @@ import Paths_vcsgui(getDataFileName) import qualified Data.Text as T (unpack, pack) import Data.Text (Text)+import GI.Gtk.Objects.TreeView (TreeView(..))+import Data.GI.Gtk.ModelView.SeqStore+ (seqStoreAppend, seqStoreClear, seqStoreToList, SeqStore(..))+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Objects.Widget (widgetShowAll)+import GI.Gtk.Objects.Builder (builderGetObject, Builder(..))+import Data.GI.Base.BasicTypes+ (ManagedPtr(..), NullToNothing(..), GObject)+import Data.GI.Base.ManagedPtr (unsafeCastTo) -- -- glade path and object accessors@@ -55,9 +63,9 @@ -> [Option] -- ^ options (this is currently not implemented i.e. '[]' is passed) -> Wrapper.Ctx () --- | fn to set listStore model for treeview+-- | fn to set seqStore model for treeview type TreeViewSetter = TreeView- -> Wrapper.Ctx (ListStore SCFile)+ -> Wrapper.Ctx (SeqStore SCFile) data CommitGUI = CommitGUI {@@ -110,7 +118,7 @@ liftIO $ H.registerClose $ windowCommit gui liftIO $ H.registerCloseAction (actCancel gui) (windowCommit gui) config <- ask- liftIO $ on (H.getItem (actCommit gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actCommit gui)) $ do let (store,_) = H.getItem (treeViewFiles gui) selectedFiles <- getSelectedFiles store mbMsg <- H.get (txtViewMsg gui)@@ -129,7 +137,7 @@ -loadCommitGUI :: TreeViewSetter -- ^ fn to set listStore model for treeview+loadCommitGUI :: TreeViewSetter -- ^ fn to set seqStore model for treeview -> Wrapper.Ctx CommitGUI loadCommitGUI setUpTreeView = do gladepath <- liftIO getGladepath@@ -145,9 +153,9 @@ ---- HELPERS ---- -getSelectedFiles :: ListStore SCFile -> IO [FilePath]-getSelectedFiles listStore = do- listedFiles <- listStoreToList listStore+getSelectedFiles :: SeqStore SCFile -> IO [FilePath]+getSelectedFiles seqStore = do+ listedFiles <- seqStoreToList seqStore let selectedFiles = map (\scf -> filePath scf ) $ filter (\scf -> selected scf) listedFiles return (selectedFiles)@@ -156,39 +164,39 @@ -> Text -> TreeViewSetter -> Wrapper.Ctx (H.TreeViewItem SCFile)-getTreeViewFromGladeCustomStore builder name setupListStore = do- (_, tView) <- liftIO $ wrapWidget builder castToTreeView name- store <- setupListStore tView- let getter = getFromListStore (store, tView)- setter = setToListStore (store, tView)+getTreeViewFromGladeCustomStore builder name setupSeqStore = do+ (_, tView) <- liftIO $ wrapWidget builder TreeView name+ store <- setupSeqStore tView+ let getter = getFromSeqStore (store, tView)+ setter = setToSeqStore (store, tView) return (name, (store, tView), (getter, setter)) --- --- same as gtkhelper, but avoiding exposing it ----wrapWidget :: GObjectClass objClass =>+wrapWidget :: GObject objClass => Builder- -> (GObject -> objClass)+ -> (ManagedPtr objClass -> objClass) -> Text -> IO (Text, objClass)-wrapWidget builder cast name = do+wrapWidget builder constructor name = do putStrLn $ " cast " ++ T.unpack name- gobj <- builderGetObject builder cast name+ gobj <- nullToNothing (builderGetObject builder name) >>= unsafeCastTo constructor . fromJust return (name, gobj) -getFromListStore :: (ListStore a, TreeView)+getFromSeqStore :: (SeqStore a, TreeView) -> IO (Maybe [a])-getFromListStore (store, _) = do- list <- listStoreToList store+getFromSeqStore (store, _) = do+ list <- seqStoreToList store if null list then return Nothing else return $ Just list -setToListStore :: (ListStore a, TreeView)+setToSeqStore :: (SeqStore a, TreeView) -> [a] -> IO ()-setToListStore (store, view) newList = do- listStoreClear store- mapM_ (listStoreAppend store) newList+setToSeqStore (store, view) newList = do+ seqStoreClear store+ mapM_ (seqStoreAppend store) newList return ()
src/VCSGui/Common/ConflictsResolved.hs view
@@ -21,8 +21,9 @@ import Paths_vcsgui(getDataFileName) import qualified VCSGui.Common.GtkHelper as H import Control.Monad.Trans(liftIO)-import Graphics.UI.Gtk import Control.Monad.Reader(ask)+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Objects.Widget (widgetShowAll) -- -- glade path and object accessors@@ -50,11 +51,11 @@ -- connect actions liftIO $ H.registerClose $ windowConflictsResolved gui config <- ask- liftIO $ on (H.getItem (actConflictsNotResolved gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actConflictsNotResolved gui)) $ do Wrapper.runVcs config $ handler False H.closeWin (windowConflictsResolved gui) - liftIO $ on (H.getItem (actConflictsResolved gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actConflictsResolved gui)) $ do Wrapper.runVcs config $ handler True H.closeWin (windowConflictsResolved gui)
src/VCSGui/Common/Error.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- --@@ -17,14 +18,24 @@ showErrorGUI ) where -import Graphics.UI.Gtk import Data.Text (Text)+import GI.Gtk.Objects.Dialog (constructDialogUseHeaderBar, dialogRun)+import GI.Gtk.Objects.Widget (widgetDestroy)+import Data.GI.Base (new')+import GI.Gtk.Objects.MessageDialog+ (constructMessageDialogMessageType, constructMessageDialogButtons,+ setMessageDialogText, MessageDialog(..))+import GI.Gtk.Enums (ButtonsType(..), MessageType(..)) -- | Displays a simple window displaying given 'String' as an error message. showErrorGUI :: Text -- ^ Message to display. -> IO () showErrorGUI msg = do- dialog <- messageDialogNew Nothing [] MessageError ButtonsOk msg+ dialog <- new' MessageDialog [+ constructDialogUseHeaderBar 0,+ constructMessageDialogMessageType MessageTypeError,+ constructMessageDialogButtons ButtonsTypeOk]+ setMessageDialogText dialog msg _ <- dialogRun dialog widgetDestroy dialog return ()
src/VCSGui/Common/FilesInConflict.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-} ----------------------------------------------------------------------------- -- -- Module : VCSGui.Common.FilesInConflict@@ -25,13 +26,38 @@ import qualified VCSGui.Common.Process as Process import qualified VCSGui.Common.ConflictsResolved as ConflictsResolvedGUI import qualified VCSGui.Common.Error as Error-import Graphics.UI.Gtk import Control.Monad.Trans(liftIO) import Control.Monad import Control.Monad.Reader import Paths_vcsgui(getDataFileName) import Data.Text (Text) import qualified Data.Text as T (unpack, pack)+import GI.Gtk.Objects.TreeView (treeViewSetModel, TreeView(..))+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Enums (ResponseType(..), FileChooserAction(..))+import GI.Gtk.Objects.Widget (widgetDestroy, widgetShowAll)+import GI.Gtk.Objects.CellRendererText (cellRendererTextNew)+import GI.Gtk.Objects.CellRendererToggle+ (onCellRendererToggleToggled, cellRendererToggleNew)+import GI.Gtk.Interfaces.TreeModel (treeModelGetIterFromString)+import GI.Gtk.Objects.Builder (builderGetObject, Builder(..))+import Data.GI.Base.BasicTypes+ (ManagedPtr(..), NullToNothing(..), GObject)+import Data.GI.Base.ManagedPtr (unsafeCastTo)+import Data.GI.Gtk.ModelView.SeqStore+ (seqStoreAppend, seqStoreClear, seqStoreToList,+ seqStoreSetValue, seqStoreIterToIndex, seqStoreGetValue,+ seqStoreNew, SeqStore(..))+import GI.Gtk.Objects.Window+ (setWindowTransientFor, setWindowTitle, Window(..))+import Data.GI.Base (new', nullToNothing)+import GI.Gtk.Objects.FileChooserDialog (FileChooserDialog(..))+import GI.Gtk.Objects.Dialog (dialogRun, dialogAddButton)+import GI.Gtk.Interfaces.FileChooser+ (fileChooserGetFilename, setFileChooserAction)+import Data.Maybe (fromJust)+import GI.Gtk+ (setCellRendererToggleActive, setCellRendererTextText) -- -- glade path and object accessors@@ -52,7 +78,7 @@ -- | Handler being called after all files have been resolved and resolved button is pressed type Handler = Wrapper.Ctx() --- fn to set listStore model for treeview+-- fn to set seqStore model for treeview type TreeViewSetter = (Maybe FilePath) -- ^ Maybe cwd -> [FilePath] -- ^ conflicting files -> (FilePath -> Wrapper.Ctx [FilePath]) -- ^ fn receiving a path to a conflicting file and returning all conflicting files involved in the conflict (max 4)@@ -60,7 +86,7 @@ -> (Either Merge.MergeTool Merge.MergeToolSetter) -- ^ either a mergetool or fn to set one -> H.TextEntryItem -- ^ the entry to get the path to the mergetool from -> TreeView -- ^ the treeview to set the model to- -> Wrapper.Ctx (ListStore SCFile)+ -> Wrapper.Ctx (SeqStore SCFile) -- GUI storing accessible elements data GUI = GUI {@@ -81,7 +107,7 @@ -- | Shows a GUI showing conflicting files and providing means to resolve the conflicts.-showFilesInConflictGUI :: (Maybe TreeViewSetter) -- ^ fn to set listStore model for treeview, Nothing for default+showFilesInConflictGUI :: (Maybe TreeViewSetter) -- ^ fn to set seqStore model for treeview, Nothing for default -> [FilePath] -- ^ conflicting files -> (FilePath -> Wrapper.Ctx [FilePath]) -- ^ fn receiving a path to a conflicting file and returning all conflicting files involved in the conflict (max 4) -> (FilePath -> Wrapper.Ctx ()) -- ^ fn to mark files as resolved in VCS@@ -105,11 +131,11 @@ liftIO $ H.registerClose $ windowFilesInConflict gui liftIO $ H.registerCloseAction (actCancel gui) (windowFilesInConflict gui) config <- ask- liftIO $ on (H.getItem (actResolved gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actResolved gui)) $ do --TODO check if all files have been resolved Wrapper.runVcs config $ actResolvedHandler H.closeWin (windowFilesInConflict gui)- liftIO $ on (H.getItem (actBrowsePath gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actBrowsePath gui)) $ do mbPath <- showFolderChooserDialog "Select executable" (H.getItem $ windowFilesInConflict gui) FileChooserActionOpen case mbPath of Nothing -> return ()@@ -126,8 +152,8 @@ return () -loadGUI :: (H.TextEntryItem -> TreeView -> Wrapper.Ctx (ListStore SCFile))- -- ^ (The entry to get the path to the mergetool from. , treeview to setup, fn to set listStore model for treeview+loadGUI :: (H.TextEntryItem -> TreeView -> Wrapper.Ctx (SeqStore SCFile))+ -- ^ (The entry to get the path to the mergetool from. , treeview to setup, fn to set seqStore model for treeview -> Wrapper.Ctx GUI loadGUI setUpTreeView = do gladepath <- liftIO getGladepath@@ -146,31 +172,31 @@ config <- ask liftIO $ do -- create model- listStore <- listStoreNew [+ seqStore <- seqStoreNew [ (SCFile fileName (False)) | fileName <- conflictingFiles]- treeViewSetModel listView listStore+ treeViewSetModel listView (Just seqStore) - let treeViewItem = (listStore, listView)+ let treeViewItem = (seqStore, listView) renderer <- cellRendererTextNew H.addColumnToTreeView' treeViewItem renderer "File"- $ \scf -> [cellText := T.pack $ filePath scf]+ $ \cell scf -> setCellRendererTextText cell . T.pack $ filePath scf renderer <- cellRendererToggleNew H.addColumnToTreeView' treeViewItem renderer "Resolved"- $ \scf -> [cellToggleActive := isResolved scf]+ $ \cell scf -> setCellRendererToggleActive cell $ isResolved scf -- connect select action- on renderer cellToggled $ \(columnId :: Text) -> do+ onCellRendererToggleToggled renderer $ \(columnId :: Text) -> do putStrLn $ "Checkbutton clicked at column " ++ (show columnId) --TODO only call tool if button is not checked, move this code to being called if a click on row is received- let callTool' = (\path -> Wrapper.runVcs config $ callTool columnId listStore path)+ let callTool' = (\path -> Wrapper.runVcs config $ callTool columnId seqStore path) mbPath <- H.get entPath case mbPath of Nothing -> Error.showErrorGUI "MergeTool not set. Set MergeTool first."@@ -178,28 +204,29 @@ return () - return listStore+ return seqStore where- callTool columnId listStore pathToTool = do+ callTool columnId seqStore pathToTool = do config <- ask- Just treeIter <- liftIO $ treeModelGetIterFromString listStore columnId- value <- liftIO $ listStoreGetValue listStore $ listStoreIterToIndex treeIter+ (True, treeIter) <- liftIO $ treeModelGetIterFromString seqStore columnId+ value <- liftIO $ seqStoreGetValue seqStore =<< seqStoreIterToIndex treeIter filesToResolve <- filesToResolveGetter $ filePath value resolvedByTool <- liftIO $ Process.exec mbcwd pathToTool $ map T.pack filesToResolve- let setResolved' = setResolved listStore treeIter value+ let setResolved' = setResolved seqStore treeIter value case resolvedByTool of False -> ConflictsResolvedGUI.showConflictsResolvedGUI (\resolved -> setResolved' resolved)- True -> setResolved listStore treeIter value True+ True -> setResolved seqStore treeIter value True return()- setResolved listStore treeIter oldValue isResolved = do+ setResolved seqStore treeIter oldValue isResolved = do let fp = filePath oldValue case isResolved of False -> return () True -> resolveMarker fp let newValue = (\(SCFile fp b) -> SCFile fp isResolved) oldValue- liftIO $ listStoreSetValue listStore (listStoreIterToIndex treeIter) newValue+ n <- seqStoreIterToIndex treeIter+ liftIO $ seqStoreSetValue seqStore n newValue return () ----@@ -208,41 +235,41 @@ getTreeViewFromGladeCustomStore :: Builder -> Text- -> (TreeView -> Wrapper.Ctx (ListStore SCFile)) -- ^ fn defining how to setup the liststore+ -> (TreeView -> Wrapper.Ctx (SeqStore SCFile)) -- ^ fn defining how to setup the liststore -> Wrapper.Ctx (H.TreeViewItem SCFile)-getTreeViewFromGladeCustomStore builder name setupListStore = do- (_, tView) <- liftIO $ wrapWidget builder castToTreeView name- store <- setupListStore tView- let getter = getFromListStore (store, tView)- setter = setToListStore (store, tView)+getTreeViewFromGladeCustomStore builder name setupSeqStore = do+ (_, tView) <- liftIO $ wrapWidget builder TreeView name+ store <- setupSeqStore tView+ let getter = getFromSeqStore (store, tView)+ setter = setToSeqStore (store, tView) return (name, (store, tView), (getter, setter)) --- --- same as gtkhelper, but avoiding exposing it ----wrapWidget :: GObjectClass objClass =>+wrapWidget :: GObject objClass => Builder- -> (GObject -> objClass)+ -> (ManagedPtr objClass -> objClass) -> Text -> IO (Text, objClass)-wrapWidget builder cast name = do+wrapWidget builder constructor name = do putStrLn $ " cast " ++ T.unpack name- gobj <- builderGetObject builder cast name+ gobj <- nullToNothing (builderGetObject builder name) >>= unsafeCastTo constructor . fromJust return (name, gobj) -getFromListStore :: (ListStore a, TreeView)+getFromSeqStore :: (SeqStore a, TreeView) -> IO (Maybe [a])-getFromListStore (store, _) = do- list <- listStoreToList store+getFromSeqStore (store, _) = do+ list <- seqStoreToList store if null list then return Nothing else return $ Just list -setToListStore :: (ListStore a, TreeView)+setToSeqStore :: (SeqStore a, TreeView) -> [a] -> IO ()-setToListStore (store, view) newList = do- listStoreClear store- mapM_ (listStoreAppend store) newList+setToSeqStore (store, view) newList = do+ seqStoreClear store+ mapM_ (seqStoreAppend store) newList return () -- HELPER@@ -253,13 +280,18 @@ -> FileChooserAction -> IO (Maybe FilePath) showFolderChooserDialog title parent fcAction = do- dialog <- fileChooserDialogNew (Just title) (Just parent) fcAction [("Cancel", ResponseCancel), ("Select", ResponseAccept)]+ dialog <- new' FileChooserDialog []+ setWindowTitle dialog title+ dialogAddButton dialog "gtk-cancel" (fromIntegral $ fromEnum ResponseTypeCancel)+ dialogAddButton dialog "Select" (fromIntegral $ fromEnum ResponseTypeAccept)+ setWindowTransientFor dialog parent+ setFileChooserAction dialog fcAction response <- dialogRun dialog- case response of- ResponseCancel -> widgetDestroy dialog >> return Nothing- ResponseDeleteEvent -> widgetDestroy dialog >> return Nothing- ResponseAccept -> do- f <- fileChooserGetFilename dialog+ case toEnum $ fromIntegral response of+ ResponseTypeCancel -> widgetDestroy dialog >> return Nothing+ ResponseTypeDeleteEvent -> widgetDestroy dialog >> return Nothing+ ResponseTypeAccept -> do+ f <- nullToNothing $ fileChooserGetFilename dialog widgetDestroy dialog return f
src/VCSGui/Common/GtkHelper.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-} ----------------------------------------------------------------------------- -- -- Module : VCSGui.Common.GtkHelper@@ -61,14 +62,56 @@ , ButtonItem ) where -import qualified Graphics.UI.Gtk as Gtk- import System.Directory import Control.Monad.Trans(liftIO) import System.IO (hPutStrLn, stderr) import VCSGui.Common.Helpers (emptyTextToNothing) import Data.Text (Text)-import qualified Data.Text as T (unpack)+import qualified Data.Text as T (pack, unpack)+import qualified GI.Gtk.Objects.Window as Gtk (Window(..))+import qualified GI.Gtk.Objects.Action as Gtk+ (onActionActivate, Action(..))+import qualified GI.Gtk.Objects.Label as Gtk+ (labelSetText, Label(..))+import qualified GI.Gtk.Objects.Entry as Gtk+ (entrySetText, entryGetText, Entry(..))+import qualified GI.Gtk.Objects.ComboBox as Gtk (ComboBox(..))+import qualified GI.Gtk.Objects.TextView as Gtk+ (textViewGetBuffer, TextView(..))+import qualified Data.GI.Gtk.ModelView.SeqStore as Gtk+ (seqStoreToList, seqStoreNew, seqStoreAppend, seqStoreClear,+ SeqStore(..))+import qualified GI.Gtk.Objects.TreeView as Gtk+ (treeViewAppendColumn, treeViewSetModel, TreeView(..))+import qualified GI.Gtk.Objects.CheckButton as Gtk+ (CheckButton(..))+import qualified GI.Gtk.Objects.Button as Gtk+ (buttonSetLabel, buttonGetLabel, Button(..))+import qualified GI.Gtk.Objects.Builder as Gtk+ (builderGetObject, builderAddFromFile, builderNew, Builder(..))+import qualified Data.GI.Gtk.ComboBox as Gtk+ (comboBoxGetModelText, comboBoxGetActiveText, comboBoxSetModelText)+import qualified GI.Gtk.Objects.TextBuffer as Gtk+ (textBufferGetText, textBufferGetEndIter, textBufferGetStartIter,+ textBufferSetText)+import qualified GI.Gtk.Structs.TextIter as Gtk (textIterEqual)+import qualified GI.Gtk.Objects.ToggleButton as Gtk+ (toggleButtonSetActive, toggleButtonGetActive)+import qualified GI.Gtk.Objects.Widget as Gtk+ (onWidgetDeleteEvent, widgetHide)+import qualified GI.Gtk.Functions as Gtk (mainQuit)+import qualified GI.Gtk.Objects.CellRenderer as Gtk (IsCellRenderer)+import qualified GI.Gtk.Objects.TreeViewColumn as Gtk+ (treeViewColumnPackStart, setTreeViewColumnTitle,+ treeViewColumnNew)+import qualified Data.GI.Gtk.ModelView.CellLayout as Gtk+ (cellLayoutSetDataFunction)+import qualified GI.Gtk.Objects.CellRendererText as Gtk+ (cellRendererTextNew, CellRendererText(..))+import qualified Data.GI.Base.BasicTypes as Gtk (GObject)+import Data.GI.Base.ManagedPtr (unsafeCastTo)+import Data.GI.Base.BasicTypes (ManagedPtr(..), NullToNothing(..))+import Data.Maybe (fromJust) -- Typesynonyms type WindowItem = (Text, Gtk.Window, ())@@ -77,7 +120,7 @@ type TextEntryItem = (Text, Gtk.Entry, (IO (Maybe Text), Text -> IO ())) type ComboBoxItem = (Text, Gtk.ComboBox, (IO (Maybe Text), [Text] -> IO ())) type TextViewItem = (Text, Gtk.TextView, (IO (Maybe Text), Text -> IO ()))-type TreeViewItem a = (Text, (Gtk.ListStore a, Gtk.TreeView), (IO (Maybe [a]), [a] -> IO ()))+type TreeViewItem a = (Text, (Gtk.SeqStore a, Gtk.TreeView), (IO (Maybe [a]), [a] -> IO ())) type CheckButtonItem = (Text, Gtk.CheckButton, (IO Bool, Bool -> IO())) type ButtonItem = (Text, Gtk.Button, (IO Text, Text -> IO())) @@ -109,7 +152,7 @@ -> IO Gtk.Builder openGladeFile fn = do builder <- Gtk.builderNew- Gtk.builderAddFromFile builder fn+ Gtk.builderAddFromFile builder $ T.pack fn return builder -- | Get a 'WindowItem' from a gladefile.@@ -117,7 +160,7 @@ -> Text -- ^ name of the window to get as specified in the gladefile. -> IO WindowItem getWindowFromGlade builder name = do- (a, b) <- wrapWidget builder Gtk.castToWindow name+ (a, b) <- wrapWidget builder Gtk.Window name return (a, b, ()) -- | Get an 'ActionItem' from a gladefile.@@ -125,7 +168,7 @@ -> Text -- ^ name of the action to get as specified in the gladefile. -> IO ActionItem getActionFromGlade builder name = do- (a, b) <- wrapWidget builder Gtk.castToAction name+ (a, b) <- wrapWidget builder Gtk.Action name return (a, b, ()) -- | Get an 'LabelItem' from a gladefile.@@ -133,7 +176,7 @@ -> Text -- ^ name of the label to get as specified in the gladefile. -> IO LabelItem getLabelFromGlade builder name = do- (_, entry) <- wrapWidget builder Gtk.castToLabel name+ (_, entry) <- wrapWidget builder Gtk.Label name let getter = error "don't call get on a gtk label!" :: IO (Maybe Text) setter val = Gtk.labelSetText entry val :: IO () return (name, entry, (getter, setter))@@ -143,7 +186,7 @@ -> Text -- ^ name of the button to get as specified in the gladefile. -> IO ButtonItem getButtonFromGlade builder name = do- (_,btn) <- wrapWidget builder Gtk.castToButton name+ (_,btn) <- wrapWidget builder Gtk.Button name let getter = Gtk.buttonGetLabel btn :: IO Text setter val = Gtk.buttonSetLabel btn val return (name, btn, (getter,setter))@@ -153,7 +196,7 @@ -> Text -- ^ name of the text entry to get as specified in the gladefile. -> IO TextEntryItem getTextEntryFromGlade builder name = do- (_, entry) <- wrapWidget builder Gtk.castToEntry name+ (_, entry) <- wrapWidget builder Gtk.Entry name let getter = fmap emptyTextToNothing $ Gtk.entryGetText entry :: IO (Maybe Text) setter val = Gtk.entrySetText entry val :: IO () return (name, entry, (getter, setter))@@ -163,13 +206,13 @@ -> Text -- ^ name of the combo box to get as specified in the gladefile. -> IO ComboBoxItem getComboBoxFromGlade builder name = do- (_, combo) <- wrapWidget builder Gtk.castToComboBox name+ (_, combo) <- wrapWidget builder Gtk.ComboBox name Gtk.comboBoxSetModelText combo let getter = Gtk.comboBoxGetActiveText combo :: IO (Maybe Text) -- get selected text setter entries = do -- fill with new entries store <- Gtk.comboBoxGetModelText combo- Gtk.listStoreClear store- mapM_ (Gtk.listStoreAppend store) entries+ Gtk.seqStoreClear store+ mapM_ (Gtk.seqStoreAppend store) entries return () return (name, combo, (getter, setter)) @@ -178,10 +221,10 @@ -> Text -- ^ name of the text view to get as specified in the gladefile. -> IO TextViewItem getTextViewFromGlade builder name = do- (_, entry) <- wrapWidget builder Gtk.castToTextView name+ (_, entry) <- wrapWidget builder Gtk.TextView name buffer <- Gtk.textViewGetBuffer entry let getter = getLongText buffer :: IO (Maybe Text)- setter = (\text -> Gtk.textBufferSetText buffer text) :: Text -> IO ()+ setter = (\text -> Gtk.textBufferSetText buffer text (-1)) :: Text -> IO () return (name, entry, (getter, setter)) where getLongText buffer = do@@ -197,7 +240,7 @@ -> Text -- ^ name of the check button to get as specified in the gladefile. -> IO CheckButtonItem getCheckButtonFromGlade builder name = do- (_,bt) <- wrapWidget builder Gtk.castToCheckButton name+ (_,bt) <- wrapWidget builder Gtk.CheckButton name let getter = Gtk.toggleButtonGetActive bt setter = (\bool -> Gtk.toggleButtonSetActive bt bool) :: Bool -> IO() return (name,bt, (getter,setter))@@ -212,50 +255,50 @@ -> [a] -- ^ Content of the new tree view. -> IO (TreeViewItem a) getTreeViewFromGlade builder name rows = do- (_, tView) <- wrapWidget builder Gtk.castToTreeView name+ (_, tView) <- wrapWidget builder Gtk.TreeView name entry@(store, treeView) <- createStoreForTreeView tView rows- let getter = getFromListStore entry- setter = setToListStore entry+ let getter = getFromSeqStore entry+ setter = setToSeqStore entry return (name, (store, treeView), (getter, setter)) -- | Get a 'TreeViewItem' from a gladefile. getTreeViewFromGladeCustomStore :: Gtk.Builder -> Text -- ^ name of the tree view to get as specified in the gladefile.- -> (Gtk.TreeView -> IO (Gtk.ListStore a)) -- ^ fn defining how to setup the liststore+ -> (Gtk.TreeView -> IO (Gtk.SeqStore a)) -- ^ fn defining how to setup the liststore -> IO (TreeViewItem a)-getTreeViewFromGladeCustomStore builder name setupListStore = do- (_, tView) <- wrapWidget builder Gtk.castToTreeView name- store <- setupListStore tView- Gtk.treeViewSetModel tView store- let getter = getFromListStore (store, tView)- setter = setToListStore (store, tView)+getTreeViewFromGladeCustomStore builder name setupSeqStore = do+ (_, tView) <- wrapWidget builder Gtk.TreeView name+ store <- setupSeqStore tView+ Gtk.treeViewSetModel tView (Just store)+ let getter = getFromSeqStore (store, tView)+ setter = setToSeqStore (store, tView) return (name, (store, tView), (getter, setter)) --- | Create a new 'Gtk.ListStore' for a 'Gtk.TreeView'.+-- | Create a new 'Gtk.SeqStore' for a 'Gtk.TreeView'. createStoreForTreeView :: Gtk.TreeView -- ^ The created list store will be set the model for this TreeView. -> [a] -- ^ Content of the new store.- -> IO (Gtk.ListStore a, Gtk.TreeView)+ -> IO (Gtk.SeqStore a, Gtk.TreeView) createStoreForTreeView listView rows = do- listStore <- Gtk.listStoreNew rows- Gtk.treeViewSetModel listView listStore- return (listStore, listView)+ seqStore <- Gtk.seqStoreNew rows+ Gtk.treeViewSetModel listView (Just seqStore)+ return (seqStore, listView) --- | Get the content of a ListStore.-getFromListStore :: (Gtk.ListStore a, Gtk.TreeView)- -> IO (Maybe [a]) -- ^ Nothing if the ListStore is empty.-getFromListStore (store, _) = do- list <- Gtk.listStoreToList store+-- | Get the content of a SeqStore.+getFromSeqStore :: (Gtk.SeqStore a, Gtk.TreeView)+ -> IO (Maybe [a]) -- ^ Nothing if the SeqStore is empty.+getFromSeqStore (store, _) = do+ list <- Gtk.seqStoreToList store if null list then return Nothing else return $ Just list --- | Set the content of a ListStore.-setToListStore :: (Gtk.ListStore a, Gtk.TreeView)- -> [a] -- ^ New content of the ListStore.+-- | Set the content of a SeqStore.+setToSeqStore :: (Gtk.SeqStore a, Gtk.TreeView)+ -> [a] -- ^ New content of the SeqStore. -> IO ()-setToListStore (store, view) newList = do- Gtk.listStoreClear store- mapM_ (Gtk.listStoreAppend store) newList+setToSeqStore (store, view) newList = do+ Gtk.seqStoreClear store+ mapM_ (Gtk.seqStoreAppend store) newList return () --@@ -268,34 +311,34 @@ -- | Close a window if 'Gtk.deleteEvent' occurs on this 'WindowItem'. registerClose :: WindowItem -> IO ()-registerClose win = Gtk.on (getItem win) Gtk.deleteEvent (liftIO (closeWin win) >> return False) >> return ()+registerClose win = Gtk.onWidgetDeleteEvent (getItem win) (\_ -> liftIO (closeWin win) >> return False) >> return () -- | Close a window if the specified action occurs on this 'WindowItem'. registerCloseAction :: ActionItem -> WindowItem -> IO ()-registerCloseAction act win = Gtk.on (getItem act) Gtk.actionActivated (liftIO (closeWin win)) >> return ()+registerCloseAction act win = Gtk.onActionActivate (getItem act) (liftIO (closeWin win)) >> return () -- | Call 'Gtk.mainQuit' if 'Gtk.deleteEvent' occurs on this 'WindowItem'. registerQuit :: WindowItem -> IO ()-registerQuit win = Gtk.on (getItem win) Gtk.deleteEvent (liftIO $ Gtk.mainQuit >> return False) >> return ()+registerQuit win = Gtk.onWidgetDeleteEvent (getItem win) (\_ -> liftIO $ Gtk.mainQuit >> return False) >> return () -- | Call 'Gtk.mainQuit' if the specified action occurs on this 'WindowItem'. registerQuitAction :: ActionItem -> IO ()-registerQuitAction act = Gtk.on (getItem act) Gtk.actionActivated (liftIO (Gtk.mainQuit)) >> return ()+registerQuitAction act = Gtk.onActionActivate (getItem act) (liftIO (Gtk.mainQuit)) >> return () -- TODO fun argument is not used. what was the purpos of this function? -- | same as 'registerQuitAction' since second argument is ignored (?) registerQuitWithCustomFun :: WindowItem -> IO () -- ^ custom fun -> IO ()-registerQuitWithCustomFun win fun = Gtk.on (getItem win) Gtk.deleteEvent (liftIO $ Gtk.mainQuit >> return False) >> return ()+registerQuitWithCustomFun win fun = Gtk.onWidgetDeleteEvent (getItem win) (\_ -> liftIO $ Gtk.mainQuit >> return False) >> return () --- | Add a column to given ListStore and TreeView using a mapping.+-- | Add a column to given SeqStore and TreeView using a mapping. -- The mapping consists of a CellRenderer, the title and a function, that maps each row to attributes of the column-addColumnToTreeView :: Gtk.CellRendererClass r =>+addColumnToTreeView :: Gtk.IsCellRenderer r => TreeViewItem a -> r -- ^ CellRenderer -> Text -- ^ title- -> (a -> [Gtk.AttrOp r]) -- ^ mapping+ -> (r -> a -> IO ()) -- ^ mapping -> IO () addColumnToTreeView (_, item, _) = do addColumnToTreeView' item@@ -303,35 +346,35 @@ -- Gtk.set newCol [Gtk.treeViewColumnTitle Gtk.:= title] -- Gtk.treeViewAppendColumn listView newCol -- Gtk.treeViewColumnPackStart newCol renderer True--- Gtk.cellLayoutSetAttributes newCol renderer listStore value2attributes+-- Gtk.cellLayoutSetAttributes newCol renderer seqStore value2attributes -- | Same as 'addColumnToTreeView'. This function can be called without a complete 'TreeViewItem'.-addColumnToTreeView' :: Gtk.CellRendererClass r =>- (Gtk.ListStore a, Gtk.TreeView)+addColumnToTreeView' :: Gtk.IsCellRenderer r =>+ (Gtk.SeqStore a, Gtk.TreeView) -> r -> Text- -> (a -> [Gtk.AttrOp r])+ -> (r -> a -> IO ()) -> IO ()-addColumnToTreeView' (listStore, listView) renderer title value2attributes = do+addColumnToTreeView' (seqStore, listView) renderer title value2attributes = do newCol <- Gtk.treeViewColumnNew- Gtk.set newCol [Gtk.treeViewColumnTitle Gtk.:= title]+ Gtk.setTreeViewColumnTitle newCol title Gtk.treeViewAppendColumn listView newCol Gtk.treeViewColumnPackStart newCol renderer True- Gtk.cellLayoutSetAttributes newCol renderer listStore value2attributes+ Gtk.cellLayoutSetDataFunction newCol renderer seqStore (value2attributes renderer) -- | Shortcut for adding text columns to a TreeView. See 'addColumnToTreeView'. addTextColumnToTreeView :: TreeViewItem a -> Text -- ^ title- -> (a -> [Gtk.AttrOp Gtk.CellRendererText]) -- ^ mapping+ -> (Gtk.CellRendererText -> a -> IO ()) -- ^ mapping -> IO () addTextColumnToTreeView tree title map = do r <- Gtk.cellRendererTextNew addColumnToTreeView tree r title map -- | Shortcut for adding text columns to a TreeView. See 'addColumnToTreeView\''.-addTextColumnToTreeView' :: (Gtk.ListStore a, Gtk.TreeView)+addTextColumnToTreeView' :: (Gtk.SeqStore a, Gtk.TreeView) -> Text- -> (a -> [Gtk.AttrOp Gtk.CellRendererText])+ -> (Gtk.CellRendererText -> a -> IO ()) -> IO () addTextColumnToTreeView' item title map = do r <- Gtk.cellRendererTextNew@@ -341,11 +384,13 @@ -- internal helpers --------------------------- -wrapWidget :: Gtk.GObjectClass objClass =>+wrapWidget :: Gtk.GObject objClass => Gtk.Builder- -> (Gtk.GObject -> objClass)+ -> (ManagedPtr objClass -> objClass) -> Text -> IO (Text, objClass)-wrapWidget builder cast name = do+wrapWidget builder constructor name = do hPutStrLn stderr $ " cast " ++ T.unpack name- gobj <- Gtk.builderGetObject builder cast name+ gobj <- nullToNothing (Gtk.builderGetObject builder name) >>= unsafeCastTo constructor . fromJust return (name, gobj)++
src/VCSGui/Common/Log.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE LambdaCase #-} ----------------------------------------------------------------------------- -- -- Module : VCSGui.Common.Log@@ -18,7 +20,6 @@ ) where import Control.Monad.Reader-import qualified Graphics.UI.Gtk as Gtk import Data.Maybe import VCSGui.Common.GtkHelper@@ -30,6 +31,20 @@ import Data.Text (Text) import qualified Data.Text as T (pack) import Data.Monoid ((<>))+import qualified GI.Gtk.Objects.TreeView as Gtk+ (treeViewSetCursor, treeViewGetCursor, TreeView(..))+import qualified GI.Gtk.Objects.Action as Gtk (onActionActivate)+import qualified GI.Gtk.Objects.Widget as Gtk+ (setWidgetVisible, widgetShowAll)+import qualified GI.Gtk.Interfaces.TreeModel as Gtk+ (treeModelGetPath, treeModelGetIterFirst, treeModelGetIter)+import qualified Data.GI.Gtk.ModelView.SeqStore as Gtk+ (seqStoreIterToIndex, seqStoreGetValue, SeqStore(..))+import qualified Data.GI.Gtk.ComboBox as Gtk+ (comboBoxSetActive, comboBoxPrependText)+import qualified GI.Gtk.Objects.ComboBox as Gtk (onComboBoxChanged)+import GI.Gtk.Objects.TreeViewColumn (noTreeViewColumn)+import qualified GI.Gtk as Gtk (setCellRendererTextText) getGladepath = getDataFileName "data/guiCommonLog.glade" @@ -91,7 +106,7 @@ liftIO $ registerCloseAction (actLogCancel gui) (logWin gui) config <- ask- liftIO $ Gtk.on (getItem (actCheckout gui)) Gtk.actionActivated $+ liftIO $ Gtk.onActionActivate (getItem (actCheckout gui)) $ doCheckout' config (logTreeView gui) (comboBranch gui) >> (closeWin (logWin gui)) @@ -101,37 +116,40 @@ where doCheckout' :: Common.Config -> TreeViewItem Common.LogEntry -> ComboBoxItem -> IO () doCheckout' cfg (_, (store, view), _) combo = do- (path, _) <- Gtk.treeViewGetCursor view -- TODO fix nothing selected bug here- Just treeIter <- Gtk.treeModelGetIter store path- selectedLog <- Gtk.listStoreGetValue store $ Gtk.listStoreIterToIndex treeIter- selectedBranch <- get combo- Common.runVcs cfg $ doCheckoutFn selectedLog selectedBranch+ (mbPath, _) <- Gtk.treeViewGetCursor view+ case mbPath of+ Just path -> do+ (True, treeIter) <- Gtk.treeModelGetIter store path+ selectedLog <- Gtk.seqStoreGetValue store =<< Gtk.seqStoreIterToIndex treeIter+ selectedBranch <- get combo+ Common.runVcs cfg $ doCheckoutFn selectedLog selectedBranch+ Nothing -> return () -- TODO fix nothing selected bug here setupLogColumns :: LogGUI -> Bool -> IO () setupLogColumns gui displayBranchNames = do let item = (logTreeView gui)- addTextColumnToTreeView item "Subject" (\Common.LogEntry { Common.subject = t } -> [Gtk.cellText Gtk.:= t])- addTextColumnToTreeView item "Author" (\Common.LogEntry { Common.author = t, Common.email = mail } -> [Gtk.cellText Gtk.:= t <> " <" <> mail <> ">"])- addTextColumnToTreeView item "Date" (\Common.LogEntry { Common.date = t } -> [Gtk.cellText Gtk.:= t])+ addTextColumnToTreeView item "Subject" (\cell Common.LogEntry { Common.subject = t } -> Gtk.setCellRendererTextText cell t)+ addTextColumnToTreeView item "Author" (\cell Common.LogEntry { Common.author = t, Common.email = mail } -> Gtk.setCellRendererTextText cell $ t <> " <" <> mail <> ">")+ addTextColumnToTreeView item "Date" (\cell Common.LogEntry { Common.date = t } -> Gtk.setCellRendererTextText cell t) case displayBranchNames of- True -> addTextColumnToTreeView item "Branch" (\Common.LogEntry { Common.mbBranch = t } -> [Gtk.cellText Gtk.:= fromMaybe "" t])+ True -> addTextColumnToTreeView item "Branch" (\cell Common.LogEntry { Common.mbBranch = t } -> Gtk.setCellRendererTextText cell $ fromMaybe "" t) False -> return() return () guiAddBranches :: LogGUI -> (Text, [Text]) -> (Text -> Common.Ctx [Common.LogEntry]) -> Common.Ctx () guiAddBranches gui (curBranch, otherBranches) changeBranchFn = do -- set branch selection visible- liftIO $ Gtk.set (getItem $ lblBranch gui) [Gtk.widgetVisible Gtk.:= True]- liftIO $ Gtk.set (getItem $ comboBranch gui) [Gtk.widgetVisible Gtk.:= True]+ liftIO $ Gtk.setWidgetVisible (getItem $ lblBranch gui) True+ liftIO $ Gtk.setWidgetVisible (getItem $ comboBranch gui) True - -- fill with data+ -- fill with data® liftIO $ set (comboBranch gui) otherBranches liftIO $ Gtk.comboBoxPrependText (getItem $ comboBranch gui) curBranch liftIO $ Gtk.comboBoxSetActive (getItem $ comboBranch gui) 0 -- register branch switch fn config <- ask- liftIO $ Gtk.on (getItem $ comboBranch gui) Gtk.changed $ changeBranchFn' config (fmap (fromMaybe "") $ get $ comboBranch gui)+ liftIO $ Gtk.onComboBoxChanged (getItem $ comboBranch gui) $ changeBranchFn' config (fmap (fromMaybe "") $ get $ comboBranch gui) return () where changeBranchFn' :: Common.Config -> IO Text -> IO ()@@ -141,9 +159,11 @@ newLogEntries <- Common.runVcs cfg $ changeBranchFn branch set (logTreeView gui) newLogEntries -- set cursor to first log entry (so checkoutbutton works)- Just firstRowIter <- Gtk.treeModelGetIterFirst store- firstRow <- Gtk.treeModelGetPath store firstRowIter- Gtk.treeViewSetCursor view firstRow Nothing+ Gtk.treeModelGetIterFirst store >>= \case+ (True, firstRowIter) -> do+ firstRow <- Gtk.treeModelGetPath store firstRowIter+ Gtk.treeViewSetCursor view firstRow noTreeViewColumn False+ _ -> return () loadLogGui :: [Common.LogEntry] -> Common.Ctx LogGUI
src/VCSGui/Common/SetupConfig.hs view
@@ -16,7 +16,6 @@ module VCSGui.Common.SetupConfig ( showSetupConfigGUI ) where-import Graphics.UI.Gtk hiding (set, get) import Control.Monad.Trans(liftIO) import Data.Maybe import Control.Monad@@ -32,6 +31,21 @@ import Data.Text (Text) import qualified Data.Text as T (unpack, pack) import Control.Applicative ((<$>))+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Enums+ (ResponseType(..), FileChooserAction, FileChooserAction(..))+import GI.Gtk.Objects.ToggleButton (onToggleButtonToggled)+import GI.Gtk.Objects.Widget+ (widgetDestroy, widgetHide, widgetShowAll)+import GI.Gtk.Objects.ComboBox (comboBoxSetActive)+import GI.Gtk.Objects.Window+ (setWindowTransientFor, setWindowTitle, Window(..))+import Data.GI.Base (new, nullToNothing)+import GI.Gtk.Objects.FileChooserDialog (FileChooserDialog(..))+import GI.Gtk.Objects.Dialog (dialogRun, dialogAddButton)+import GI.Gtk.Interfaces.FileChooser+ (setFileChooserAction, fileChooserGetFilename)+import GI.Gtk.Objects.Builder (Builder(..)) type Config = Maybe (Wrapper.VCSType, Wrapper.Config, Maybe MergeTool.MergeTool) --config for setting up vcs@@ -127,7 +141,7 @@ H.registerClose $ winSetupRepo gui liftIO $ H.registerCloseAction (actCancel gui) (winSetupRepo gui) - on (H.getItem (actOk gui)) actionActivated $+ onActionActivate (H.getItem (actOk gui)) $ do mbConfig <- createVCSTypAndConfig gui case mbConfig of Left errorMsg -> showErrorGUI errorMsg@@ -135,7 +149,7 @@ callback $ Just tuple H.closeWin $ winSetupRepo gui - on (H.getItem (actBrowseRepo gui)) actionActivated $ liftIO $ do+ onActionActivate (H.getItem (actBrowseRepo gui)) $ liftIO $ do mbPath <- showFolderChooserDialog "Choose repository location" (H.getItem $ winSetupRepo gui) FileChooserActionSelectFolder case mbPath of Nothing -> return ()@@ -146,7 +160,7 @@ -- update gui H.set (entRepo gui) (T.pack path) return ()- on (H.getItem (actBrowseExec gui)) actionActivated $ liftIO $ do+ onActionActivate (H.getItem (actBrowseExec gui)) $ liftIO $ do mbExec <- showFolderChooserDialog "Choose executable location" (H.getItem $ winSetupRepo gui) FileChooserActionOpen case mbExec of Nothing -> return ()@@ -155,7 +169,7 @@ H.set (checkbtExec gui) True return () - on (H.getItem (checkbtExec gui)) toggled $ do+ onToggleButtonToggled (H.getItem (checkbtExec gui)) $ do putStrLn "checkbtnexec toogled" active <- H.get (checkbtExec gui) if active then do@@ -167,7 +181,7 @@ widgetHide (H.getItem (entExec gui)) widgetHide (H.getItem (btnBrowseExec gui)) - on (H.getItem (checkbtAuthor gui)) toggled $ do+ onToggleButtonToggled (H.getItem (checkbtAuthor gui)) $ do putStrLn "checkbtnauthor toogled" active <- H.get (checkbtAuthor gui) if active then do@@ -181,7 +195,7 @@ widgetHide (H.getItem (lblEmail gui)) widgetHide (H.getItem (entEmail gui)) return ()- liftIO $ on (H.getItem (actBrowsePathToTool gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actBrowsePathToTool gui)) $ do mbPath <- showFolderChooserDialog "Select executable" (H.getItem $ winSetupRepo gui) FileChooserActionOpen case mbPath of Nothing -> return ()@@ -248,7 +262,7 @@ case findIndex (== vcsType) availableVCS of Just index -> --set active- comboBoxSetActive (H.getItem (comboBoxVCSType gui)) index+ comboBoxSetActive (H.getItem (comboBoxVCSType gui)) (fromIntegral index) _ -> return () case mbExec of Nothing -> do@@ -305,13 +319,18 @@ -> FileChooserAction -> IO (Maybe FilePath) showFolderChooserDialog title parent fcAction = do- dialog <- fileChooserDialogNew (Just title) (Just parent) fcAction [("Cancel", ResponseCancel), ("Select", ResponseAccept)]+ dialog <- new FileChooserDialog []+ setWindowTitle dialog title+ dialogAddButton dialog "gtk-cancel" (fromIntegral $ fromEnum ResponseTypeCancel)+ dialogAddButton dialog "Select" (fromIntegral $ fromEnum ResponseTypeAccept)+ setWindowTransientFor dialog parent+ setFileChooserAction dialog fcAction response <- dialogRun dialog- case response of- ResponseCancel -> widgetDestroy dialog >> return Nothing- ResponseDeleteEvent -> widgetDestroy dialog >> return Nothing- ResponseAccept -> do- f <- fileChooserGetFilename dialog+ case toEnum $ fromIntegral response of+ ResponseTypeCancel -> widgetDestroy dialog >> return Nothing+ ResponseTypeDeleteEvent -> widgetDestroy dialog >> return Nothing+ ResponseTypeAccept -> do+ f <- nullToNothing $ fileChooserGetFilename dialog widgetDestroy dialog return f
src/VCSGui/Git/Commit.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE LambdaCase #-} ----------------------------------------------------------------------------- -- -- Module : VCSGui.Git.Commit@@ -20,8 +22,6 @@ import Control.Monad.Trans(liftIO) import Control.Monad.Reader(ask) -import Graphics.UI.Gtk- import VCSGui.Common.GtkHelper import qualified VCSGui.Common.Commit as Commit @@ -29,7 +29,15 @@ import qualified VCSWrapper.Common as Wrapper import Data.Text (Text) import qualified Data.Text as T (unpack, pack)-+import GI.Gtk.Objects.TreeView (treeViewSetModel, TreeView(..))+import Data.GI.Gtk.ModelView.SeqStore+ (seqStoreSetValue, seqStoreGetValue, seqStoreIterToIndex,+ seqStoreNew, SeqStore(..))+import GI.Gtk.Objects.CellRendererToggle+ (onCellRendererToggleToggled, cellRendererToggleNew)+import GI.Gtk.Interfaces.TreeModel (treeModelGetIterFromString)+import GI.Gtk+ (setCellRendererTextText, setCellRendererToggleActive) doCommit :: Text -> [FilePath] -> [Commit.Option] -> Wrapper.Ctx () doCommit commitMsg files _ = do@@ -42,38 +50,40 @@ Nothing -> Git.commit files (Just (author, "noEmailSet@noEmailSet")) commitMsg [] Just m -> Git.commit files (Just (author, m)) commitMsg [] -{- | Calls 'Commit.showCommitGUI' with a 'Graphics.UI.Gtk.ListStore' and 'OkCallBack' setup for Git.+{- | Calls 'Commit.showCommitGUI' with a 'Data.GI.Gtk.SeqStore' and 'OkCallBack' setup for Git. This will display a window to enter a commit message and select the files to be commited by this commit. -} showCommitGUI :: Git.Ctx () showCommitGUI = do- Commit.showCommitGUI setupListStore doCommit+ Commit.showCommitGUI setupSeqStore doCommit -setupListStore :: TreeView -> Wrapper.Ctx (ListStore Commit.SCFile)-setupListStore view = do+setupSeqStore :: TreeView -> Wrapper.Ctx (SeqStore Commit.SCFile)+setupSeqStore view = do repoStatus <- Git.status --GITSCFile Bool FilePath Text let selectedF = [Commit.GITSCFile True fp (T.pack $ show mod) | (Wrapper.GITStatus fp mod) <- repoStatus, mod == Wrapper.Modified || mod == Wrapper.Added] notSelectedF = [Commit.GITSCFile False fp (T.pack $ show mod) | (Wrapper.GITStatus fp mod) <- repoStatus, mod /= Wrapper.Modified && mod /= Wrapper.Added] liftIO $ do- store <- listStoreNew (selectedF ++ notSelectedF)- treeViewSetModel view store+ store <- seqStoreNew (selectedF ++ notSelectedF)+ treeViewSetModel view $ Just store let item = (store, view) toggleRenderer <- cellRendererToggleNew- addColumnToTreeView' item toggleRenderer "Commit" (\(Commit.GITSCFile s _ _)-> [cellToggleActive := s])- addTextColumnToTreeView' item "File" (\(Commit.GITSCFile _ p _) -> [cellText := T.pack p])- addTextColumnToTreeView' item "File status" (\(Commit.GITSCFile _ _ m) -> [cellText := m])+ addColumnToTreeView' item toggleRenderer "Commit" (\cell (Commit.GITSCFile s _ _) -> setCellRendererToggleActive cell s)+ addTextColumnToTreeView' item "File" (\cell (Commit.GITSCFile _ p _) -> setCellRendererTextText cell $ T.pack p)+ addTextColumnToTreeView' item "File status" (\cell (Commit.GITSCFile _ _ m) -> setCellRendererTextText cell m) -- register toggle renderer- on toggleRenderer cellToggled $ \filepath -> do+ onCellRendererToggleToggled toggleRenderer $ \filepath -> do putStrLn ("toggle called: " ++ T.unpack filepath) - Just treeIter <- treeModelGetIterFromString store filepath- value <- listStoreGetValue store $ listStoreIterToIndex treeIter- let newValue = (\(Commit.GITSCFile b fp m) -> Commit.GITSCFile (not b) fp m) value- listStoreSetValue store (listStoreIterToIndex treeIter) newValue- return ()+ treeModelGetIterFromString store filepath >>= \case+ (True, treeIter) -> do+ n <- seqStoreIterToIndex treeIter+ value <- seqStoreGetValue store n+ let newValue = (\(Commit.GITSCFile b fp m) -> Commit.GITSCFile (not b) fp m) value+ seqStoreSetValue store n newValue+ _ -> return () return store
src/VCSGui/Git/Log.hs view
@@ -19,7 +19,6 @@ showLogGUI ) where -import qualified Graphics.UI.Gtk as Gtk import qualified VCSGui.Common.Log as Common import qualified VCSWrapper.Git as Git import Control.Monad.Reader (liftIO)@@ -27,6 +26,18 @@ import VCSGui.Common.Helpers (emptyTextToNothing) import qualified Data.Text as T (unpack, pack) import Data.Text (Text)+import qualified GI.Gtk.Objects.Dialog as Gtk+ (dialogRun, dialogGetContentArea, dialogAddButton, dialogNew)+import qualified GI.Gtk.Enums as Gtk (ResponseType(..))+import qualified GI.Gtk.Objects.Entry as Gtk+ (entryGetText, entryNew)+import qualified GI.Gtk.Objects.Label as Gtk (labelNew)+import qualified GI.Gtk.Objects.HBox as Gtk (hBoxNew)+import qualified GI.Gtk.Objects.Container as Gtk (containerAdd)+import Data.GI.Base.ManagedPtr (unsafeCastTo)+import GI.Gtk.Objects.Box (Box(..))+import qualified GI.Gtk.Objects.Widget as Gtk+ (widgetDestroy, widgetShowAll) {- | Calls 'Common.showLogGUI' using Git. This will display all log entries. The branch to be displayed can be selected.@@ -53,17 +64,13 @@ askForNewBranchname :: IO (Maybe Text) askForNewBranchname = do dialog <- Gtk.dialogNew- Gtk.dialogAddButton dialog ("gtk-ok"::Text) Gtk.ResponseOk-#if defined(MIN_VERSION_gtk3)- upper <- Gtk.dialogGetContentArea dialog-#else- upper <- Gtk.dialogGetUpper dialog-#endif+ Gtk.dialogAddButton dialog ("gtk-ok"::Text) (fromIntegral $ fromEnum Gtk.ResponseTypeOk)+ upper <- Gtk.dialogGetContentArea dialog >>= unsafeCastTo Box inputBranch <- Gtk.entryNew lblBranch <- Gtk.labelNew $ Just ("Enter a new branchname (empty for anonym branch):" :: Text) box <- Gtk.hBoxNew False 2- Gtk.containerAdd (Gtk.castToBox upper) box+ Gtk.containerAdd upper box Gtk.containerAdd box lblBranch Gtk.containerAdd box inputBranch
src/VCSGui/Mercurial/Commit.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE LambdaCase #-} ----------------------------------------------------------------------------- -- -- Module : VCSGui.Mercurial.Commit@@ -20,8 +22,6 @@ import Control.Monad.Trans(liftIO) import Control.Monad.Reader(ask) -import Graphics.UI.Gtk- import VCSGui.Common.GtkHelper import qualified VCSGui.Common.Commit as Commit @@ -29,6 +29,15 @@ import qualified VCSWrapper.Common as Wrapper import Data.Text (Text) import qualified Data.Text as T (pack, unpack)+import GI.Gtk.Objects.TreeView (treeViewSetModel, TreeView(..))+import Data.GI.Gtk.ModelView.SeqStore+ (seqStoreSetValue, seqStoreGetValue, seqStoreIterToIndex,+ seqStoreNew, SeqStore(..))+import GI.Gtk.Objects.CellRendererToggle+ (onCellRendererToggleToggled, cellRendererToggleNew)+import GI.Gtk.Interfaces.TreeModel (treeModelGetIterFromString)+import qualified GI.Gtk as Gtk+ (setCellRendererTextText, setCellRendererToggleActive) doCommit :: Text -> [FilePath] -> [Commit.Option] -> Wrapper.Ctx () doCommit commitMsg files _ = do@@ -36,38 +45,41 @@ Mercurial.commit files commitMsg [] {- |- Calls 'Commit.showCommitGUI' with a 'Graphics.UI.Gtk.ListStore' and 'OkCallBack' setup for Mercurial.+ Calls 'Commit.showCommitGUI' with a 'Data.GI.Gtk.SeqStore' and 'OkCallBack' setup for Mercurial. This will display a window to enter a commit message and select the files to be commited by this commit. -} showCommitGUI :: Mercurial.Ctx () showCommitGUI = do- Commit.showCommitGUI setupListStore doCommit+ Commit.showCommitGUI setupSeqStore doCommit --TODO this is copy&pasted from git implementation refactor it and use abstract version-setupListStore :: TreeView -> Wrapper.Ctx (ListStore Commit.SCFile)-setupListStore view = do+setupSeqStore :: TreeView -> Wrapper.Ctx (SeqStore Commit.SCFile)+setupSeqStore view = do repoStatus <- Mercurial.status --GITSCFile Bool FilePath Text let selectedF = [Commit.GITSCFile True fp (T.pack $ show mod) | (Wrapper.GITStatus fp mod) <- repoStatus, mod == Wrapper.Modified || mod == Wrapper.Added] notSelectedF = [Commit.GITSCFile False fp (T.pack $ show mod) | (Wrapper.GITStatus fp mod) <- repoStatus, mod /= Wrapper.Modified && mod /= Wrapper.Added] liftIO $ do- store <- listStoreNew (selectedF ++ notSelectedF)- treeViewSetModel view store+ store <- seqStoreNew (selectedF ++ notSelectedF)+ treeViewSetModel view (Just store) let item = (store, view) toggleRenderer <- cellRendererToggleNew- addColumnToTreeView' item toggleRenderer "Commit" (\(Commit.GITSCFile s _ _)-> [cellToggleActive := s])- addTextColumnToTreeView' item "File" (\(Commit.GITSCFile _ p _) -> [cellText := T.pack p])- addTextColumnToTreeView' item "File status" (\(Commit.GITSCFile _ _ m) -> [cellText := m])+ addColumnToTreeView' item toggleRenderer "Commit" (\cell (Commit.GITSCFile s _ _) -> Gtk.setCellRendererToggleActive cell s)+ addTextColumnToTreeView' item "File" (\cell (Commit.GITSCFile _ p _) -> Gtk.setCellRendererTextText cell $ T.pack p)+ addTextColumnToTreeView' item "File status" (\cell (Commit.GITSCFile _ _ m) -> Gtk.setCellRendererTextText cell m) -- register toggle renderer- on toggleRenderer cellToggled $ \filepath -> do+ onCellRendererToggleToggled toggleRenderer $ \filepath -> do putStrLn ("toggle called: " ++ T.unpack filepath) - Just treeIter <- treeModelGetIterFromString store filepath- value <- listStoreGetValue store $ listStoreIterToIndex treeIter- let newValue = (\(Commit.GITSCFile b fp m) -> Commit.GITSCFile (not b) fp m) value- listStoreSetValue store (listStoreIterToIndex treeIter) newValue- return ()+ treeModelGetIterFromString store filepath >>= \case+ (True, treeIter) -> do+ n <- seqStoreIterToIndex treeIter+ value <- seqStoreGetValue store n+ let newValue = (\(Commit.GITSCFile b fp m) -> Commit.GITSCFile (not b) fp m) value+ seqStoreSetValue store n newValue+ return ()+ _ -> return () return store
src/VCSGui/Mercurial/Log.hs view
@@ -16,7 +16,6 @@ showLogGUI ) where -import qualified Graphics.UI.Gtk as Gtk import qualified VCSGui.Common.Log as Common import qualified VCSWrapper.Mercurial as Mercurial import Control.Monad.Reader (liftIO)
src/VCSGui/Svn/AskPassword.hs view
@@ -23,13 +23,22 @@ import qualified VCSWrapper.Common as Wrapper -import Graphics.UI.Gtk--import Data.Maybe (fromMaybe)+import Data.Maybe (fromJust, fromMaybe) import Control.Monad.Trans(liftIO) import Paths_vcsgui(getDataFileName) import Control.Monad.Reader(ask) import Data.Text (Text)+import GI.Gtk.Objects.VBox (VBox(..))+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Objects.ToggleButton+ (setToggleButtonActive, getToggleButtonActive,+ onToggleButtonToggled)+import GI.Gtk.Objects.Widget+ (onWidgetDeleteEvent, widgetHide, widgetShowAll)+import Data.GI.Base.Attributes (AttrOp(..))+import GI.Gtk.Objects.Builder (builderGetObject)+import Data.GI.Base.ManagedPtr (unsafeCastTo)+import Data.GI.Base.BasicTypes (NullToNothing(..)) -- -- glade path and object accessors --@@ -76,7 +85,7 @@ -- connect actions registerClose (windowAskpass gui) handler config registerCloseAction (actCancel gui) (windowAskpass gui) handler config- on (H.getItem (actOk gui)) actionActivated $ do+ onActionActivate (H.getItem (actOk gui)) $ do putStrLn "ok clicked" usePw <- H.get $ checkbtUsePw gui pw <- H.get (entryPw gui)@@ -86,8 +95,8 @@ else Just (saveForSession, Nothing) VCSGUI.defaultVCSExceptionHandler $ Wrapper.runVcs config $ handler args H.closeWin (windowAskpass gui)- on (H.getItem (checkbtUsePw gui)) toggled $ do- active <- get (H.getItem (checkbtUsePw gui)) toggleButtonActive+ onToggleButtonToggled (H.getItem (checkbtUsePw gui)) $ do+ active <- getToggleButtonActive (H.getItem (checkbtUsePw gui)) if active then widgetShowAll (boxUsePwd gui) else@@ -100,14 +109,14 @@ -> Handler -> Wrapper.Config -> IO()-registerClose win handler config = on (H.getItem win) deleteEvent (liftIO (close win handler config) >> return False) >> return ()+registerClose win handler config = onWidgetDeleteEvent (H.getItem win) (\e -> liftIO (close win handler config) >> return False) >> return () registerCloseAction :: H.ActionItem -> H.WindowItem -> Handler -> Wrapper.Config -> IO()-registerCloseAction act win handler config = on (H.getItem act) actionActivated (liftIO (close win handler config)) >> return ()+registerCloseAction act win handler config = onActionActivate (H.getItem act) (liftIO (close win handler config)) >> return () close :: H.WindowItem -> Handler@@ -127,8 +136,8 @@ actCancel <- H.getActionFromGlade builder accessorActCancel entryPw <- H.getTextEntryFromGlade builder accessorEntryPw checkbtUsePw <- H.getCheckButtonFromGlade builder accessorCheckbtUsePw- set (H.getItem checkbtUsePw) [toggleButtonActive := True]+ setToggleButtonActive (H.getItem checkbtUsePw) True checkbtSaveForSession <- H.getCheckButtonFromGlade builder accessorCheckbtSaveForSession- set (H.getItem checkbtSaveForSession) [toggleButtonActive := True]- boxUsePw <- builderGetObject builder castToVBox accessorboxUsePwd+ setToggleButtonActive (H.getItem checkbtSaveForSession) True+ boxUsePw <- nullToNothing (builderGetObject builder accessorboxUsePwd) >>= unsafeCastTo VBox . fromJust return $ AskpassGUI windowAskpass actOk actCancel entryPw checkbtUsePw checkbtSaveForSession boxUsePw
src/VCSGui/Svn/Checkout.hs view
@@ -17,7 +17,6 @@ showCheckoutGUI ) where -import Graphics.UI.Gtk import Control.Monad.Trans(liftIO) import Control.Monad import Control.Monad.Reader@@ -27,6 +26,8 @@ import Data.Maybe import qualified Data.Text as T (unpack, pack) import Control.Applicative ((<$>))+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Objects.Widget (widgetShowAll) -- -- glade path and object accessors --@@ -59,7 +60,7 @@ -- connect actions H.registerClose $ windowCheckout gui H.registerCloseAction (actCancel gui) (windowCheckout gui)- liftIO $ on (H.getItem (actCheckout gui)) actionActivated $ do+ liftIO $ onActionActivate (H.getItem (actCheckout gui)) $ do url <- H.get (txtViewUrl gui) realRevision <- H.get (txtViewRevision gui) realFilePath <- H.get (txtViewPath gui)
src/VCSGui/Svn/Commit.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-} ----------------------------------------------------------------------------- -- -- Module : Main@@ -28,10 +29,19 @@ import qualified VCSWrapper.Svn as Svn -import Graphics.UI.Gtk import Control.Monad.Trans(liftIO) import Data.Text (Text) import qualified Data.Text as T (pack)+import GI.Gtk.Objects.TreeView (treeViewSetModel, TreeView(..))+import Data.GI.Gtk.ModelView.SeqStore+ (seqStoreSetValue, seqStoreIterToIndex, seqStoreGetValue,+ seqStoreNew, SeqStore(..))+import GI.Gtk.Objects.CellRendererToggle+ (onCellRendererToggleToggled, cellRendererToggleNew)+import GI.Gtk.Interfaces.TreeModel (treeModelGetIterFromString)+import GI.Gtk.Objects.CellRendererText (cellRendererTextNew)+import GI.Gtk+ (setCellRendererTextText, setCellRendererToggleActive) {- | Shows a GUI showing status of subversion and possibilites to commit/cancel.@@ -82,7 +92,7 @@ -setUpTreeView :: TreeView -> Svn.Ctx (ListStore C.SCFile)+setUpTreeView :: TreeView -> Svn.Ctx (SeqStore C.SCFile) setUpTreeView listView = do -- get status repoStatus <- Svn.status@@ -91,49 +101,50 @@ liftIO $ do -- create model- listStore <- listStoreNew [+ seqStore <- seqStoreNew [ (C.SVNSCFile (ctxSelect (Svn.modification status)) (Svn.filePath status) (T.pack . show $ Svn.modification status) (Svn.isLocked status)) | status <- repoStatus]- treeViewSetModel listView listStore+ treeViewSetModel listView (Just seqStore) - let treeViewItem = (listStore, listView)+ let treeViewItem = (seqStore, listView) renderer <- cellRendererToggleNew H.addColumnToTreeView' treeViewItem renderer ""- $ \scf -> [cellToggleActive := C.selected scf]+ $ \cell scf -> setCellRendererToggleActive cell $ C.selected scf -- connect select action- on renderer cellToggled $ \(columnId :: Text) -> do- Just treeIter <- treeModelGetIterFromString listStore columnId- value <- listStoreGetValue listStore $ listStoreIterToIndex treeIter+ onCellRendererToggleToggled renderer $ \(columnId :: Text) -> do+ (True, treeIter) <- treeModelGetIterFromString seqStore columnId+ n <- seqStoreIterToIndex treeIter+ value <- seqStoreGetValue seqStore n let newValue = (\(C.SVNSCFile bool fp s l) -> C.SVNSCFile (not bool) fp s l) value- listStoreSetValue listStore (listStoreIterToIndex treeIter) newValue+ seqStoreSetValue seqStore n newValue return () renderer <- cellRendererTextNew H.addColumnToTreeView' treeViewItem renderer "Files to commit"- $ \scf -> [cellText := T.pack $ C.filePath scf]+ $ \cell scf -> setCellRendererTextText cell . T.pack $ C.filePath scf renderer <- cellRendererTextNew H.addColumnToTreeView' treeViewItem renderer "Status"- $ \scf -> [cellText := C.status scf]+ $ \cell scf -> setCellRendererTextText cell $ C.status scf renderer <- cellRendererToggleNew H.addColumnToTreeView' treeViewItem renderer "Locked"- $ \scf -> [cellToggleActive := C.isLocked scf]- return listStore+ $ \cell scf -> setCellRendererToggleActive cell $ C.isLocked scf+ return seqStore where ctxSelect status = status == Svn.Added || status == Svn.Deleted || status==Svn.Modified || status == Svn.Replaced
src/exe/askpass/Main.hs view
@@ -18,12 +18,15 @@ main ) where -import Graphics.UI.Gtk import qualified VCSGui.Common.GtkHelper as H import Data.Maybe (fromMaybe) import Paths_vcsgui(getDataFileName) import qualified Data.Text as T (unpack)+import qualified GI.Gtk.Functions as Gtk (main, init)+import GI.Gtk.Objects.Action (onActionActivate)+import GI.Gtk.Functions (mainQuit)+import GI.Gtk.Objects.Widget (widgetShowAll) -- -- glade path and object accessors --@@ -44,9 +47,9 @@ main :: IO () main = do- initGUI+ Gtk.init Nothing showAskpassGUI- mainGUI+ Gtk.main showAskpassGUI :: IO ()@@ -56,7 +59,7 @@ -- connect actions H.registerQuit $ window gui H.registerQuitAction $ actCancel gui- on (H.getItem (actOk gui)) actionActivated $ do+ onActionActivate (H.getItem (actOk gui)) $ do pw <- H.get (entryPw gui) putStr . T.unpack $ fromMaybe "" pw mainQuit
vcsgui.cabal view
@@ -1,6 +1,6 @@ name: vcsgui-version: 0.1.3.0-cabal-version: >= 1.8+version: 0.2.1.0+cabal-version: >=1.8 build-type: Simple license: GPL license-file: LICENSE@@ -16,104 +16,133 @@ Currently git, SVN and mercurial (hg) are supported. category: Development author: Stephan Fortelny, Harald Jagenteufel, Hamish Mackenzie-tested-with: GHC == 7.0-data-files: LICENSE- data/guiCommonCommit.glade- data/guiCommonLog.glade- data/guiCommonSetupRepo.glade- data/guiSvnCheckout.glade- data/guiCommonAskpass.glade- data/guiSvnAskpass.glade- data/guiCommonFilesInConflict.glade- data/guiCommonMergeTool.glade- data/guiCommonConflictsResolved.glade-data-dir: ""--flag gtk3- description: Use Gtk3- default: True+tested-with: GHC ==7.0+data-files:+ LICENSE+ data/guiCommonCommit.glade+ data/guiCommonLog.glade+ data/guiCommonSetupRepo.glade+ data/guiSvnCheckout.glade+ data/guiCommonAskpass.glade+ data/guiSvnAskpass.glade+ data/guiCommonFilesInConflict.glade+ data/guiCommonMergeTool.glade+ data/guiCommonConflictsResolved.glade library+ exposed-modules:+ VCSGui.Common+ VCSGui.Git+ VCSGui.Svn+ VCSGui.Mercurial build-depends:- filepath >=1.2.0.0 && < 1.5,- base >=4.0.0.0 && <4.9,- directory >=1.1.0.0 && <1.3,- mtl >=2.0.1.0 && <2.3,- vcswrapper >=0.1.1 && <0.2,- process >=1.0.1.5 && <1.3,- text -any- if flag(gtk3)- build-depends: gtk3 >=0.13.0.0 && <0.15- cpp-options: -DMIN_VERSION_gtk=MIN_VERSION_gtk3- else- build-depends: gtk >=0.13.0.0 && <0.14- exposed-modules: VCSGui.Common VCSGui.Git VCSGui.Svn VCSGui.Mercurial- exposed: True- buildable: True+ filepath >=1.2.0.0 && <1.5,+ base >=4.0.0.0 && <4.10,+ directory >=1.1.0.0 && <1.3,+ mtl >=2.0.1.0 && <2.3,+ vcswrapper >=0.1.1 && <0.2,+ process >=1.0.1.5 && <1.5,+ text -any,+ haskell-gi-base >=0.20 && <0.21,+ gi-gtk >=3.0.6 && <3.1,+ gi-gtk-hs >=0.3.0.0 && <0.4 hs-source-dirs: src- other-modules: VCSGui.Svn.Helper VCSGui.Common.Process- VCSGui.Common.ConflictsResolved VCSGui.Common.MergeTool- VCSGui.Common.FilesInConflict VCSGui.Git.Pull VCSGui.Svn.Update- VCSGui.Svn.AskPassword VCSGui VCSGui.Svn.Log VCSGui.Svn.Checkout- VCSGui.Svn.Commit VCSGui.Git.Log VCSGui.Git.Helpers- VCSGui.Git.Commit VCSGui.Common.Log- VCSGui.Common.GtkHelper VCSGui.Common.ExceptionHandler- VCSGui.Common.SetupConfig VCSGui.Common.Error VCSGui.Common.Commit- VCSGui.Mercurial.Commit VCSGui.Mercurial.Log- VCSGui.Common.Helpers- Paths_vcsgui+ other-modules:+ VCSGui.Svn.Helper+ VCSGui.Common.Process+ VCSGui.Common.ConflictsResolved+ VCSGui.Common.MergeTool+ VCSGui.Common.FilesInConflict+ VCSGui.Git.Pull+ VCSGui.Svn.Update+ VCSGui.Svn.AskPassword+ VCSGui+ VCSGui.Svn.Log+ VCSGui.Svn.Checkout+ VCSGui.Svn.Commit+ VCSGui.Git.Log+ VCSGui.Git.Helpers+ VCSGui.Git.Commit+ VCSGui.Common.Log+ VCSGui.Common.GtkHelper+ VCSGui.Common.ExceptionHandler+ VCSGui.Common.SetupConfig+ VCSGui.Common.Error+ VCSGui.Common.Commit+ VCSGui.Mercurial.Commit+ VCSGui.Mercurial.Log+ VCSGui.Common.Helpers+ Paths_vcsgui executable vcsgui- main-is: Main.hs- build-depends:- filepath >=1.2.0.0 && < 1.5,- base >=4.0.0.0 && <4.9,- directory >=1.1.0.0 && <1.3,- mtl >=2.0.1.0 && <2.3,- vcswrapper >=0.1.1 && <0.2,- process >=1.0.1.5 && <1.3,- text -any- if flag(gtk3)- build-depends: gtk3 >=0.12.4 && <0.15- cpp-options: -DMIN_VERSION_gtk=MIN_VERSION_gtk3- else- build-depends: gtk >=0.12.4 && <0.14+ if os(osx) ghc-options: -optl-headerpad_max_install_names- buildable: True+ main-is: Main.hs+ build-depends:+ filepath >=1.2.0.0 && <1.5,+ base >=4.0.0.0 && <4.10,+ directory >=1.1.0.0 && <1.3,+ mtl >=2.0.1.0 && <2.3,+ vcswrapper >=0.1.1 && <0.2,+ process >=1.0.1.5 && <1.5,+ text -any,+ haskell-gi-base >=0.20 && <0.21,+ gi-gtk >=3.0.6 && <3.1,+ gi-gtk-hs >=0.3.0.0 && <0.4 hs-source-dirs: src- other-modules: VCSGui.Svn.Helper VCSGui.Common.Process- VCSGui.Common.ConflictsResolved VCSGui.Common.MergeTool- VCSGui.Common.FilesInConflict VCSGui.Git.Pull VCSGui.Svn.Update- VCSGui.Svn.AskPassword VCSGui VCSGui.Svn.Log VCSGui.Svn.Checkout- VCSGui.Svn.Commit VCSGui.Git.Log VCSGui.Git.Helpers- VCSGui.Git.Commit VCSGui.Common.Log- VCSGui.Common.GtkHelper VCSGui.Common.ExceptionHandler- VCSGui.Common.SetupConfig VCSGui.Common.Error VCSGui.Common.Commit- VCSGui.Common.Helpers- Paths_vcsgui+ other-modules:+ VCSGui.Svn.Helper+ VCSGui.Common.Process+ VCSGui.Common.ConflictsResolved+ VCSGui.Common.MergeTool+ VCSGui.Common.FilesInConflict+ VCSGui.Git.Pull+ VCSGui.Svn.Update+ VCSGui.Svn.AskPassword+ VCSGui+ VCSGui.Svn.Log+ VCSGui.Svn.Checkout+ VCSGui.Svn.Commit+ VCSGui.Git.Log+ VCSGui.Git.Helpers+ VCSGui.Git.Commit+ VCSGui.Common.Log+ VCSGui.Common.GtkHelper+ VCSGui.Common.ExceptionHandler+ VCSGui.Common.SetupConfig+ VCSGui.Common.Error+ VCSGui.Common.Commit+ VCSGui.Common.Helpers+ Paths_vcsgui executable vcsgui-askpass- main-is: Main.hs- build-depends:- filepath >=1.2.0.0 && < 1.5,- base >=4.0.0.0 && <4.9,- directory >=1.1.0.0 && <1.3,- mtl >=2.0.1.0 && <2.3,- vcswrapper >=0.1.1 && <0.2,- process >=1.0.1.5 && <1.3,- text -any- if flag(gtk3)- build-depends: gtk3 >=0.12.4 && <0.15- cpp-options: -DMIN_VERSION_gtk=MIN_VERSION_gtk3- else- build-depends: gtk >=0.12.4 && <0.14+ if os(osx) ghc-options: -optl-headerpad_max_install_names- buildable: True+ main-is: Main.hs+ build-depends:+ filepath >=1.2.0.0 && <1.5,+ base >=4.0.0.0 && <4.10,+ directory >=1.1.0.0 && <1.3,+ mtl >=2.0.1.0 && <2.3,+ vcswrapper >=0.1.1 && <0.2,+ process >=1.0.1.5 && <1.5,+ text -any,+ haskell-gi-base >=0.20 && <0.21,+ gi-gtk >=3.0.6 && <3.1,+ gi-gtk-hs >=0.3.0.0 && <0.4 hs-source-dirs: src/exe/askpass src- other-modules: VCSGui.Svn.Helper VCSGui.Common.Process- VCSGui.Common.ConflictsResolved VCSGui.Common.MergeTool- VCSGui.Common.FilesInConflict VCSGui.Git.Pull VCSGui.Svn.Update- VCSGui.Svn.AskPassword Paths_vcsgui VCSGui.Common.GtkHelper- VCSGui.Common.Helpers+ other-modules:+ VCSGui.Svn.Helper+ VCSGui.Common.Process+ VCSGui.Common.ConflictsResolved+ VCSGui.Common.MergeTool+ VCSGui.Common.FilesInConflict+ VCSGui.Git.Pull+ VCSGui.Svn.Update+ VCSGui.Svn.AskPassword+ Paths_vcsgui+ VCSGui.Common.GtkHelper+ VCSGui.Common.Helpers+