hoodle-core-0.13: src/Hoodle/Coroutine/Select/Clipboard.hs
-----------------------------------------------------------------------------
-- |
-- Module : Hoodle.Coroutine.Select.Clipboard
-- Copyright : (c) 2011-2013 Ian-Woo Kim
--
-- License : BSD3
-- Maintainer : Ian-Woo Kim <ianwookim@gmail.com>
-- Stability : experimental
-- Portability : GHC
--
-- Clipboard action while dealing with selection
--
-----------------------------------------------------------------------------
module Hoodle.Coroutine.Select.Clipboard where
-- from other packages
import Control.Lens (view,set,(%~))
import Control.Monad.State
import Graphics.UI.Gtk hiding (get,set)
-- from hoodle-platform
import Control.Monad.Trans.Crtn.Queue
import Data.Hoodle.Generic
import Data.Hoodle.Select
import Data.Hoodle.Simple
import Graphics.Hoodle.Render.Item
import Graphics.Hoodle.Render.Type
import Graphics.Hoodle.Render.Type.HitTest
-- from this package
import Hoodle.Accessor
import Hoodle.Coroutine.Draw
import Hoodle.Coroutine.Commit
import Hoodle.Coroutine.Mode
import Hoodle.ModelAction.Page
import Hoodle.ModelAction.Select
import Hoodle.ModelAction.Select.Transform
import Hoodle.ModelAction.Clipboard
import Hoodle.Type.Canvas
import Hoodle.Type.Coroutine
import Hoodle.Type.Event
import Hoodle.Type.PageArrangement
import Hoodle.Type.HoodleState
-- |
deleteSelection :: MainCoroutine ()
deleteSelection = do
xstate <- get
case view hoodleModeState xstate of
SelectState thdl -> do
let Just (n,tpage) = view gselSelected thdl
slayer = view (glayers.selectedLayer) tpage
case unTEitherAlterHitted . view gitems $ slayer of
Left _ -> return ()
Right alist -> do
let newlayer = Left . concat . getA $ alist
newpage = set (glayers.selectedLayer) (GLayer (view gbuffer slayer) (TEitherAlterHitted newlayer)) tpage
newthdl <- liftIO $ updateTempHoodleSelectIO thdl newpage n
newxstate <- liftIO $ updatePageAll (SelectState newthdl)
. set hoodleModeState (SelectState newthdl)
$ xstate
commit newxstate
let ui = view gtkUIManager newxstate
liftIO $ toggleCutCopyDelete ui False
modeChange ToViewAppendMode
invalidateAll
_ -> return ()
-- |
cutSelection :: MainCoroutine ()
cutSelection = copySelection >> deleteSelection
-- |
copySelection :: MainCoroutine ()
copySelection = do
updateXState copySelectionAction >> invalidateAll
where copySelectionAction xst =
forBoth' unboxBiAct (fsingle xst) . view currentCanvasInfo $ xst
fsingle xstate cinfo = maybe (return xstate) id $ do
let hdlmodst = view hoodleModeState xstate
let epage = getCurrentPageEitherFromHoodleModeState cinfo hdlmodst
eitherMaybe epage `pipe` rItmsInActiveLyr
`pipe` (Right . liftIO . updateClipboard xstate . map rItem2Item . takeHitted)
where eitherMaybe (Left _) = Nothing
eitherMaybe (Right a) = Just a
x `pipe` a = x >>= eitherMaybe . a
infixl 6 `pipe`
-- |
getClipFromGtk :: MainCoroutine (Maybe [Item])
getClipFromGtk = do
let action = mkIOaction $
\evhandler -> do
hdltag <- liftIO $ atomNew "hoodle"
clipbd <- liftIO $ clipboardGet hdltag
liftIO $ clipboardRequestText clipbd (callback4Clip evhandler)
return (UsrEv ActionOrdered)
modify (tempQueue %~ enqueue action)
go
where go = do r <- nextevent
case r of
GotClipboardContent cnt' -> return cnt'
_ -> go
-- |
pasteToSelection :: MainCoroutine ()
pasteToSelection = do
mitms <- getClipFromGtk
case mitms of
Nothing -> return ()
Just itms -> do
ritms <- liftIO (mapM cnstrctRItem itms)
modeChange ToSelectMode >>updateXState (pasteAction ritms) >> invalidateAll
where
pasteAction itms xst = forBoth' unboxBiAct (fsimple itms xst) . view currentCanvasInfo $ xst
fsimple itms xstate cinfo = do
geometry <- liftIO (getGeometry4CurrCvs xstate)
let pagenum = view currentPageNum cinfo
hdlmodst@(SelectState thdl) = view hoodleModeState xstate
nclipitms = adjustItemPosition4Paste geometry (PageNum pagenum) itms
epage = getCurrentPageEitherFromHoodleModeState cinfo hdlmodst
tpage = either mkHPage id epage
layerselect = view (glayers.selectedLayer) tpage
gbuf = view gbuffer layerselect
newlayerselect = case rItmsInActiveLyr tpage of
Left nitms -> (GLayer gbuf . TEitherAlterHitted . Right) (nitms :- Hitted nclipitms :- Empty)
Right alist -> (GLayer gbuf . TEitherAlterHitted . Right)
(concat (interleave id unHitted alist)
:- Hitted nclipitms
:- Empty )
tpage' = set (glayers.selectedLayer) newlayerselect tpage
thdl' <- liftIO $ updateTempHoodleSelectIO thdl tpage' pagenum
xstate' <- liftIO $ updatePageAll (SelectState thdl')
. set hoodleModeState (SelectState thdl')
$ xstate
commit xstate'
let ui = view gtkUIManager xstate'
liftIO $ toggleCutCopyDelete ui True
return xstate'