packages feed

spike-0.2: src/Utils.hs

module Utils where

import Control.Concurrent.STM
import Graphics.UI.Gtk.WebKit.WebView
import Graphics.UI.Gtk.WebKit.WebHistoryItem
import Graphics.UI.Gtk.WebKit.WebBackForwardList
import Graphics.UI.Gtk
import Data.Tree
import Data.Maybe
import Data.Tree.Zipper

import Datatypes

-- | wait until the TVar changes it's value from specified outer value
waitTVarChangeFrom :: (Eq a) => a -> (TVar a) -> IO a
waitTVarChangeFrom t tv = do
  tNew <- atomically $ do
                      t' <- readTVar tv
                      if (t' /= t) then return t' else retry
  return tNew

-- | wait until the TVar changes it's value from it's current value
waitTVarChange :: (Eq a) => (TVar a) -> IO a
waitTVarChange tv = readTVarIO tv >>= flip waitTVarChangeFrom tv

-- | block for two TVars to change their value from specified tuple value
waitTVarChangePairFrom :: (Eq a,Eq b) => (a,b) -> ((TVar a),(TVar b)) -> IO (a,b)
waitTVarChangePairFrom (ta,tb) (tva,tvb) = do
  tt <- atomically $ do
                      ta' <- readTVar tva
                      tb' <- readTVar tvb
                      let tt' = (ta',tb')
                      if tt' /= (ta,tb) then return tt' else retry
  return tt

-- | block for two TVars to change their value from their current values
waitTVarChangePair :: (Eq a,Eq b) => ((TVar a),(TVar b)) -> IO (a,b)
waitTVarChangePair tt@(tva,tvb) = do
  ta <- readTVarIO tva
  tb <- readTVarIO tvb
  waitTVarChangePairFrom (ta,tb) tt



dontReenter :: TVar Bool -> IO a -> IO ()
dontReenter var act = do
  a' <- atomically $ do
          v <- readTVar var
          if v 
           then return (return ()) 
           else writeTVar var True >> return (act >> atomically (writeTVar var False))
  a'

callDepthCount :: TVar Int -> (Int -> IO a) -> IO ()
callDepthCount var act = do
  v <- atomically $ do
         v' <- readTVar var
         writeTVar var (v'+1)
         return v'
  act v
  atomically $ writeTVar var v

----------------


isWidgetPage :: Widget -> Page -> IO Bool
isWidgetPage w p = do
  return (pgWidget p == w)

isSamePage :: Page -> Page -> Bool
isSamePage p1 p2 = pgWidget p1 == pgWidget p2

getPageTitle :: Page -> IO String
getPageTitle p = do
  let web = pgWeb p
  mtit <- webViewGetTitle web
  muri <- webViewGetUri web
  bflst <- webViewGetBackForwardList web

  let titles = catMaybes [mtit, muri] ++ [pgStartURI p]

  return $ head titles

flattenToZipper :: Tree a -> [TreePos Full a]
flattenToZipper n@(Node _ sub) = fromTree n : concatMap flattenToZipper sub


flattenToZipper' :: Tree a -> [TreePos Full a]
flattenToZipper' n = go (fromTree n) where
    go z = [z] ++ (fromMaybe [] (fmap go (firstChild z))) ++ (fromMaybe [] (fmap go (next z)))