vision-0.0.5.0: src/Collection/PropFlt.hs
-- -*-haskell-*-
-- Vision (for the Voice): an XMMS2 client.
--
-- Author: Oleg Belozeorov
-- Created: 6 Jul. 2011
--
-- Copyright (C) 2011 Oleg Belozeorov
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 3 of
-- the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
module Collection.PropFlt
( PropFlt (..)
, mkPropFlt
) where
import Prelude hiding (lookup)
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Data.List (intercalate, isInfixOf)
import Data.Char (toLower)
import Data.Map (lookup)
import Data.IORef
import Graphics.UI.Gtk
import XMMS2.Client hiding (Property)
import qualified XMMS2.Client as X
import Properties hiding (lookup)
import XMMS
import Utils
import Compound
import Collection.Common
import Collection.Actions
import Collection.Utils
data PropFlt
= PF { pStore :: ListStore X.Property
, pView :: TreeView
, pSel :: TreeSelection
, pScroll :: ScrolledWindow
, pColl :: Coll
, pProp :: Property
, pNextRef :: IORef VI
}
instance ViewItem PropFlt where
nextVIRef = pNextRef
mkPropFlt env prop coll = do
let abRef = eABRef env
ae = eAE env
store <- listStoreNewDND [] Nothing Nothing
view <- treeViewNewWithModel store
treeViewSetHeadersVisible view False
sel <- treeViewGetSelection view
treeSelectionSetMode sel SelectionMultiple
treeViewSetRulesHint view True
setupTreeViewPopup view $ eVPopup env
column <- treeViewColumnNew
treeViewAppendColumn view column
cell <- cellRendererTextNew
treeViewColumnPackStart column cell True
cellLayoutSetAttributes column cell store $ \p ->
[ cellText := showValue prop p ]
scroll <- scrolledWindowNew Nothing Nothing
scrolledWindowSetShadowType scroll ShadowIn
scrolledWindowSetPolicy scroll PolicyNever PolicyAutomatic
containerAdd scroll view
widgetShowAll scroll
treeViewSetEnableSearch view True
treeViewSetSearchEqualFunc view . Just $ \str iter ->
(isInfixOf (map toLower str) . map toLower . showValue prop) <$>
(listStoreGetValue store $ listStoreIterToIndex iter)
fcoll <- collNew TypeIntersection
collAddOperand fcoll coll
flt <- collParse $ "NOT " ++ propKey prop ++ ":''"
collAddOperand fcoll flt
let key = propKey prop
addLine v [] = return v
addLine v (p : ps) =
case lookup key p of
Just s | v == s -> addLine v ps
| otherwise -> do
listStoreAppend store s
addLine s ps
Nothing -> addLine v ps
getInfos s v =
collQueryInfos xmms fcoll [key] s 100 [key] [key] >>* do
lst <- result
len <- resultLength
liftIO $ do
v' <- addLine v lst
when (len == 100) $
getInfos (s + 100) v'
getInfos 0 (PropString "")
nextRef <- newIORef None
let pf = PF { pStore = store
, pView = view
, pSel = sel
, pScroll = scroll
, pColl = fcoll
, pProp = prop
, pNextRef = nextRef
}
aef = do
foc <- view `get` widgetHasFocus
when foc $ do
rows <- treeSelectionGetSelectedRows sel
aEnableSel ae $ not $ null rows
aEnableRen ae False
aEnableDel ae False
setupViewFocus abRef view aef
AB { aWithColl = withBuiltColl pf
, aWithNames = const $ return ()
, aSelection = Just sel
}
sel `on` treeSelectionSelectionChanged $ aef
return pf
instance CollBuilder PropFlt where
withBuiltColl pf f = do
let store = pStore pf
sel = pSel pf
rows <- treeSelectionGetSelectedRows sel
unless (null rows) $ do
vals <- mapM (listStoreGetValue store . head) rows
int <- collNew TypeIntersection
collAddOperand int $ pColl pf
flt <- collParse $ mkFilterText (pProp pf) vals
collAddOperand int flt
f int
treeViewSel pf = (pView pf, pSel pf)
instance CompoundWidget PropFlt where
type Outer PropFlt = ScrolledWindow
outer = pScroll
instance FocusChild PropFlt where
type Focus PropFlt = TreeView
focus = pView
cond' [] = "'"
cond' ('\'' : t) = '\\' : '\'' : cond' t
cond' ('\\' : t) = '\\' : '\\' : cond' t
cond' (h : t) = h : cond' t
cond prop (PropString s)
| propKey prop == "url" = "url:'" ++ s ++ "'"
| otherwise = propKey prop ++ ":'" ++ cond' s
cond prop (PropInt32 i) = propKey prop ++ ":" ++ show i
mkFilterText prop vals =
intercalate " OR " $ map (cond prop) vals