module Manatee.Toolkit.Gtk.Multiline where
import Control.Monad
import Data.ByteString (ByteString)
import Graphics.UI.Gtk hiding (Statusbar, statusbarNew)
import Manatee.Toolkit.General.Basic
import Manatee.Toolkit.General.Functor
import Manatee.Toolkit.General.Maybe
import System.IO.Unsafe
textBufferWrapAction :: TextBufferClass self => self -> IO () -> IO ()
textBufferWrapAction tb action = do
textBufferBeginUserAction tb
action
textBufferEndUserAction tb
textBufferGetTagTextWithIter :: TextBufferClass buffer => buffer
-> TextIter
-> TextTag
-> IO (Maybe String)
textBufferGetTagTextWithIter buffer iter tag = do
startIter <- textIterCopy iter
endIter <- textIterCopy iter
moveBackward <- textIterBackwardToTagToggle startIter (Just tag)
moveForward <- textIterForwardToTagToggle endIter (Just tag)
if moveBackward && moveForward
then liftM Just $ textBufferGetText buffer startIter endIter True
else return Nothing
textBufferGetTagText :: TextBufferClass buffer => buffer
-> TextTag
-> IO (Maybe String)
textBufferGetTagText buffer tag = do
iter <- textBufferGetInsertIter buffer
textBufferGetTagTextWithIter buffer iter tag
textBufferGetTagByteStringWithIter :: TextBufferClass buffer => buffer
-> TextIter
-> TextTag
-> IO (Maybe ByteString)
textBufferGetTagByteStringWithIter buffer iter tag = do
startIter <- textIterCopy iter
endIter <- textIterCopy iter
moveBackward <- textIterBackwardToTagToggle startIter (Just tag)
moveForward <- textIterForwardToTagToggle endIter (Just tag)
if moveBackward && moveForward
then liftM Just $ textBufferGetByteString buffer startIter endIter True
else return Nothing
textBufferGetTagByteString :: TextBufferClass buffer => buffer
-> TextTag
-> IO (Maybe ByteString)
textBufferGetTagByteString buffer tag = do
iter <- textBufferGetInsertIter buffer
textBufferGetTagByteStringWithIter buffer iter tag
textBufferKeepSelection :: TextBufferClass self => self -> Bool -> Bool -> IO () -> IO ()
textBufferKeepSelection tb sLeft eLeft action = do
(sIter, eIter) <- textBufferGetSelectionBounds tb
fromUpToDown <- textBufferIsEqualInsertIter tb eIter
sMark <- textBufferCreateMark tb Nothing sIter sLeft
eMark <- textBufferCreateMark tb Nothing eIter eLeft
action
startIter <- textBufferGetIterAtMark tb sMark
endIter <- textBufferGetIterAtMark tb eMark
if fromUpToDown
then textBufferSelectRange tb endIter startIter
else textBufferSelectRange tb startIter endIter
textBufferUpdateSelectionIter tb
textBufferMoveRange :: TextBufferClass self => self -> TextIter -> TextIter -> TextIter -> IO ()
textBufferMoveRange tb iter start end =
unlessM (textIterEqual start end) $ do
textIterOrder start end
ifM (textIterInRange iter start end)
(do
sMark <- textBufferCreateMark tb Nothing start True
slice <- textBufferGetSlice tb start end True
textBufferDelete tb start end
textBufferInsertAtMark tb sMark slice)
(do
sMark <- textBufferCreateMark tb Nothing start True
eMark <- textBufferCreateMark tb Nothing end True
textBufferInsertRange tb iter start end
sIter <- textBufferGetIterAtMark tb sMark
eIter <- textBufferGetIterAtMark tb eMark
textBufferDelete tb sIter eIter)
textBufferCancelSelection :: TextBufferClass self => self -> IO ()
textBufferCancelSelection tb = do
iter <- textBufferGetInsertIter tb
textBufferSelectRange tb iter iter
textBufferGetInsertIter :: TextBufferClass self => self -> IO TextIter
textBufferGetInsertIter tb =
textBufferGetIterAtMark tb
=<< textBufferGetInsert tb
textBufferGetLineStartIter :: TextBufferClass self => self -> Int -> IO TextIter
textBufferGetLineStartIter = textBufferGetIterAtLine
textBufferGetCurrentLineStartIter :: TextBufferClass self => self -> IO TextIter
textBufferGetCurrentLineStartIter tb =
textBufferGetLineStartIter tb
=<< textBufferGetLine tb
textBufferGetLineEndIter :: TextBufferClass self => self -> Int -> Bool -> IO TextIter
textBufferGetLineEndIter tb line incDelimiter = do
iter <- textBufferGetInsertIter tb
textIterSetLine iter line
chars <- (if incDelimiter
then textIterGetCharsInLine
else textIterGetCharsInLine_ ) iter
textIterSetLineOffset iter chars
return iter
textBufferGetCurrentLineEndIter :: TextBufferClass self => self -> IO TextIter
textBufferGetCurrentLineEndIter tb = do
line <- textBufferGetLine tb
textBufferGetLineEndIter tb line True
textBufferGetCurrentLineEndIter_ :: TextBufferClass self => self -> IO TextIter
textBufferGetCurrentLineEndIter_ tb = do
line <- textBufferGetLine tb
textBufferGetLineEndIter tb line False
textBufferGetLine :: TextBufferClass self => self -> IO Int
textBufferGetLine tb =
textIterGetLine
=<< textBufferGetInsertIter tb
textBufferGetLineOffset :: TextBufferClass self => self -> IO Int
textBufferGetLineOffset tb =
textIterGetLineOffset
=<< textBufferGetInsertIter tb
textBufferSelectionIter :: Attr TextBuffer (Maybe TextIter)
textBufferSelectionIter = unsafePerformIO objectCreateAttribute
textBufferSetSelectionIter :: TextBufferClass self => self -> TextIter -> IO ()
textBufferSetSelectionIter tb ti =
set (toTextBuffer tb) [textBufferSelectionIter := Just ti]
textBufferRemoveSelectionIter :: TextBufferClass self => self -> IO ()
textBufferRemoveSelectionIter tb =
set (toTextBuffer tb) [textBufferSelectionIter := Nothing]
textBufferGetSelectionIter :: TextBufferClass self => self -> IO (Maybe TextIter)
textBufferGetSelectionIter tb =
get (toTextBuffer tb) textBufferSelectionIter
textBufferUpdateSelectionIter :: TextBufferClass self => self -> IO ()
textBufferUpdateSelectionIter tb =
ifM (textBufferHasSelection tb)
(textBufferSetSelectionIter tb
=<< textBufferGetSelectionBoundIter tb)
(textBufferRemoveSelectionIter tb)
textBufferGetSelectionBoundLines :: TextBufferClass self => self -> IO (TextIter, TextIter, Bool, Bool)
textBufferGetSelectionBoundLines tb = do
hasSelect <- textBufferHasSelection tb
if hasSelect
then do
(sIter, eIter) <- textBufferGetSelectionBounds tb
firstLine <- textIterIsFirstLine sIter
lastLine <- textIterIsLastLine eIter
textIterBackwardToLineStart sIter
chars <- textIterGetCharsInLine eIter
textIterSetLineOffset eIter chars
return (sIter, eIter, firstLine, lastLine)
else do
sIter <- textBufferGetCurrentLineStartIter tb
eIter <- textBufferGetCurrentLineEndIter tb
firstLine <- textIterIsFirstLine sIter
lastLine <- textIterIsLastLine sIter
return (sIter, eIter, firstLine, lastLine)
textBufferGetSelectionBoundIter :: TextBufferClass self => self -> IO TextIter
textBufferGetSelectionBoundIter tb = (<=<) (textBufferGetIterAtMark tb) textBufferGetSelectionBound tb
textBufferGetSelectionInsertIter :: TextBufferClass self => self -> IO TextIter
textBufferGetSelectionInsertIter = textBufferGetInsertIter
textBufferIsEqualInsertIter :: TextBufferClass self => self -> TextIter -> IO Bool
textBufferIsEqualInsertIter tb ti =
textIterEqual ti
=<< textBufferGetInsertIter tb
textBufferDeleteLastChar :: TextBufferClass self => self -> IO ()
textBufferDeleteLastChar tb = do
startIter <- textBufferGetEndIter tb
endIter <- textIterCopy startIter
textIterBackwardChar startIter
textBufferDelete tb startIter endIter
textBufferInsertNewlineAtMark :: TextBufferClass self => self -> TextMark -> IO ()
textBufferInsertNewlineAtMark tb mark =
textBufferInsertAtMark tb mark "\n"
textBufferInsertAtMark :: TextBufferClass self => self -> TextMark -> String -> IO ()
textBufferInsertAtMark tb mark str = do
iter <- textBufferGetIterAtMark tb mark
textBufferInsert tb iter str
textViewPlaceCursor :: TextViewClass self => self -> TextIter -> IO ()
textViewPlaceCursor tv ti = do
tb <- textViewGetBuffer tv
textBufferPlaceCursor tb ti
textViewScrollCursorOnscreen tv
textViewPlaceCursorWithMark :: TextViewClass self => self -> TextMark -> IO ()
textViewPlaceCursorWithMark tv tm = do
tb <- textViewGetBuffer tv
iter <- textBufferGetIterAtMark tb tm
textViewPlaceCursor tv iter
textViewGotoLine :: TextViewClass self => self -> Int -> IO ()
textViewGotoLine tv line = do
tb <- textViewGetBuffer tv
lineCount <- textBufferGetLineCount tb
let lineNumber
| line <= 1
= 1
| line > lineCount
= lineCount
| otherwise
= line
iter <- textBufferGetIterAtLine tb (lineNumber 1)
textViewPlaceCursor tv iter
textViewGotoColumn :: TextViewClass self => self -> Int -> IO ()
textViewGotoColumn tv column = do
tb <- textViewGetBuffer tv
currentIter <- textBufferGetInsertIter tb
columnCount <- textIterGetCharsInLine_ currentIter
let columnNumber
| column <= 0
= 0
| column > columnCount
= columnCount
| otherwise
= column
currentLine <- textIterGetLine currentIter
columnIter <- textBufferGetIterAtLineOffset tb currentLine columnNumber
textViewPlaceCursor tv columnIter
textViewWrapAction :: TextViewClass self => self -> IO () -> IO ()
textViewWrapAction tv action = do
tb <- textViewGetBuffer tv
textBufferWrapAction tb action
textViewLoadFile :: TextViewClass self => self -> FilePath -> IO ()
textViewLoadFile tv path = textViewSetText tv =<< readFile path
textViewSetText :: TextViewClass self => self -> String -> IO ()
textViewSetText tv str = do
tb <- textViewGetBuffer tv
textBufferSetText tb str
textViewGetTextIter :: TextViewClass self => self -> IO TextIter
textViewGetTextIter tv =
textBufferGetInsertIter
=<< textViewGetBuffer tv
textViewMoveTextIter :: (TextViewClass self, ScrolledWindowClass swc) => (TextIter -> IO Bool) -> self -> swc -> IO ()
textViewMoveTextIter move tv sw = do
ti <- textViewGetTextIter tv
move ti
tb <- textViewGetBuffer tv
textBufferPlaceCursor tb ti
aj <- scrolledWindowGetVAdjustment sw
vl <- adjustmentGetValue aj
y <- (<<<=) (i2d . fst) (textViewGetLineYrange tv)
=<< textViewGetTextIter tv
if y <= vl
then adjustmentSetValue aj y
else textViewScrollCursorOnscreen tv
return ()
textViewForwardLine :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewForwardLine =
textViewMoveTextIter $ \iter -> do
lastLine <- textIterIsLastLine iter
unless lastLine $ textIterForwardLine iter >> return ()
return True
textViewBackwardLine :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewBackwardLine = textViewMoveTextIter textIterBackwardLine
textViewForwardChar :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewForwardChar = textViewMoveTextIter textIterForwardChar
textViewBackwardChar :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewBackwardChar = textViewMoveTextIter textIterBackwardChar
textViewForwardWord :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewForwardWord = textViewMoveTextIter textIterForwardWordEnd
textViewBackwardWord :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewBackwardWord = textViewMoveTextIter textIterBackwardWordStart
textViewBegin :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewBegin =
textViewMoveTextIter $ \t -> textIterBackwardToStart t >> return True
textViewEnd :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewEnd =
textViewMoveTextIter $ \t -> textIterForwardToEnd t >> return True
textViewGetText :: TextViewClass self => self -> IO String
textViewGetText tv = do
tb <- textViewGetBuffer tv
(start, end) <- textBufferGetBounds tb
textBufferGetText tb start end True
textViewGetCurrentLineContent :: TextViewClass self => self -> IO String
textViewGetCurrentLineContent tv = do
tb <- textViewGetBuffer tv
startIter <- textBufferGetCurrentLineStartIter tb
endIter <- textBufferGetCurrentLineEndIter_ tb
textBufferGetText tb startIter endIter True
textViewGetLine :: TextViewClass self => self -> IO Int
textViewGetLine =
(<<<=) succ ((<=<) textIterGetLine textViewGetTextIter)
textViewGetColumn :: TextViewClass self => self -> IO Int
textViewGetColumn =
(<=<) textIterGetLineOffset textViewGetTextIter
textViewSelectAll :: TextViewClass self => self -> IO ()
textViewSelectAll tv = do
tb <- textViewGetBuffer tv
(start, end) <- textBufferGetBounds tb
textBufferSelectRange tb start end
textBufferUpdateSelectionIter tb
textViewDelete :: TextViewClass self => self -> Bool -> Bool -> IO Bool
textViewDelete tv interactive defaultEditable = do
tb <- textViewGetBuffer tv
textBufferDeleteSelection tb interactive defaultEditable
textViewCut :: TextViewClass self => self -> IO ()
textViewCut tv = do
tb <- textViewGetBuffer tv
clip <- clipboardGet selectionClipboard
textBufferCutClipboard tb clip True
textViewCopy :: TextViewClass self => self -> IO ()
textViewCopy tv = do
tb <- textViewGetBuffer tv
clip <- clipboardGet selectionClipboard
textBufferCopyClipboard tb clip
textViewPaste :: TextViewClass self => self -> IO ()
textViewPaste tv = do
tb <- textViewGetBuffer tv
clip <- clipboardGet selectionClipboard
textBufferPasteClipboardAtCursor tb clip True
textViewDeleteForwardChar :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteForwardChar tv =
textViewDeleteBound tv textIterForwardChar
textViewDeleteBackwardChar :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteBackwardChar tv =
textViewDeleteBound tv textIterBackwardChar
textViewDeleteForwardWord :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteForwardWord tv =
textViewDeleteBound tv textIterForwardWordEnd
textViewDeleteBackwardWord :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteBackwardWord tv =
textViewDeleteBound tv textIterBackwardWordStart
textViewDeleteToLineEnd :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteToLineEnd tv =
textViewDeleteBound tv textIterForwardToLineEnd
textViewDeleteToLineStart :: TextViewClass self => self -> Bool -> IO Bool
textViewDeleteToLineStart tv =
textViewDeleteBound tv (\t -> textIterBackwardToLineStart t >> return True)
textViewDeleteBound :: TextViewClass self => self -> (TextIter -> IO Bool) -> Bool -> IO Bool
textViewDeleteBound tv move deleteWhenEditable = do
tb <- textViewGetBuffer tv
start <- textViewGetTextIter tv
offset <- textIterGetOffset start
move start
end <- textViewGetTextIter tv
let deleteAction = do
textBufferDelete tb start end
return True
restoreAction = do
textIterSetOffset end offset
return False
isEditable <- textIterBoundIsEditable (start, end)
if deleteWhenEditable && not isEditable
then restoreAction
else deleteAction
textViewDupLines :: TextViewClass self => self -> Bool -> IO ()
textViewDupLines tv dupBelow = do
tb <- textViewGetBuffer tv
(sIter, eIter, _, lastLine) <- textBufferGetSelectionBoundLines tb
if dupBelow
then textBufferKeepSelection tb True True $
do
eMark <- textBufferCreateMark tb Nothing eIter True
textBufferInsertRange tb eIter sIter eIter
when lastLine $ textBufferInsertNewlineAtMark tb eMark
else textBufferKeepSelection tb False False $
do
sMark <- textBufferCreateMark tb Nothing sIter False
textBufferInsertRange tb sIter sIter eIter
when lastLine $ textBufferInsertNewlineAtMark tb sMark
textViewDupLinesBelow, textViewDupLinesAbove :: TextViewClass self => self -> IO ()
textViewDupLinesBelow tv = textViewDupLines tv True
textViewDupLinesAbove tv = textViewDupLines tv False
textViewTraLines :: TextViewClass self => self -> Bool -> IO ()
textViewTraLines tv traBelow = do
tb <- textViewGetBuffer tv
(sIter, eIter, firstLine, lastLine) <- textBufferGetSelectionBoundLines tb
if traBelow
then
unless lastLine $ textBufferKeepSelection tb False False $
do
sMark <- textBufferCreateMark tb Nothing sIter False
eMark <- textBufferCreateMark tb Nothing eIter False
trasStartIter <- textIterCopy eIter
trasEndIter <- textIterCopy eIter
atLastLine <- textIterIsLastLine eIter
chars <- textIterGetCharsInLine eIter
textIterSetLineOffset trasEndIter chars
textBufferMoveRange tb sIter trasStartIter trasEndIter
when atLastLine $ do
textBufferInsertNewlineAtMark tb sMark
textBufferDeleteLastChar tb
textViewScrollMarkOnscreen tv eMark
else
unless firstLine $ textBufferKeepSelection tb True True $
do
sMark <- textBufferCreateMark tb Nothing sIter True
eMark <- textBufferCreateMark tb Nothing eIter True
trasStartIter <- textIterCopy sIter
trasEndIter <- textIterCopy sIter
textIterBackwardLine trasStartIter
textBufferMoveRange tb eIter trasStartIter trasEndIter
when lastLine $ do
textBufferInsertNewlineAtMark tb eMark
textBufferDeleteLastChar tb
textViewScrollMarkOnscreen tv sMark
textViewTraLinesBelow, textViewTraLinesAbove :: TextViewClass self => self -> IO ()
textViewTraLinesBelow tv = textViewTraLines tv True
textViewTraLinesAbove tv = textViewTraLines tv False
textViewDelLines :: TextViewClass self => self -> IO Bool
textViewDelLines tv = do
tb <- textViewGetBuffer tv
(sIter, eIter, _, lastLine) <- textBufferGetSelectionBoundLines tb
isEditable <- textIterBoundIsEditable (sIter, eIter)
if isEditable
then do
textBufferDelete tb sIter eIter
when lastLine $ do
textViewDeleteBackwardChar tv False
iter <- textViewGetTextIter tv
textIterBackwardToLineStart iter
textBufferPlaceCursor tb iter
return True
else return False
textViewSmartHome :: TextViewClass self => self -> IO ()
textViewSmartHome tv = do
ti <- textViewGetTextIter tv
lo <- textIterGetLineOffset ti
tb <- textViewGetBuffer tv
textIterForwardToLineEnd_ ti
limit <- textIterCopy ti
textIterBackwardToLineStart ti
ifM (textIterForwardFindChar ti (/= ' ') (Just limit))
(do
nlo <- textIterGetLineOffset ti
if lo == nlo || nlo == 1
then textIterBackwardToLineStart ti
else textIterSetLineOffset ti nlo)
(textIterBackwardToLineStart ti)
textBufferPlaceCursor tb ti
textViewSmartEnd :: TextViewClass self => self -> IO ()
textViewSmartEnd tv = do
ti <- textViewGetTextIter tv
lo <- textIterGetLineOffset ti
tb <- textViewGetBuffer tv
textIterBackwardToLineStart ti
limit <- textIterCopy ti
textIterForwardToLineEnd_ ti
ifM (textIterBackwardFindChar ti (/= ' ') (Just limit))
(do
nlo <- textIterGetLineOffset ti
let nl = nlo + 1
if lo == nl || nlo == 0
then textIterForwardToLineEnd_ ti
else textIterSetLineOffset ti nl)
(textIterForwardToLineEnd_ ti)
textBufferPlaceCursor tb ti
textViewScrollVertical :: (TextViewClass tvc, ScrolledWindowClass swc) => tvc -> swc -> Double -> IO ()
textViewScrollVertical tv sw inc = do
aj <- scrolledWindowGetVAdjustment sw
ps <- adjustmentGetPageSize aj
vl <- adjustmentGetValue aj
ur <- adjustmentGetUpper aj
lr <- adjustmentGetLower aj
ti <- textViewGetTextIter tv
tb <- textViewGetBuffer tv
(y, lnH) <- textViewGetLineYrange tv ti
let iv = vl + inc
av = if inc >= 0
then min iv (ur i2d lnH)
else max iv lr
adjustmentSetValue aj av
top <- adjustmentGetValue aj
let bottom = top + ps
if top >= i2d y
then do
(nti, _) <- textViewGetLineAtY tv (truncate top)
textBufferPlaceCursor tb nti
else when (bottom <= i2d (y + lnH)) $
do
(nti, _) <- textViewGetLineAtY tv (truncate (bottom i2d lnH))
textBufferPlaceCursor tb nti
textViewToggleSelectionMark :: TextViewClass self => self -> IO ()
textViewToggleSelectionMark tv = do
tb <- textViewGetBuffer tv
selectionActive <- textBufferHasSelection tb
if selectionActive
then textViewCancelSelectionMark tv
else textViewSetSelectionMark tv
textViewExchangeSelectionMark :: TextViewClass self => self -> IO ()
textViewExchangeSelectionMark tv = do
tb <- textViewGetBuffer tv
selectionActive <- textBufferHasSelection tb
when selectionActive $ do
(sIter, eIter) <- textBufferGetSelectionBounds tb
selectionAbove <- textBufferIsEqualInsertIter tb sIter
let (startIter, endIter) =
if selectionAbove
then (eIter, sIter)
else (sIter, eIter)
textBufferSetSelectionIter tb endIter
textBufferSelectRange tb startIter endIter
textViewScrollCursorOnscreen tv
textViewScrollCursorOnscreen :: TextViewClass self => self -> IO ()
textViewScrollCursorOnscreen tv =
textViewScrollMarkOnscreen tv
=<< (<=<) textBufferGetInsert textViewGetBuffer tv
textViewSetSelectionMark :: TextViewClass self => self -> IO ()
textViewSetSelectionMark tv = do
tb <- textViewGetBuffer tv
textBufferCancelSelection tb
textBufferSetSelectionIter tb
=<< textViewGetTextIter tv
textViewCancelSelectionMark :: TextViewClass self => self -> IO ()
textViewCancelSelectionMark tv = do
tb <- textViewGetBuffer tv
textBufferCancelSelection tb
textBufferRemoveSelectionIter tb
textViewApplySelectionMark :: TextViewClass self => self -> IO ()
textViewApplySelectionMark tv = do
tb <- textViewGetBuffer tv
textBufferGetSelectionIter tb >>=
(?>= (\markIter -> do
insertIter <- textBufferGetInsertIter tb
textBufferSelectRange tb insertIter markIter))
textViewNewLine :: TextViewClass self => self -> IO ()
textViewNewLine tv =
textViewInsertAtCursor tv "\n"
textViewInsertAtCursor :: TextViewClass self => self -> String -> IO ()
textViewInsertAtCursor tv str = do
tb <- textViewGetBuffer tv
textBufferCancelSelection tb
textBufferInsertAtCursor tb str
textViewScrollCursorOnscreen tv
textViewOpenNewlineBelow :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewOpenNewlineBelow tv swc = do
tb <- textViewGetBuffer tv
iter <- textViewGetTextIter tv
inBlankLine <- textIterInBlankLine iter
textIterForwardToLineEnd_ iter
textBufferInsert tb iter "\n"
unless inBlankLine $ textViewForwardLine tv swc
textViewOpenNewlineAbove :: (TextViewClass self, ScrolledWindowClass swc) => self -> swc -> IO ()
textViewOpenNewlineAbove tv swc = do
tb <- textViewGetBuffer tv
iter <- textViewGetTextIter tv
textIterBackwardToLineStart iter
textBufferInsert tb iter "\n"
textViewBackwardLine tv swc
textIterBackwardToStart :: TextIter -> IO ()
textIterBackwardToStart ti = do
textIterSetLine ti 0
textIterBackwardToLineStart ti
textIterForwardToLineEnd_ :: TextIter -> IO ()
textIterForwardToLineEnd_ ti =
textIterSetLineOffset ti
=<< textIterGetCharsInLine_ ti
textIterInBlankLine :: TextIter -> IO Bool
textIterInBlankLine =
(<<<=) (1 ==) textIterGetCharsInLine
textIterIsFirstLine :: TextIter -> IO Bool
textIterIsFirstLine =
(<<<=) (0 ==) textIterGetLine
textIterIsLastLine :: TextIter -> IO Bool
textIterIsLastLine ti = do
line <- textIterGetLine ti
lines <- (<=<) textBufferGetLineCount textIterGetBuffer ti
return $ line == (lines 1)
textIterBackwardToLineStart :: TextIter -> IO ()
textIterBackwardToLineStart ti =
textIterSetLineOffset ti 0
textIterGetCharsInLine_ :: TextIter -> IO Int
textIterGetCharsInLine_ ti = do
chars <- textIterGetCharsInLine ti
ifM (textIterIsLastLine ti)
(return chars)
(return $ chars 1)
textIterBoundIsEditable :: (TextIter, TextIter) -> IO Bool
textIterBoundIsEditable (startIter, endIter) =
liftM2 (&&)
(textIterEditable startIter True)
(textIterEditable endIter True)