[project @ 2002-06-13 23:03:12 by as49] Reversing the argument order flipped some arguments which weren't supposed to move. Jens Petersen pointed that out.

-- -*-haskell-*-
--  GIMP Toolkit (GTK) @entry TextIter abstract datatype@
--
--  Author : Axel Simon
--
--  Created: 23 February 2002
--
--  Version $Revision: 1.3 $ from $Date: 2002/06/13 23:03:12 $
--
--  This file 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 2 of the License, or
--  (at your option) any later version.
--
--  This file 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.
--
-- @description@ --------------------------------------------------------------
--
--   * An iterator is an abstract datatype representing a pointer into a
--     @TextBuffer.
--
-- @documentation@ ------------------------------------------------------------
--
-- * The following functions do not make sense due to Haskell's wide character
--   representation of Unicode:
--     gtk_text_iter_get_line_index
--     gtk_text_iter_get_visible_line_index
--     gtk_text_iter_get_bytes_in_line
--     gtk_text_iter_set_line_index
--     gtk_text_iter_set_visible_line_index
--
-- * The functions gtk_text_iter_in_range and gtk_text_iter_order are not bound
--   because they are only convenience functions which can replaced by calls
--   to textIterCompare.
--
-- * All offsets are counted from 0.
--
-- @todo@ ---------------------------------------------------------------------
--
-- * Bind the following function when GSList is bound:
--     gtk_text_iter_get_marks
--     gtk_text_iter_get_toggled_tags
--     gtk_text_iter_get_tags
--
-- * Bind the following functions when we are sure about anchors
--   (see @TextBuffer):
--     gtk_text_iter_get_anchor
--
-- * Bind TextAttribute functions when I am clear how to model them.
--     gtk_text_iter_get_attribute
--
-- * Forward exceptions in the two callback functions.
--
module TextIter(
  TextIter(TextIter),
  mkTextIter,
  makeEmptyTextIter,	-- for internal use only
  textIterGetBuffer,
  textIterCopy,
  textIterGetOffset,
  textIterGetLine,
  textIterGetLineOffset,
  textIterGetVisibleLineOffset,
  textIterGetChar,
  textIterGetSlice,
  textIterGetText,
  textIterGetVisibleSlice,
  textIterGetVisibleText,
  textIterGetPixbuf,
  textIterBeginsTag,
  textIterEndsTag,
  textIterTogglesTag,
  textIterHasTag,
  textIterEditable,
  textIterCanInsert,
  textIterStartsWord,
  textIterEndsWord,
  textIterInsideWord,
  textIterStartsLine,
  textIterEndsLine,
  textIterStartsSentence,
  textIterEndsSentence,
  textIterInsideSentence,
  textIterIsCursorPosition,
  textIterGetCharsInLine,
  textIterIsEnd,
  textIterIsStart,
  textIterForwardChar,
  textIterBackwardChar,
  textIterForwardChars,
  textIterBackwardChars,
  textIterForwardLine,
  textIterBackwardLine,
  textIterForwardLines,
  textIterBackwardLines,
  textIterForwardWordEnds,
  textIterBackwardWordStarts,
  textIterForwardWordEnd,
  textIterBackwardWordStart,
  textIterForwardCursorPosition,
  textIterBackwardCursorPosition,
  textIterForwardCursorPositions,
  textIterBackwardCursorPositions,
  textIterForwardSentenceEnds,
  textIterBackwardSentenceStarts,
  textIterForwardSentenceEnd,
  textIterBackwardSentenceStart,
  textIterSetOffset,
  textIterSetLine,
  textIterSetLineOffset,
  textIterSetVisibleLineOffset,
  textIterForwardToEnd,
  textIterForwardToLineEnd,
  textIterForwardToTagToggle,
  textIterBackwardToTagToggle,
  textIterForwardFindChar,
  textIterBackwardFindChar,
  textIterForwardSearch,
  textIterBackwardSearch,
  textIterEqual,
  textIterCompare
  ) where

import Monad	(liftM)
import Maybe	(fromMaybe)
import Char	(chr)
import Foreign
import CForeign
import GObject	(makeNewGObject)
{#import Hierarchy#}
{#import Signal#}
import Structs  (nullForeignPtr, textIterSize)
import Enums	(TextSearchFlags, Flags(fromFlags))

{# context lib="gtk" prefix="gtk" #}

-- methods

{#pointer *TextIter foreign newtype #}

-- Create a @TextIter from a pointer.
--
mkTextIter :: Ptr TextIter -> IO TextIter
mkTextIter iterPtr = liftM TextIter $
  newForeignPtr iterPtr (textIterFree iterPtr)

-- Allocate memory to be filled with a @TextIter.
--
makeEmptyTextIter :: IO TextIter
makeEmptyTextIter = do
  iterPtr <- mallocBytes textIterSize
  liftM TextIter $ newForeignPtr iterPtr (textIterFree iterPtr)

-- Free a @TextIter pointer.
--
foreign import ccall "gtk_text_iter_free" unsafe
  textIterFree :: Ptr TextIter -> IO ()

-- @method textIterGetBuffer@ Return the @ref type TextBuffer@ this iterator
-- is associated with.
--
textIterGetBuffer :: TextIter -> IO TextBuffer
textIterGetBuffer ti = makeNewGObject mkTextBuffer $
  {#call unsafe text_iter_get_buffer#} ti

-- @method textIterCopy@ Copy the iterator.
--
textIterCopy :: TextIter -> IO TextIter
textIterCopy ti = do
  iterPtr <- {#call unsafe text_iter_copy#} ti
  liftM TextIter $ newForeignPtr iterPtr (textIterFree iterPtr)

-- @method textIterGetOffset@ Extract the offset relative to the beginning of
-- the buffer.
--
textIterGetOffset :: TextIter -> IO Int
textIterGetOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_offset#} ti

-- @method textIterGetLine@ Extract the line of the buffer.
--
textIterGetLine :: TextIter -> IO Int
textIterGetLine ti = liftM fromIntegral $
  {#call unsafe text_iter_get_line#} ti

-- @method textIterGetLineOffset@ Extract the offset relative to the beginning
-- of the line.
--
textIterGetLineOffset :: TextIter -> IO Int
textIterGetLineOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_line_offset#} ti

-- @method textIterGetVisibleLineOffset@ Extract the offset relative to the
-- beginning of the line skipping invisible parts of the line.
--
textIterGetVisibleLineOffset :: TextIter -> IO Int
textIterGetVisibleLineOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_visible_line_offset#} ti

-- @method textIterGetChar@ Return the character at this iterator.
--
textIterGetChar :: TextIter -> IO (Maybe Char)
textIterGetChar ti = do
  (res::Int) <- liftM fromIntegral $ {#call unsafe text_iter_get_char#} ti
  return $ if res==0 then Nothing else Just (chr res)

-- @method textIterGetSlice@ Return the text in a given range.
--
-- * Pictures (and other objects) are represented by 0xFFFC.
--
textIterGetSlice :: TextIter -> TextIter -> IO String
textIterGetSlice end start = do
  cStr <- {#call text_iter_get_slice#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetText@ Return the text in a given range.
--
-- * Pictures (and other objects) are stripped form the output.
--
textIterGetText :: TextIter -> TextIter -> IO String
textIterGetText start end = do
  cStr <- {#call text_iter_get_text#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetVisibleSlice@ Return the visible text in a given range.
--
-- * Pictures (and other objects) are represented by 0xFFFC.
--
textIterGetVisibleSlice :: TextIter -> TextIter -> IO String
textIterGetVisibleSlice start end = do
  cStr <- {#call text_iter_get_visible_slice#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetVisibleText@ Return the visible text in a given range.
--
-- * Pictures (and other objects) are stripped form the output.
--
textIterGetVisibleText :: TextIter -> TextIter -> IO String
textIterGetVisibleText start end = do
  cStr <- {#call text_iter_get_visible_text#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetPixbuf@ Get the @ref arg GdkPixbuf@ under the iterator.
--
textIterGetPixbuf :: TextIter -> IO (Maybe GdkPixbuf)
textIterGetPixbuf it = do
  pbPtr <- {#call unsafe text_iter_get_pixbuf#} it
  if pbPtr==nullPtr then return Nothing else liftM Just $
    makeNewGObject mkGdkPixbuf (return pbPtr)

-- @method textIterBeginsTag@ Query whether a @ref type TextIter@ is at the
-- start of a @ref type TextTag@.
--
textIterBeginsTag :: TextIter -> TextTag -> IO Bool
textIterBeginsTag ti tt = liftM toBool $
  {#call unsafe text_iter_begins_tag#} ti tt

-- @method textIterEndsTag@ Query whether a @ref type TextIter@ is at the end
-- of a @ref type TextTag@.
--
textIterEndsTag :: TextIter -> TextTag -> IO Bool
textIterEndsTag ti tt = liftM toBool $
  {#call unsafe text_iter_ends_tag#} ti tt

-- @method textIterTogglesTag@ Query if the @ref type TextIter@ is at the
-- beginning or the end of a @ref type TextTag@.
--
textIterTogglesTag :: TextIter -> TextTag -> IO Bool
textIterTogglesTag ti tt = liftM toBool $
  {#call unsafe text_iter_toggles_tag#} ti tt

-- @method textIterHasTag@ Check if @ref type TextIter@ is within a range
-- tagged with tag.
--
textIterHasTag :: TextIter -> TextTag -> IO Bool
textIterHasTag ti tt = liftM toBool $
  {#call unsafe text_iter_has_tag#} ti tt

-- @method textIterEditable@ Check if @ref type TextIter@ is within an
-- editable region.
--
-- * If no tags that affect editability are attached to the current position
--   @ref arg def@ will be returned.
--
-- * This function cannot be used to decide whether text can be inserted at
--   @ref type TextIter@. Use the @ref method textIterCanInsert@ function for
--   this purpose.
--
textIterEditable :: TextIter -> Bool -> IO Bool
textIterEditable ti def = liftM toBool $
  {#call unsafe text_iter_editable#} ti (fromBool def)

-- @method textIterCanInsert@ Check if new text can be inserted at
-- @ref type TextIter@.
--
-- * Use @ref method textBufferInsertInteractive@ if you want to insert text
--   depending on the current editable status.
--
textIterCanInsert :: TextIter -> Bool -> IO Bool
textIterCanInsert ti def = liftM toBool $
  {#call unsafe text_iter_can_insert#} ti (fromBool def)

-- @method textIterStartsWord@ Determine if @ref type TextIter@ begins a new
-- natural-language word.
--
textIterStartsWord :: TextIter -> IO Bool
textIterStartsWord ti = liftM toBool $ {#call unsafe text_iter_starts_word#} ti

-- @method textIterEndsWord@ Determine if @ref type TextIter@ ends a new
-- natural-language word.
--
textIterEndsWord :: TextIter -> IO Bool
textIterEndsWord ti = liftM toBool $ {#call unsafe text_iter_ends_word#} ti

-- @method textIterInsideWord@ Determine if @ref type TextIter@ is inside a
-- word.
--
textIterInsideWord :: TextIter -> IO Bool
textIterInsideWord ti = liftM toBool $ {#call unsafe text_iter_inside_word#} ti

-- @method textIterStartsLine@ Determine if @ref type TextIter@ begins a new
-- line.
--
textIterStartsLine :: TextIter -> IO Bool
textIterStartsLine ti = liftM toBool $ {#call unsafe text_iter_starts_line#} ti

-- @method textIterEndsLine@ Determine if @ref type TextIter@ point to the
-- beginning of a line delimiter.
--
-- * Returns False if @ref type TextIter@ points to the \n in a \r\n sequence.
--
textIterEndsLine :: TextIter -> IO Bool
textIterEndsLine ti = liftM toBool $ {#call unsafe text_iter_ends_line#} ti

-- @method textIterStartsSentence@ Determine if @ref type TextIter@ starts a
-- sentence.
--
textIterStartsSentence :: TextIter -> IO Bool
textIterStartsSentence ti = liftM toBool $
  {#call unsafe text_iter_starts_sentence#} ti

-- @method textIterEndsSentence@ Determine if @ref type TextIter@ ends a
-- sentence.
--
textIterEndsSentence :: TextIter -> IO Bool
textIterEndsSentence ti = liftM toBool $
  {#call unsafe text_iter_ends_sentence#} ti

-- @method textIterInsideSentence@ Determine if @ref type TextIter@ is inside
-- a sentence.
--
textIterInsideSentence :: TextIter -> IO Bool
textIterInsideSentence ti = liftM toBool $
  {#call unsafe text_iter_inside_sentence#} ti

-- @method textIterIsCursorPosition@ Determine if @ref type TextIter@ is at a
-- cursor position.
--
textIterIsCursorPosition :: TextIter -> IO Bool
textIterIsCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_is_cursor_position#} ti

-- @method textIterGetCharsInLine@ Return number of characters in this line.
--
-- * The return value includes delimiters.
--
textIterGetCharsInLine :: TextIter -> IO Int
textIterGetCharsInLine ti = liftM fromIntegral $
  {#call unsafe text_iter_get_chars_in_line#} ti

-- @dunno@Get the text attributes at the iterator.
-- * The @ta argument gives the default values if no specific attributes are
--   set at that specific location.
--
-- * The function returns Nothing if the text at the iterator has the same
--   attributes.

-- @method textIterIsEnd@ Determine if @ref type TextIter@ is at the end of
-- the buffer.
--
textIterIsEnd :: TextIter -> IO Bool
textIterIsEnd ti = liftM toBool $
  {#call unsafe text_iter_is_end#} ti

-- @method textIterIsStart@ Determine if @ref type TextIter@ is at the
-- beginning of the buffer.
--
textIterIsStart :: TextIter -> IO Bool
textIterIsStart ti = liftM toBool $
  {#call unsafe text_iter_is_start#} ti

-- @method textIterForwardChar@ Move @ref type TextIter@ forwards.
--
-- * Retuns True if the iterator is pointing to a character.
--
textIterForwardChar :: TextIter -> IO Bool
textIterForwardChar ti = liftM toBool $
  {#call unsafe text_iter_forward_char#} ti

-- @method textIterBackwardChar@ Move @ref type TextIter@ backwards.
--
-- * Retuns True if the movement was possible.
--
textIterBackwardChar :: TextIter -> IO Bool
textIterBackwardChar ti = liftM toBool $
  {#call unsafe text_iter_backward_char#} ti

-- @method textIterForwardChars@ Move @ref type TextIter@ forwards by
-- @ref arg n@ characters.
--
-- * Retuns True if the iterator is pointing to a new character (and False if
--   the iterator points to a picture or has not moved).
--
textIterForwardChars :: TextIter -> Int -> IO Bool
textIterForwardChars ti n = liftM toBool $
  {#call unsafe text_iter_forward_chars#} ti (fromIntegral n)

-- @method textIterBackwardChars@ Move @ref type TextIter@ backwards by
-- @ref arg n@ characters.
--
-- * Retuns True if the iterator is pointing to a new character (and False if
--   the iterator points to a picture or has not moved).
--
textIterBackwardChars :: TextIter -> Int -> IO Bool
textIterBackwardChars ti n = liftM toBool $
  {#call unsafe text_iter_backward_chars#} ti (fromIntegral n)

-- @method textIterForwardLine@ Move @ref type TextIter@ forwards.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the
--   beginning of the buffer.
--
textIterForwardLine :: TextIter -> IO Bool
textIterForwardLine ti = liftM toBool $
  {#call unsafe text_iter_forward_line#} ti

-- @method textIterBackwardLine@ Move @ref type TextIter@ backwards.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the end
--   of the buffer.
--
textIterBackwardLine :: TextIter -> IO Bool
textIterBackwardLine ti = liftM toBool $
  {#call unsafe text_iter_backward_line#} ti

-- @method textIterForwardLines@ Move @ref type TextIter@ forwards by
-- @ref arg n@ lines.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the
--   beginning of the buffer.
--
-- * @ref arg n@ can be negative.
--
textIterForwardLines :: TextIter -> Int -> IO Bool
textIterForwardLines ti n = liftM toBool $
  {#call unsafe text_iter_forward_lines#} ti (fromIntegral n)

-- @method textIterBackwardLines@ Move @ref type TextIter@ backwards by
-- @ref arg n@ lines.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the end
--   of the buffer.
--
-- * @ref arg n@ can be negative.
--
textIterBackwardLines :: TextIter -> Int -> IO Bool
textIterBackwardLines ti n = liftM toBool $
  {#call unsafe text_iter_backward_lines#} ti (fromIntegral n)

-- @method textIterForwardWordEnds@ Move @ref type TextIter@ forwards by
-- @ref arg n@ word ends.
--
-- * Retuns True if the iterator is pointing to a new word end.
--
textIterForwardWordEnds :: TextIter -> Int -> IO Bool
textIterForwardWordEnds ti n = liftM toBool $
  {#call unsafe text_iter_forward_word_ends#} ti (fromIntegral n)

-- @method textIterBackwardWordStarts@ Move @ref type TextIter@ backwards by
-- @ref arg n@ word beginnings.
--
-- * Retuns True if the iterator is pointing to a new word start.
--
textIterBackwardWordStarts :: TextIter -> Int -> IO Bool
textIterBackwardWordStarts ti n = liftM toBool $
  {#call unsafe text_iter_backward_word_starts#} ti (fromIntegral n)

-- @method textIterForwardWordEnd@ Move @ref type TextIter@ forwards to the
-- next word end.
--
-- * Retuns True if the iterator has moved to a new word end.
--
textIterForwardWordEnd :: TextIter -> IO Bool
textIterForwardWordEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_word_end#} ti

-- @method textIterBackwardWordStart@ Move @ref type TextIter@ backwards to
-- the next word beginning.
--
-- * Retuns True if the iterator has moved to a new word beginning.
--
textIterBackwardWordStart :: TextIter -> IO Bool
textIterBackwardWordStart ti = liftM toBool $
  {#call unsafe text_iter_backward_word_start#} ti

-- @method textIterForwardCursorPosition@ Move @ref type TextIter@ forwards to
-- the next cursor position.
--
-- * Some characters are composed of two Unicode codes. This function ensures
--   that @ref type TextIter@ does not point inbetween such double characters.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterForwardCursorPosition :: TextIter -> IO Bool
textIterForwardCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_forward_cursor_position#} ti

-- @method textIterBackwardCursorPosition@ Move @ref type TextIter@ backwards
-- to the next cursor position.
--
-- * Some characters are composed of two Unicode codes. This function ensures
--   that @ref type TextIter@ does not point inbetween such double characters.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterBackwardCursorPosition :: TextIter -> IO Bool
textIterBackwardCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_backward_cursor_position#} ti

-- @method textIterForwardCursorPositions@ Move @ref type TextIter@ forwards
-- by @ref arg n@ cursor positions.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterForwardCursorPositions :: TextIter -> Int -> IO Bool
textIterForwardCursorPositions ti n = liftM toBool $
  {#call unsafe text_iter_forward_cursor_positions#} ti (fromIntegral n)

-- @method textIterBackwardCursorPositions@ Move @ref type TextIter@ backwards
-- by @ref arg n@ cursor positions.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterBackwardCursorPositions :: TextIter -> Int -> IO Bool
textIterBackwardCursorPositions ti n = liftM toBool $
  {#call unsafe text_iter_backward_cursor_positions#} ti (fromIntegral n)

-- @method textIterForwardSentenceEnds@ Move @ref type TextIter@ forwards by
-- @ref arg n@ sentence ends.
--
-- * Retuns True if the iterator is pointing to a new sentence end.
--
textIterForwardSentenceEnds :: TextIter -> Int -> IO Bool
textIterForwardSentenceEnds ti n = liftM toBool $
  {#call unsafe text_iter_forward_sentence_ends#} ti (fromIntegral n)

-- @method textIterBackwardSentenceStarts@ Move @ref type TextIter@ backwards
-- by @ref arg n@ sentence beginnings.
--
-- * Retuns True if the iterator is pointing to a new sentence start.
--
textIterBackwardSentenceStarts :: TextIter -> Int -> IO Bool
textIterBackwardSentenceStarts ti n = liftM toBool $
  {#call unsafe text_iter_backward_sentence_starts#} ti (fromIntegral n)

-- @method textIterForwardSentenceEnd@ Move @ref type TextIter@ forwards to
-- the next sentence end.
--
-- * Retuns True if the iterator has moved to a new sentence end.
--
textIterForwardSentenceEnd :: TextIter -> IO Bool
textIterForwardSentenceEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_sentence_end#} ti

-- @method textIterBackwardSentenceStart@ Move @ref type TextIter@ backwards
-- to the next sentence beginning.
--
-- * Retuns True if the iterator has moved to a new sentence beginning.
--
textIterBackwardSentenceStart :: TextIter -> IO Bool
textIterBackwardSentenceStart ti = liftM toBool $
  {#call unsafe text_iter_backward_sentence_start#} ti

-- @method textIterSetOffset@ Set @ref type TextIter@ to an offset within the
-- buffer.
--
textIterSetOffset :: TextIter -> Int -> IO ()
textIterSetOffset ti n =
  {#call unsafe text_iter_set_offset#} ti (fromIntegral n)

-- @method textIterSetLine@ Set @ref type TextIter@ to a line within the
-- buffer.
--
textIterSetLine :: TextIter -> Int -> IO ()
textIterSetLine ti n =
  {#call unsafe text_iter_set_line#} ti (fromIntegral n)

-- @method textIterSetLineOffset@ Set @ref type TextIter@ to an offset within
-- the line.
--
textIterSetLineOffset :: TextIter -> Int -> IO ()
textIterSetLineOffset ti n =
  {#call unsafe text_iter_set_line_offset#} ti (fromIntegral n)

-- @method textIterSetVisibleLineOffset@ Set @ref type TextIter@ to an visible
-- character within the line.
--
textIterSetVisibleLineOffset :: TextIter -> Int -> IO ()
textIterSetVisibleLineOffset ti n =
  {#call unsafe text_iter_set_visible_line_offset#} ti (fromIntegral n)

-- @method textIterForwardToEnd@ Moves @ref type TextIter@ to the end of the
-- buffer.
--
textIterForwardToEnd :: TextIter -> IO ()
textIterForwardToEnd ti = {#call unsafe text_iter_forward_to_end#} ti

-- @method textIterForwardToLineEnd@ Moves @ref type TextIter@ to the end of
-- the line.
--
-- * Returns True if @ref type TextIter@ moved to a new location which is not
--   the buffer end iterator.
--
textIterForwardToLineEnd :: TextIter -> IO Bool
textIterForwardToLineEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_to_line_end#} ti

-- @method textIterForwardToTagToggle@ Moves @ref type TextIter@ forward to
-- the next change of a @ref type TextTag@.
--
-- * If Nothing is supplied, any @ref type TextTag@ will be matched.
--
-- * Returns True if there was a tag toggle after @ref type TextIter@.
--
textIterForwardToTagToggle :: TextIter -> Maybe TextTag -> IO Bool
textIterForwardToTagToggle ti tt = liftM toBool $
  {#call unsafe text_iter_forward_to_tag_toggle#} ti
    (fromMaybe (mkTextTag nullForeignPtr) tt)

-- @method textIterBackwardToTagToggle@ Moves @ref type TextIter@ backward to
-- the next change of a @ref type TextTag@.
--
-- * If Nothing is supplied, any @ref type TextTag@ will be matched.
--
-- * Returns True if there was a tag toggle before @ref type TextIter@.
--
textIterBackwardToTagToggle :: TextIter -> Maybe TextTag -> IO Bool
textIterBackwardToTagToggle ti tt = liftM toBool $
  {#call unsafe text_iter_backward_to_tag_toggle#} ti
    (fromMaybe (mkTextTag nullForeignPtr) tt)

-- Setup a callback for a predicate function.
--
type TextCharPredicateCB = Char -> Bool

{#pointer TextCharPredicate#}

foreign export dynamic mkTextCharPredicate ::
  ({#type gunichar#} -> Ptr () -> {#type gboolean#}) -> IO TextCharPredicate

-- @method textIterForwardFindChar@ Move @ref type TextIter@ forward until a
-- predicate function returns True.
--
-- * If @ref arg pred@ returns True before @ref arg limit@ is reached, the
--   search is stopped and the return value is True.
--
-- * If @ref arg limit@ is Nothing, the search stops at the end of the buffer.
--
textIterForwardFindChar :: TextIter -> (Char -> Bool) -> Maybe TextIter ->
                           IO Bool
textIterForwardFindChar ti pred limit = do
  fPtr <- mkTextCharPredicate (\c _ -> fromBool $ pred (chr (fromIntegral c)))
  res <- liftM toBool $ {#call text_iter_forward_find_char#}
    ti fPtr nullPtr (fromMaybe (TextIter nullForeignPtr) limit)
  freeHaskellFunPtr fPtr
  return res

-- @method textIterBackwardFindChar@ Move @ref type TextIter@ backward until a
-- predicate function returns True.
--
-- * If @ref arg pred@ returns True before @ref arg limit@ is reached, the
--   search is stopped and the return value is True.
--
-- * If @ref arg limit@ is Nothing, the search stops at the end of the buffer.
--
textIterBackwardFindChar :: TextIter -> (Char -> Bool) -> Maybe TextIter ->
                            IO Bool
textIterBackwardFindChar ti pred limit = do
  fPtr <- mkTextCharPredicate (\c _ -> fromBool $ pred (chr (fromIntegral c)))
  res <- liftM toBool $ {#call text_iter_backward_find_char#}
    ti fPtr nullPtr (fromMaybe (TextIter nullForeignPtr) limit)
  freeHaskellFunPtr fPtr
  return res

-- @method textIterForwardSearch@ Search forward for a specific string.
--
-- * If specified, the last character which is tested against that start of
--   the search pattern will be @ref arg limit@.
--
-- * @ref type TextSearchFlags@ may be empty.
--
-- * Returns the start and end position of the string found.
--
textIterForwardSearch :: TextIter -> String -> [TextSearchFlags] ->
                         Maybe TextIter -> IO (Maybe (TextIter, TextIter))
textIterForwardSearch ti str flags limit = do
  start  <- makeEmptyTextIter
  end <- makeEmptyTextIter
  found <- liftM toBool $ withCString str $ \cStr ->
    {#call unsafe text_iter_forward_search#} ti cStr
    ((fromIntegral.fromFlags) flags) start end
    (fromMaybe (TextIter nullForeignPtr) limit)
  return $ if found then Just (start,end) else Nothing

-- @method textIterBackwardSearch@ Search backward for a specific string.
--
-- * If specified, the last character which is tested against that start of
--   the search pattern will be @ref arg limit@.
--
-- * @ref type TextSearchFlags@ my be empty.
--
-- * Returns the start and end position of the string found.
--
textIterBackwardSearch :: TextIter -> String -> [TextSearchFlags] ->
                          Maybe TextIter -> IO (Maybe (TextIter, TextIter))
textIterBackwardSearch ti str flags limit = do
  start  <- makeEmptyTextIter
  end <- makeEmptyTextIter
  found <- liftM toBool $ withCString str $ \cStr ->
    {#call unsafe text_iter_backward_search#} ti cStr
    ((fromIntegral.fromFlags) flags) start end
    (fromMaybe (TextIter nullForeignPtr) limit)
  return $ if found then Just (start,end) else Nothing

-- @method textIterEqual@ Compare two @ref type TextIter@ for equality.
--
-- * @ref type TextIter@ could be in class Eq and Ord if there is a guarantee
--   that each iterator is copied before it is modified in place. This is done
--   the next abstraction layer.
--
textIterEqual :: TextIter -> TextIter -> IO Bool
textIterEqual ti2 ti1 = liftM toBool $ {#call unsafe text_iter_equal#} ti1 ti2

-- @method textIterCompare@ Compare two @ref type TextIter@.
--
-- * @ref type TextIter@ could be in class Eq and Ord if there is a guarantee
--   that each iterator is copied before it is modified in place. This could
--   be done the next abstraction layer.
--
textIterCompare :: TextIter -> TextIter -> IO Ordering
textIterCompare ti2 ti1 = do
  res <- {#call unsafe text_iter_compare#} ti1 ti2
  return $ case res of
    (-1)   -> LT
    0	   -> EQ
    1	   -> GT

-- -*-haskell-*-
--  GIMP Toolkit (GTK) @entry TextIter abstract datatype@
--
--  Author : Axel Simon
--
--  Created: 23 February 2002
--
--  Version $Revision: 1.2 $ from $Date: 2002/05/24 09:43:25 $
--
--  This file 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 2 of the License, or
--  (at your option) any later version.
--
--  This file 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.
--
-- @description@ --------------------------------------------------------------
--
--   * An iterator is an abstract datatype representing a pointer into a
--     @TextBuffer.
--
-- @documentation@ ------------------------------------------------------------
--
-- * The following functions do not make sense due to Haskell's wide character
--   representation of Unicode:
--     gtk_text_iter_get_line_index
--     gtk_text_iter_get_visible_line_index
--     gtk_text_iter_get_bytes_in_line
--     gtk_text_iter_set_line_index
--     gtk_text_iter_set_visible_line_index
--
-- * The functions gtk_text_iter_in_range and gtk_text_iter_order are not bound
--   because they are only convenience functions which can replaced by calls
--   to textIterCompare.
--
-- * All offsets are counted from 0.
--
-- @todo@ ---------------------------------------------------------------------
--
-- * Bind the following function when GSList is bound:
--     gtk_text_iter_get_marks
--     gtk_text_iter_get_toggled_tags
--     gtk_text_iter_get_tags
--
-- * Bind the following functions when we are sure about anchors
--   (see @TextBuffer):
--     gtk_text_iter_get_anchor
--
-- * Bind TextAttribute functions when I am clear how to model them.
--     gtk_text_iter_get_attribute
--
-- * Forward exceptions in the two callback functions.
--
module TextIter(
  TextIter(TextIter),
  mkTextIter,
  makeEmptyTextIter,	-- for internal use only
  textIterGetBuffer,
  textIterCopy,
  textIterGetOffset,
  textIterGetLine,
  textIterGetLineOffset,
  textIterGetVisibleLineOffset,
  textIterGetChar,
  textIterGetSlice,
  textIterGetText,
  textIterGetVisibleSlice,
  textIterGetVisibleText,
  textIterGetPixbuf,
  textIterBeginsTag,
  textIterEndsTag,
  textIterTogglesTag,
  textIterHasTag,
  textIterEditable,
  textIterCanInsert,
  textIterStartsWord,
  textIterEndsWord,
  textIterInsideWord,
  textIterStartsLine,
  textIterEndsLine,
  textIterStartsSentence,
  textIterEndsSentence,
  textIterInsideSentence,
  textIterIsCursorPosition,
  textIterGetCharsInLine,
  textIterIsEnd,
  textIterIsStart,
  textIterForwardChar,
  textIterBackwardChar,
  textIterForwardChars,
  textIterBackwardChars,
  textIterForwardLine,
  textIterBackwardLine,
  textIterForwardLines,
  textIterBackwardLines,
  textIterForwardWordEnds,
  textIterBackwardWordStarts,
  textIterForwardWordEnd,
  textIterBackwardWordStart,
  textIterForwardCursorPosition,
  textIterBackwardCursorPosition,
  textIterForwardCursorPositions,
  textIterBackwardCursorPositions,
  textIterForwardSentenceEnds,
  textIterBackwardSentenceStarts,
  textIterForwardSentenceEnd,
  textIterBackwardSentenceStart,
  textIterSetOffset,
  textIterSetLine,
  textIterSetLineOffset,
  textIterSetVisibleLineOffset,
  textIterForwardToEnd,
  textIterForwardToLineEnd,
  textIterForwardToTagToggle,
  textIterBackwardToTagToggle,
  textIterForwardFindChar,
  textIterBackwardFindChar,
  textIterForwardSearch,
  textIterBackwardSearch,
  textIterEqual,
  textIterCompare
  ) where

import Monad	(liftM)
import Maybe	(fromMaybe)
import Char	(chr)
import Foreign
import CForeign
import GObject	(makeNewGObject)
{#import Hierarchy#}
{#import Signal#}
import Structs  (nullForeignPtr, textIterSize)
import Enums	(TextSearchFlags, Flags(fromFlags))

{# context lib="gtk" prefix="gtk" #}

-- methods

{#pointer *TextIter foreign newtype #}

-- Create a @TextIter from a pointer.
--
mkTextIter :: Ptr TextIter -> IO TextIter
mkTextIter iterPtr = liftM TextIter $
  newForeignPtr iterPtr (textIterFree iterPtr)

-- Allocate memory to be filled with a @TextIter.
--
makeEmptyTextIter :: IO TextIter
makeEmptyTextIter = do
  iterPtr <- mallocBytes textIterSize
  liftM TextIter $ newForeignPtr iterPtr (textIterFree iterPtr)

-- Free a @TextIter pointer.
--
foreign import ccall "gtk_text_iter_free" unsafe
  textIterFree :: Ptr TextIter -> IO ()

-- @method textIterGetBuffer@ Return the @ref type TextBuffer@ this iterator
-- is associated with.
--
textIterGetBuffer :: TextIter -> IO TextBuffer
textIterGetBuffer ti = makeNewGObject mkTextBuffer $
  {#call unsafe text_iter_get_buffer#} ti

-- @method textIterCopy@ Copy the iterator.
--
textIterCopy :: TextIter -> IO TextIter
textIterCopy ti = do
  iterPtr <- {#call unsafe text_iter_copy#} ti
  liftM TextIter $ newForeignPtr iterPtr (textIterFree iterPtr)

-- @method textIterGetOffset@ Extract the offset relative to the beginning of
-- the buffer.
--
textIterGetOffset :: TextIter -> IO Int
textIterGetOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_offset#} ti

-- @method textIterGetLine@ Extract the line of the buffer.
--
textIterGetLine :: TextIter -> IO Int
textIterGetLine ti = liftM fromIntegral $
  {#call unsafe text_iter_get_line#} ti

-- @method textIterGetLineOffset@ Extract the offset relative to the beginning
-- of the line.
--
textIterGetLineOffset :: TextIter -> IO Int
textIterGetLineOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_line_offset#} ti

-- @method textIterGetVisibleLineOffset@ Extract the offset relative to the
-- beginning of the line skipping invisible parts of the line.
--
textIterGetVisibleLineOffset :: TextIter -> IO Int
textIterGetVisibleLineOffset ti = liftM fromIntegral $
  {#call unsafe text_iter_get_visible_line_offset#} ti

-- @method textIterGetChar@ Return the character at this iterator.
--
textIterGetChar :: TextIter -> IO (Maybe Char)
textIterGetChar ti = do
  (res::Int) <- liftM fromIntegral $ {#call unsafe text_iter_get_char#} ti
  return $ if res==0 then Nothing else Just (chr res)

-- @method textIterGetSlice@ Return the text in a given range.
--
-- * Pictures (and other objects) are represented by 0xFFFC.
--
textIterGetSlice :: TextIter -> TextIter -> IO String
textIterGetSlice end start = do
  cStr <- {#call text_iter_get_slice#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetText@ Return the text in a given range.
--
-- * Pictures (and other objects) are stripped form the output.
--
textIterGetText :: TextIter -> TextIter -> IO String
textIterGetText end start = do
  cStr <- {#call text_iter_get_text#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetVisibleSlice@ Return the visible text in a given range.
--
-- * Pictures (and other objects) are represented by 0xFFFC.
--
textIterGetVisibleSlice :: TextIter -> TextIter -> IO String
textIterGetVisibleSlice end start = do
  cStr <- {#call text_iter_get_visible_slice#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetVisibleText@ Return the visible text in a given range.
--
-- * Pictures (and other objects) are stripped form the output.
--
textIterGetVisibleText :: TextIter -> TextIter -> IO String
textIterGetVisibleText end start = do
  cStr <- {#call text_iter_get_visible_text#} start end
  str <- peekCString cStr
  {#call unsafe g_free#} (castPtr cStr)
  return str

-- @method textIterGetPixbuf@ Get the @ref arg GdkPixbuf@ under the iterator.
--
textIterGetPixbuf :: TextIter -> IO (Maybe GdkPixbuf)
textIterGetPixbuf it = do
  pbPtr <- {#call unsafe text_iter_get_pixbuf#} it
  if pbPtr==nullPtr then return Nothing else liftM Just $
    makeNewGObject mkGdkPixbuf (return pbPtr)

-- @method textIterBeginsTag@ Query whether a @ref type TextIter@ is at the
-- start of a @ref type TextTag@.
--
textIterBeginsTag :: TextIter -> TextTag -> IO Bool
textIterBeginsTag ti tt = liftM toBool $
  {#call unsafe text_iter_begins_tag#} ti tt

-- @method textIterEndsTag@ Query whether a @ref type TextIter@ is at the end
-- of a @ref type TextTag@.
--
textIterEndsTag :: TextIter -> TextTag -> IO Bool
textIterEndsTag ti tt = liftM toBool $
  {#call unsafe text_iter_ends_tag#} ti tt

-- @method textIterTogglesTag@ Query if the @ref type TextIter@ is at the
-- beginning or the end of a @ref type TextTag@.
--
textIterTogglesTag :: TextIter -> TextTag -> IO Bool
textIterTogglesTag ti tt = liftM toBool $
  {#call unsafe text_iter_toggles_tag#} ti tt

-- @method textIterHasTag@ Check if @ref type TextIter@ is within a range
-- tagged with tag.
--
textIterHasTag :: TextIter -> TextTag -> IO Bool
textIterHasTag ti tt = liftM toBool $
  {#call unsafe text_iter_has_tag#} ti tt

-- @method textIterEditable@ Check if @ref type TextIter@ is within an
-- editable region.
--
-- * If no tags that affect editability are attached to the current position
--   @ref arg def@ will be returned.
--
-- * This function cannot be used to decide whether text can be inserted at
--   @ref type TextIter@. Use the @ref method textIterCanInsert@ function for
--   this purpose.
--
textIterEditable :: TextIter -> Bool -> IO Bool
textIterEditable ti def = liftM toBool $
  {#call unsafe text_iter_editable#} ti (fromBool def)

-- @method textIterCanInsert@ Check if new text can be inserted at
-- @ref type TextIter@.
--
-- * Use @ref method textBufferInsertInteractive@ if you want to insert text
--   depending on the current editable status.
--
textIterCanInsert :: TextIter -> Bool -> IO Bool
textIterCanInsert ti def = liftM toBool $
  {#call unsafe text_iter_can_insert#} ti (fromBool def)

-- @method textIterStartsWord@ Determine if @ref type TextIter@ begins a new
-- natural-language word.
--
textIterStartsWord :: TextIter -> IO Bool
textIterStartsWord ti = liftM toBool $ {#call unsafe text_iter_starts_word#} ti

-- @method textIterEndsWord@ Determine if @ref type TextIter@ ends a new
-- natural-language word.
--
textIterEndsWord :: TextIter -> IO Bool
textIterEndsWord ti = liftM toBool $ {#call unsafe text_iter_ends_word#} ti

-- @method textIterInsideWord@ Determine if @ref type TextIter@ is inside a
-- word.
--
textIterInsideWord :: TextIter -> IO Bool
textIterInsideWord ti = liftM toBool $ {#call unsafe text_iter_inside_word#} ti

-- @method textIterStartsLine@ Determine if @ref type TextIter@ begins a new
-- line.
--
textIterStartsLine :: TextIter -> IO Bool
textIterStartsLine ti = liftM toBool $ {#call unsafe text_iter_starts_line#} ti

-- @method textIterEndsLine@ Determine if @ref type TextIter@ point to the
-- beginning of a line delimiter.
--
-- * Returns False if @ref type TextIter@ points to the \n in a \r\n sequence.
--
textIterEndsLine :: TextIter -> IO Bool
textIterEndsLine ti = liftM toBool $ {#call unsafe text_iter_ends_line#} ti

-- @method textIterStartsSentence@ Determine if @ref type TextIter@ starts a
-- sentence.
--
textIterStartsSentence :: TextIter -> IO Bool
textIterStartsSentence ti = liftM toBool $
  {#call unsafe text_iter_starts_sentence#} ti

-- @method textIterEndsSentence@ Determine if @ref type TextIter@ ends a
-- sentence.
--
textIterEndsSentence :: TextIter -> IO Bool
textIterEndsSentence ti = liftM toBool $
  {#call unsafe text_iter_ends_sentence#} ti

-- @method textIterInsideSentence@ Determine if @ref type TextIter@ is inside
-- a sentence.
--
textIterInsideSentence :: TextIter -> IO Bool
textIterInsideSentence ti = liftM toBool $
  {#call unsafe text_iter_inside_sentence#} ti

-- @method textIterIsCursorPosition@ Determine if @ref type TextIter@ is at a
-- cursor position.
--
textIterIsCursorPosition :: TextIter -> IO Bool
textIterIsCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_is_cursor_position#} ti

-- @method textIterGetCharsInLine@ Return number of characters in this line.
--
-- * The return value includes delimiters.
--
textIterGetCharsInLine :: TextIter -> IO Int
textIterGetCharsInLine ti = liftM fromIntegral $
  {#call unsafe text_iter_get_chars_in_line#} ti

-- @dunno@Get the text attributes at the iterator.
-- * The @ta argument gives the default values if no specific attributes are
--   set at that specific location.
--
-- * The function returns Nothing if the text at the iterator has the same
--   attributes.

-- @method textIterIsEnd@ Determine if @ref type TextIter@ is at the end of
-- the buffer.
--
textIterIsEnd :: TextIter -> IO Bool
textIterIsEnd ti = liftM toBool $
  {#call unsafe text_iter_is_end#} ti

-- @method textIterIsStart@ Determine if @ref type TextIter@ is at the
-- beginning of the buffer.
--
textIterIsStart :: TextIter -> IO Bool
textIterIsStart ti = liftM toBool $
  {#call unsafe text_iter_is_start#} ti

-- @method textIterForwardChar@ Move @ref type TextIter@ forwards.
--
-- * Retuns True if the iterator is pointing to a character.
--
textIterForwardChar :: TextIter -> IO Bool
textIterForwardChar ti = liftM toBool $
  {#call unsafe text_iter_forward_char#} ti

-- @method textIterBackwardChar@ Move @ref type TextIter@ backwards.
--
-- * Retuns True if the movement was possible.
--
textIterBackwardChar :: TextIter -> IO Bool
textIterBackwardChar ti = liftM toBool $
  {#call unsafe text_iter_backward_char#} ti

-- @method textIterForwardChars@ Move @ref type TextIter@ forwards by
-- @ref arg n@ characters.
--
-- * Retuns True if the iterator is pointing to a new character (and False if
--   the iterator points to a picture or has not moved).
--
textIterForwardChars :: TextIter -> Int -> IO Bool
textIterForwardChars ti n = liftM toBool $
  {#call unsafe text_iter_forward_chars#} ti (fromIntegral n)

-- @method textIterBackwardChars@ Move @ref type TextIter@ backwards by
-- @ref arg n@ characters.
--
-- * Retuns True if the iterator is pointing to a new character (and False if
--   the iterator points to a picture or has not moved).
--
textIterBackwardChars :: TextIter -> Int -> IO Bool
textIterBackwardChars ti n = liftM toBool $
  {#call unsafe text_iter_backward_chars#} ti (fromIntegral n)

-- @method textIterForwardLine@ Move @ref type TextIter@ forwards.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the
--   beginning of the buffer.
--
textIterForwardLine :: TextIter -> IO Bool
textIterForwardLine ti = liftM toBool $
  {#call unsafe text_iter_forward_line#} ti

-- @method textIterBackwardLine@ Move @ref type TextIter@ backwards.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the end
--   of the buffer.
--
textIterBackwardLine :: TextIter -> IO Bool
textIterBackwardLine ti = liftM toBool $
  {#call unsafe text_iter_backward_line#} ti

-- @method textIterForwardLines@ Move @ref type TextIter@ forwards by
-- @ref arg n@ lines.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the
--   beginning of the buffer.
--
-- * @ref arg n@ can be negative.
--
textIterForwardLines :: TextIter -> Int -> IO Bool
textIterForwardLines ti n = liftM toBool $
  {#call unsafe text_iter_forward_lines#} ti (fromIntegral n)

-- @method textIterBackwardLines@ Move @ref type TextIter@ backwards by
-- @ref arg n@ lines.
--
-- * Retuns True if the iterator is pointing to a new line (and False if the
--   iterator points to a picture or has not moved).
--
-- * If @ref type TextIter@ is on the first line, it will be moved to the end
--   of the buffer.
--
-- * @ref arg n@ can be negative.
--
textIterBackwardLines :: TextIter -> Int -> IO Bool
textIterBackwardLines ti n = liftM toBool $
  {#call unsafe text_iter_backward_lines#} ti (fromIntegral n)

-- @method textIterForwardWordEnds@ Move @ref type TextIter@ forwards by
-- @ref arg n@ word ends.
--
-- * Retuns True if the iterator is pointing to a new word end.
--
textIterForwardWordEnds :: TextIter -> Int -> IO Bool
textIterForwardWordEnds ti n = liftM toBool $
  {#call unsafe text_iter_forward_word_ends#} ti (fromIntegral n)

-- @method textIterBackwardWordStarts@ Move @ref type TextIter@ backwards by
-- @ref arg n@ word beginnings.
--
-- * Retuns True if the iterator is pointing to a new word start.
--
textIterBackwardWordStarts :: TextIter -> Int -> IO Bool
textIterBackwardWordStarts ti n = liftM toBool $
  {#call unsafe text_iter_backward_word_starts#} ti (fromIntegral n)

-- @method textIterForwardWordEnd@ Move @ref type TextIter@ forwards to the
-- next word end.
--
-- * Retuns True if the iterator has moved to a new word end.
--
textIterForwardWordEnd :: TextIter -> IO Bool
textIterForwardWordEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_word_end#} ti

-- @method textIterBackwardWordStart@ Move @ref type TextIter@ backwards to
-- the next word beginning.
--
-- * Retuns True if the iterator has moved to a new word beginning.
--
textIterBackwardWordStart :: TextIter -> IO Bool
textIterBackwardWordStart ti = liftM toBool $
  {#call unsafe text_iter_backward_word_start#} ti

-- @method textIterForwardCursorPosition@ Move @ref type TextIter@ forwards to
-- the next cursor position.
--
-- * Some characters are composed of two Unicode codes. This function ensures
--   that @ref type TextIter@ does not point inbetween such double characters.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterForwardCursorPosition :: TextIter -> IO Bool
textIterForwardCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_forward_cursor_position#} ti

-- @method textIterBackwardCursorPosition@ Move @ref type TextIter@ backwards
-- to the next cursor position.
--
-- * Some characters are composed of two Unicode codes. This function ensures
--   that @ref type TextIter@ does not point inbetween such double characters.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterBackwardCursorPosition :: TextIter -> IO Bool
textIterBackwardCursorPosition ti = liftM toBool $
  {#call unsafe text_iter_backward_cursor_position#} ti

-- @method textIterForwardCursorPositions@ Move @ref type TextIter@ forwards
-- by @ref arg n@ cursor positions.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterForwardCursorPositions :: TextIter -> Int -> IO Bool
textIterForwardCursorPositions ti n = liftM toBool $
  {#call unsafe text_iter_forward_cursor_positions#} ti (fromIntegral n)

-- @method textIterBackwardCursorPositions@ Move @ref type TextIter@ backwards
-- by @ref arg n@ cursor positions.
--
-- * Returns True if @ref type TextIter@ moved and points to a character (not
--   to an object).
--
textIterBackwardCursorPositions :: TextIter -> Int -> IO Bool
textIterBackwardCursorPositions ti n = liftM toBool $
  {#call unsafe text_iter_backward_cursor_positions#} ti (fromIntegral n)

-- @method textIterForwardSentenceEnds@ Move @ref type TextIter@ forwards by
-- @ref arg n@ sentence ends.
--
-- * Retuns True if the iterator is pointing to a new sentence end.
--
textIterForwardSentenceEnds :: TextIter -> Int -> IO Bool
textIterForwardSentenceEnds ti n = liftM toBool $
  {#call unsafe text_iter_forward_sentence_ends#} ti (fromIntegral n)

-- @method textIterBackwardSentenceStarts@ Move @ref type TextIter@ backwards
-- by @ref arg n@ sentence beginnings.
--
-- * Retuns True if the iterator is pointing to a new sentence start.
--
textIterBackwardSentenceStarts :: TextIter -> Int -> IO Bool
textIterBackwardSentenceStarts ti n = liftM toBool $
  {#call unsafe text_iter_backward_sentence_starts#} ti (fromIntegral n)

-- @method textIterForwardSentenceEnd@ Move @ref type TextIter@ forwards to
-- the next sentence end.
--
-- * Retuns True if the iterator has moved to a new sentence end.
--
textIterForwardSentenceEnd :: TextIter -> IO Bool
textIterForwardSentenceEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_sentence_end#} ti

-- @method textIterBackwardSentenceStart@ Move @ref type TextIter@ backwards
-- to the next sentence beginning.
--
-- * Retuns True if the iterator has moved to a new sentence beginning.
--
textIterBackwardSentenceStart :: TextIter -> IO Bool
textIterBackwardSentenceStart ti = liftM toBool $
  {#call unsafe text_iter_backward_sentence_start#} ti

-- @method textIterSetOffset@ Set @ref type TextIter@ to an offset within the
-- buffer.
--
textIterSetOffset :: TextIter -> Int -> IO ()
textIterSetOffset ti n =
  {#call unsafe text_iter_set_offset#} ti (fromIntegral n)

-- @method textIterSetLine@ Set @ref type TextIter@ to a line within the
-- buffer.
--
textIterSetLine :: TextIter -> Int -> IO ()
textIterSetLine ti n =
  {#call unsafe text_iter_set_line#} ti (fromIntegral n)

-- @method textIterSetLineOffset@ Set @ref type TextIter@ to an offset within
-- the line.
--
textIterSetLineOffset :: TextIter -> Int -> IO ()
textIterSetLineOffset ti n =
  {#call unsafe text_iter_set_line_offset#} ti (fromIntegral n)

-- @method textIterSetVisibleLineOffset@ Set @ref type TextIter@ to an visible
-- character within the line.
--
textIterSetVisibleLineOffset :: TextIter -> Int -> IO ()
textIterSetVisibleLineOffset ti n =
  {#call unsafe text_iter_set_visible_line_offset#} ti (fromIntegral n)

-- @method textIterForwardToEnd@ Moves @ref type TextIter@ to the end of the
-- buffer.
--
textIterForwardToEnd :: TextIter -> IO ()
textIterForwardToEnd ti = {#call unsafe text_iter_forward_to_end#} ti

-- @method textIterForwardToLineEnd@ Moves @ref type TextIter@ to the end of
-- the line.
--
-- * Returns True if @ref type TextIter@ moved to a new location which is not
--   the buffer end iterator.
--
textIterForwardToLineEnd :: TextIter -> IO Bool
textIterForwardToLineEnd ti = liftM toBool $
  {#call unsafe text_iter_forward_to_line_end#} ti

-- @method textIterForwardToTagToggle@ Moves @ref type TextIter@ forward to
-- the next change of a @ref type TextTag@.
--
-- * If Nothing is supplied, any @ref type TextTag@ will be matched.
--
-- * Returns True if there was a tag toggle after @ref type TextIter@.
--
textIterForwardToTagToggle :: TextIter -> Maybe TextTag -> IO Bool
textIterForwardToTagToggle ti tt = liftM toBool $
  {#call unsafe text_iter_forward_to_tag_toggle#} ti
    (fromMaybe (mkTextTag nullForeignPtr) tt)

-- @method textIterBackwardToTagToggle@ Moves @ref type TextIter@ backward to
-- the next change of a @ref type TextTag@.
--
-- * If Nothing is supplied, any @ref type TextTag@ will be matched.
--
-- * Returns True if there was a tag toggle before @ref type TextIter@.
--
textIterBackwardToTagToggle :: TextIter -> Maybe TextTag -> IO Bool
textIterBackwardToTagToggle ti tt = liftM toBool $
  {#call unsafe text_iter_backward_to_tag_toggle#} ti
    (fromMaybe (mkTextTag nullForeignPtr) tt)

-- Setup a callback for a predicate function.
--
type TextCharPredicateCB = Char -> Bool

{#pointer TextCharPredicate#}

foreign export dynamic mkTextCharPredicate ::
  ({#type gunichar#} -> Ptr () -> {#type gboolean#}) -> IO TextCharPredicate

-- @method textIterForwardFindChar@ Move @ref type TextIter@ forward until a
-- predicate function returns True.
--
-- * If @ref arg pred@ returns True before @ref arg limit@ is reached, the
--   search is stopped and the return value is True.
--
-- * If @ref arg limit@ is Nothing, the search stops at the end of the buffer.
--
textIterForwardFindChar :: TextIter -> (Char -> Bool) -> Maybe TextIter ->
                           IO Bool
textIterForwardFindChar ti pred limit = do
  fPtr <- mkTextCharPredicate (\c _ -> fromBool $ pred (chr (fromIntegral c)))
  res <- liftM toBool $ {#call text_iter_forward_find_char#}
    ti fPtr nullPtr (fromMaybe (TextIter nullForeignPtr) limit)
  freeHaskellFunPtr fPtr
  return res

-- @method textIterBackwardFindChar@ Move @ref type TextIter@ backward until a
-- predicate function returns True.
--
-- * If @ref arg pred@ returns True before @ref arg limit@ is reached, the
--   search is stopped and the return value is True.
--
-- * If @ref arg limit@ is Nothing, the search stops at the end of the buffer.
--
textIterBackwardFindChar :: TextIter -> (Char -> Bool) -> Maybe TextIter ->
                            IO Bool
textIterBackwardFindChar ti pred limit = do
  fPtr <- mkTextCharPredicate (\c _ -> fromBool $ pred (chr (fromIntegral c)))
  res <- liftM toBool $ {#call text_iter_backward_find_char#}
    ti fPtr nullPtr (fromMaybe (TextIter nullForeignPtr) limit)
  freeHaskellFunPtr fPtr
  return res

-- @method textIterForwardSearch@ Search forward for a specific string.
--
-- * If specified, the last character which is tested against that start of
--   the search pattern will be @ref arg limit@.
--
-- * @ref type TextSearchFlags@ may be empty.
--
-- * Returns the start and end position of the string found.
--
textIterForwardSearch :: TextIter -> String -> [TextSearchFlags] ->
                         Maybe TextIter -> IO (Maybe (TextIter, TextIter))
textIterForwardSearch ti str flags limit = do
  start  <- makeEmptyTextIter
  end <- makeEmptyTextIter
  found <- liftM toBool $ withCString str $ \cStr ->
    {#call unsafe text_iter_forward_search#} ti cStr
    ((fromIntegral.fromFlags) flags) start end
    (fromMaybe (TextIter nullForeignPtr) limit)
  return $ if found then Just (start,end) else Nothing

-- @method textIterBackwardSearch@ Search backward for a specific string.
--
-- * If specified, the last character which is tested against that start of
--   the search pattern will be @ref arg limit@.
--
-- * @ref type TextSearchFlags@ my be empty.
--
-- * Returns the start and end position of the string found.
--
textIterBackwardSearch :: TextIter -> String -> [TextSearchFlags] ->
                          Maybe TextIter -> IO (Maybe (TextIter, TextIter))
textIterBackwardSearch ti str flags limit = do
  start  <- makeEmptyTextIter
  end <- makeEmptyTextIter
  found <- liftM toBool $ withCString str $ \cStr ->
    {#call unsafe text_iter_backward_search#} ti cStr
    ((fromIntegral.fromFlags) flags) start end
    (fromMaybe (TextIter nullForeignPtr) limit)
  return $ if found then Just (start,end) else Nothing

-- @method textIterEqual@ Compare two @ref type TextIter@ for equality.
--
-- * @ref type TextIter@ could be in class Eq and Ord if there is a guarantee
--   that each iterator is copied before it is modified in place. This is done
--   the next abstraction layer.
--
textIterEqual :: TextIter -> TextIter -> IO Bool
textIterEqual ti2 ti1 = liftM toBool $ {#call unsafe text_iter_equal#} ti1 ti2

-- @method textIterCompare@ Compare two @ref type TextIter@.
--
-- * @ref type TextIter@ could be in class Eq and Ord if there is a guarantee
--   that each iterator is copied before it is modified in place. This could
--   be done the next abstraction layer.
--
textIterCompare :: TextIter -> TextIter -> IO Ordering
textIterCompare ti2 ti1 = do
  res <- {#call unsafe text_iter_compare#} ti1 ti2
  return $ case res of
    (-1)   -> LT
    0	   -> EQ
    1	   -> GT


Fix crash bug of treeViewColumnGetWidget.

When you first call treeViewColumnGetWidget will got error "main: user error (makeNewObject: object is NULL)"
Details see : http://library.gnome.org/devel/gtk/stable/GtkTreeViewColumn.html#gtk-tree-view-column-get-widget

{-# LANGUAGE CPP #-}
-- -*-haskell-*-
--  GIMP Toolkit (GTK) TreeViewColumn TreeView
--
--  Author : Axel Simon
--
--  Created: 9 May 2001
--
--  Copyright (C) 2001-2005 Axel Simon
--
--  This library is free software; you can redistribute it and/or
--  modify it under the terms of the GNU Lesser General Public
--  License as published by the Free Software Foundation; either
--  version 2.1 of the License, or (at your option) any later version.
--
--  This library 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
--  Lesser General Public License for more details.
--
-- |
-- Maintainer  : gtk2hs-users@lists.sourceforge.net
-- Stability   : provisional
-- Portability : portable (depends on GHC)
--
-- A visible column in a 'TreeView' widget
--
module Graphics.UI.Gtk.ModelView.TreeViewColumn (
-- * Detail
--
-- | The 'TreeViewColumn' object represents a visible column in a 'TreeView'
-- widget. It allows to set properties of the column header, and functions as a
-- holding pen for the cell renderers which determine how the data in the
-- column is displayed.
--

-- * Class Hierarchy
-- |
-- @
-- |  'GObject'
-- |   +----'Object'
-- |         +----TreeViewColumn
-- @

-- * Types
  TreeViewColumn,
  TreeViewColumnClass,
  castToTreeViewColumn, gTypeTreeViewColumn,
  toTreeViewColumn,

-- * Constructors
  treeViewColumnNew,

-- * Methods
  treeViewColumnPackStart,
  treeViewColumnPackEnd,
  treeViewColumnClear,
  treeViewColumnGetCellRenderers,
  treeViewColumnSetSpacing,
  treeViewColumnGetSpacing,
  treeViewColumnSetVisible,
  treeViewColumnGetVisible,
  treeViewColumnSetResizable,
  treeViewColumnGetResizable,
  TreeViewColumnSizing(..),
  treeViewColumnSetSizing,
  treeViewColumnGetSizing,
  treeViewColumnGetWidth,
  treeViewColumnSetFixedWidth,
  treeViewColumnGetFixedWidth,
  treeViewColumnSetMinWidth,
  treeViewColumnGetMinWidth,
  treeViewColumnSetMaxWidth,
  treeViewColumnGetMaxWidth,
  treeViewColumnClicked,
  treeViewColumnSetTitle,
  treeViewColumnGetTitle,
  treeViewColumnSetClickable,
  treeViewColumnGetClickable,
  treeViewColumnSetWidget,
  treeViewColumnGetWidget,
  treeViewColumnSetAlignment,
  treeViewColumnGetAlignment,
  treeViewColumnSetReorderable,
  treeViewColumnGetReorderable,
  treeViewColumnSetSortColumnId,
  treeViewColumnGetSortColumnId,
  treeViewColumnSetSortIndicator,
  treeViewColumnGetSortIndicator,
  treeViewColumnSetSortOrder,
  treeViewColumnGetSortOrder,
  SortType(..),
#if GTK_CHECK_VERSION(2,4,0)
  treeViewColumnSetExpand,
  treeViewColumnGetExpand,
#endif
  treeViewColumnCellIsVisible,
#if GTK_CHECK_VERSION(2,2,0)
  treeViewColumnFocusCell,
#if GTK_CHECK_VERSION(2,8,0)
  treeViewColumnQueueResize,
#endif
#endif

-- * Attributes
  treeViewColumnVisible,
  treeViewColumnResizable,
  treeViewColumnWidth,
  treeViewColumnSpacing,
  treeViewColumnSizing,
  treeViewColumnFixedWidth,
  treeViewColumnMinWidth,
  treeViewColumnMaxWidth,
  treeViewColumnTitle,
  treeViewColumnExpand,
  treeViewColumnClickable,
  treeViewColumnWidget,
  treeViewColumnAlignment,
  treeViewColumnReorderable,
  treeViewColumnSortIndicator,
  treeViewColumnSortOrder,
  treeViewColumnSortColumnId,

-- * Signals
  onColClicked,
  afterColClicked
  ) where

import Control.Monad	(liftM)

import System.Glib.FFI
import System.Glib.UTFString
{#import System.Glib.GList#}			(fromGList)
import System.Glib.Attributes
import System.Glib.Properties
import Graphics.UI.Gtk.Abstract.Object		(makeNewObject)
{#import Graphics.UI.Gtk.Types#}
{#import Graphics.UI.Gtk.Signals#}
import Graphics.UI.Gtk.General.Enums		(TreeViewColumnSizing(..),
						 SortType(..))
import Graphics.UI.Gtk.General.Structs          (SortColumnId)
{#import Graphics.UI.Gtk.ModelView.TreeModel#}	()

{# context lib="gtk" prefix="gtk" #}

--------------------
-- Constructors

-- | Generate a new TreeViewColumn widget.
--
treeViewColumnNew :: IO TreeViewColumn
treeViewColumnNew  = makeNewObject mkTreeViewColumn
  {# call tree_view_column_new #}

--------------------
-- Methods

-- | Add a cell renderer at the beginning of a column.
--
-- * Excess space is divided equally among all renderers which have
--   @expand@ set to True.
--
treeViewColumnPackStart :: CellRendererClass cell => TreeViewColumn
 -> cell
 -> Bool
 -> IO ()
treeViewColumnPackStart self cell expand =
  {# call unsafe tree_view_column_pack_start #}
    self
    (toCellRenderer cell)
    (fromBool expand)

-- | Add a cell renderer at the end of a column.
--
-- * Excess space is divided equally among all renderers which have
--   @expand@ set to True.
--
treeViewColumnPackEnd :: CellRendererClass cell => TreeViewColumn
 -> cell
 -> Bool
 -> IO ()
treeViewColumnPackEnd self cell expand =
  {# call unsafe tree_view_column_pack_end #}
    self
    (toCellRenderer cell)
    (fromBool expand)

-- | Remove the associations of attributes to a store for all 'CellRenderer's.
--
treeViewColumnClear :: TreeViewColumn -> IO ()
treeViewColumnClear self =
  {# call tree_view_column_clear #}
    self

-- | Retrieve all 'CellRenderer's that are contained in this column.
--
treeViewColumnGetCellRenderers :: TreeViewColumn -> IO [CellRenderer]
treeViewColumnGetCellRenderers self =
  {# call unsafe tree_view_column_get_cell_renderers #}
    self
  >>= fromGList
  >>= mapM (makeNewObject mkCellRenderer . return)

-- | Set the number of pixels between two cell renderers.
--
treeViewColumnSetSpacing :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetSpacing self spacing =
  {# call tree_view_column_set_spacing #}
    self
    (fromIntegral spacing)

-- | Get the number of pixels between two cell renderers.
--
treeViewColumnGetSpacing :: TreeViewColumn -> IO Int
treeViewColumnGetSpacing self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_spacing #}
    self

-- | Set the visibility of a given column.
--
treeViewColumnSetVisible :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetVisible self visible =
  {# call tree_view_column_set_visible #}
    self
    (fromBool visible)

-- | Get the visibility of a given column.
--
treeViewColumnGetVisible :: TreeViewColumn -> IO Bool
treeViewColumnGetVisible self =
  liftM toBool $
  {# call unsafe tree_view_column_get_visible #}
    self

-- | Set if a given column is resizable by the user.
--
treeViewColumnSetResizable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetResizable self resizable =
  {# call tree_view_column_set_resizable #}
    self
    (fromBool resizable)

-- | Get if a given column is resizable by the user.
--
treeViewColumnGetResizable :: TreeViewColumn -> IO Bool
treeViewColumnGetResizable self =
  liftM toBool $
  {# call unsafe tree_view_column_get_resizable #}
    self

-- | Set wether the column can be resized.
--
treeViewColumnSetSizing :: TreeViewColumn
 -> TreeViewColumnSizing
 -> IO ()
treeViewColumnSetSizing self type_ =
  {# call tree_view_column_set_sizing #}
    self
    ((fromIntegral . fromEnum) type_)

-- | Return the resizing type of the column.
--
treeViewColumnGetSizing :: TreeViewColumn
 -> IO TreeViewColumnSizing
treeViewColumnGetSizing self =
  liftM (toEnum . fromIntegral) $
  {# call unsafe tree_view_column_get_sizing #}
    self

-- | Query the current width of the column.
--
treeViewColumnGetWidth :: TreeViewColumn -> IO Int
treeViewColumnGetWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_width #}
    self

-- | Set the width of the column.
--
-- * This is meaningful only if the sizing type is 'TreeViewColumnFixed'.
--
treeViewColumnSetFixedWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetFixedWidth self fixedWidth =
  {# call tree_view_column_set_fixed_width #}
    self
    (fromIntegral fixedWidth)

-- | Gets the fixed width of the column.
--
-- * This is meaningful only if the sizing type is 'TreeViewColumnFixed'.
--
-- * This value is only meaning may not be the actual width of the column on the
-- screen, just what is requested.
--
treeViewColumnGetFixedWidth :: TreeViewColumn -> IO Int
treeViewColumnGetFixedWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_fixed_width #}
    self

-- | Set minimum width of the column.
--
treeViewColumnSetMinWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetMinWidth self minWidth =
  {# call tree_view_column_set_min_width #}
    self
    (fromIntegral minWidth)

-- | Get the minimum width of a column. Returns -1 if this width was not set.
--
treeViewColumnGetMinWidth :: TreeViewColumn -> IO Int
treeViewColumnGetMinWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_min_width #}
    self

-- | Set maximum width of the column.
--
treeViewColumnSetMaxWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetMaxWidth self maxWidth =
  {# call tree_view_column_set_max_width #}
    self
    (fromIntegral maxWidth)

-- | Get the maximum width of a column. Returns -1 if this width was not set.
--
treeViewColumnGetMaxWidth :: TreeViewColumn -> IO Int
treeViewColumnGetMaxWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_max_width #}
    self

-- | Emit the @clicked@ signal on the column.
--
treeViewColumnClicked :: TreeViewColumn -> IO ()
treeViewColumnClicked self =
  {# call tree_view_column_clicked #}
    self

-- | Set the widget's title if a custom widget has not been set.
--
treeViewColumnSetTitle :: TreeViewColumn -> String -> IO ()
treeViewColumnSetTitle self title =
  withUTFString title $ \titlePtr ->
  {# call tree_view_column_set_title #}
    self
    titlePtr

-- | Get the widget's title.
--
treeViewColumnGetTitle :: TreeViewColumn -> IO (Maybe String)
treeViewColumnGetTitle self =
  {# call unsafe tree_view_column_get_title #}
    self
  >>= maybePeek peekUTFString

-- | Set if the column should be sensitive to mouse clicks.
--
treeViewColumnSetClickable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetClickable self clickable =
  {# call tree_view_column_set_clickable #}
    self
    (fromBool clickable)

-- | Returns True if the user can click on the header for the column.
--
treeViewColumnGetClickable :: TreeViewColumn -> IO Bool
treeViewColumnGetClickable self =
  liftM toBool $
  {# call tree_view_column_get_clickable #}
    self

-- | Set the column's title to this widget.
--
treeViewColumnSetWidget :: WidgetClass widget => TreeViewColumn
 -> Maybe widget
 -> IO ()
treeViewColumnSetWidget self widget =
  {# call tree_view_column_set_widget #}
    self
    (maybe (Widget nullForeignPtr) toWidget widget)

-- | Retrieve the widget responsible for
-- showing the column title. In case only a text title was set this will be a
-- 'Alignment' widget with a 'Label' inside.
--
treeViewColumnGetWidget :: TreeViewColumn
 -> IO (Maybe Widget) -- ^ returns the 'Widget' in the column header, or 'Nothing'
treeViewColumnGetWidget self = do
  widgetPtr <- {# call unsafe tree_view_column_get_widget #} self
  if widgetPtr == nullPtr
     then return Nothing
     else liftM Just $ makeNewObject mkWidget (return widgetPtr)

-- | Sets the alignment of the title or custom widget inside the column
-- header. The alignment determines its location inside the button -- 0.0 for
-- left, 0.5 for center, 1.0 for right.
--
treeViewColumnSetAlignment :: TreeViewColumn
 -> Float          -- ^ @xalign@ - The alignment, which is between [0.0 and
                   -- 1.0] inclusive.
 -> IO ()
treeViewColumnSetAlignment self xalign =
  {# call tree_view_column_set_alignment #}
    self
    (realToFrac xalign)

-- | Returns the current x alignment of the tree column. This value can range
-- between 0.0 and 1.0.
--
treeViewColumnGetAlignment :: TreeViewColumn -> IO Float
treeViewColumnGetAlignment self =
  liftM realToFrac $
  {# call unsafe tree_view_column_get_alignment #}
    self

-- | Set if the column can be reordered by the end user dragging the header.
--
treeViewColumnSetReorderable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetReorderable self reorderable =
  {# call tree_view_column_set_reorderable #}
    self
    (fromBool reorderable)

-- | Returns whether the column can be reordered by the user.
--
treeViewColumnGetReorderable :: TreeViewColumn -> IO Bool
treeViewColumnGetReorderable self =
  liftM toBool $
  {# call unsafe tree_view_column_get_reorderable #}
    self

-- | Set the column by which to sort.
--
-- * Sets the logical @columnId@ that this column sorts on when
--   this column is selected for sorting. The selected column's header
--   will be clickable after this call. Logical refers to the
--   'Graphics.UI.Gtk.ModelView.TreeSortable.SortColumnId' for which
--   a comparison function was set.
--
treeViewColumnSetSortColumnId :: TreeViewColumn -> SortColumnId -> IO ()
treeViewColumnSetSortColumnId self sortColumnId =
  {# call tree_view_column_set_sort_column_id #}
    self
    (fromIntegral sortColumnId)

-- | Get the column by which to sort.
--
-- * Retrieves the logical @columnId@ that the model sorts on when this column
--   is selected for sorting.
--
-- * Returns
--   'Graphics.UI.Gtk.ModelView.TreeSortable.treeSortableDefaultSortColumnId'
--   if this tree view column has no
--   'Graphics.UI.Gtk.ModelView.TreeSortable.SortColumnId' associated with it.
--
treeViewColumnGetSortColumnId :: TreeViewColumn -> IO SortColumnId
treeViewColumnGetSortColumnId self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_sort_column_id #}
    self

-- | Set if a given column has sorting arrows in its heading.
--
treeViewColumnSetSortIndicator :: TreeViewColumn
 -> Bool -> IO ()
treeViewColumnSetSortIndicator self setting =
  {# call tree_view_column_set_sort_indicator #}
    self
    (fromBool setting)

-- | Query if a given column has sorting arrows in its heading.
--
treeViewColumnGetSortIndicator :: TreeViewColumn -> IO Bool
treeViewColumnGetSortIndicator self =
  liftM toBool $
  {# call unsafe tree_view_column_get_sort_indicator #}
    self

-- | Set if a given column is sorted in ascending or descending order.
--
-- * In order for sorting to work, it is necessary to either use automatic
--   sorting via 'treeViewColumnSetSortColumnId' or to use a
--   user defined sorting on the elements in a 'TreeModel'.
--
treeViewColumnSetSortOrder :: TreeViewColumn
 -> SortType -> IO ()
treeViewColumnSetSortOrder self order =
  {# call tree_view_column_set_sort_order #}
    self
    ((fromIntegral . fromEnum) order)

-- | Query if a given column is sorted in ascending or descending order.
--
treeViewColumnGetSortOrder :: TreeViewColumn -> IO SortType
treeViewColumnGetSortOrder self =
  liftM (toEnum . fromIntegral) $
  {# call unsafe tree_view_column_get_sort_order #}
    self

#if GTK_CHECK_VERSION(2,4,0)
-- %hash c:7808 d:942b
-- | Sets the column to take available extra space. This space is shared
-- equally amongst all columns that have the expand set to @True@. If no column
-- has this option set, then the last column gets all extra space. By default,
-- every column is created with this @False@.
--
-- * Available since Gtk+ version 2.4
--
treeViewColumnSetExpand :: TreeViewColumn
 -> Bool -- ^ @expand@ - @True@ if the column should take available extra
         -- space, @False@ if not
 -> IO ()
treeViewColumnSetExpand self expand =
  {# call gtk_tree_view_column_set_expand #}
    self
    (fromBool expand)

-- %hash c:ee41 d:f16b
-- | Return @True@ if the column expands to take any available space.
--
-- * Available since Gtk+ version 2.4
--
treeViewColumnGetExpand :: TreeViewColumn
 -> IO Bool -- ^ returns @True@, if the column expands
treeViewColumnGetExpand self =
  liftM toBool $
  {# call gtk_tree_view_column_get_expand #}
    self
#endif

-- %hash c:77e0 d:e1c7
-- | Returns @True@ if any of the cells packed into the @treeColumn@ are
-- visible. For this to be meaningful, you must first initialize the cells with
-- 'treeViewColumnCellSetCellData'
--
treeViewColumnCellIsVisible :: TreeViewColumn
 -> IO Bool -- ^ returns @True@, if any of the cells packed into the
            -- @treeColumn@ are currently visible
treeViewColumnCellIsVisible self =
  liftM toBool $
  {# call gtk_tree_view_column_cell_is_visible #}
    self

#if GTK_CHECK_VERSION(2,2,0)
-- %hash c:a202 d:1401
-- | Sets the current keyboard focus to be at @cell@, if the column contains 2
-- or more editable and activatable cells.
--
-- * Available since Gtk+ version 2.2
--
treeViewColumnFocusCell :: CellRendererClass cell => TreeViewColumn
 -> cell -- ^ @cell@ - A 'CellRenderer'
 -> IO ()
treeViewColumnFocusCell self cell =
  {# call gtk_tree_view_column_focus_cell #}
    self
    (toCellRenderer cell)

#if GTK_CHECK_VERSION(2,8,0)
-- %hash c:4420 d:bfde
-- | Flags the column, and the cell renderers added to this column, to have
-- their sizes renegotiated.
--
-- * Available since Gtk+ version 2.8
--
treeViewColumnQueueResize :: TreeViewColumn -> IO ()
treeViewColumnQueueResize self =
  {# call gtk_tree_view_column_queue_resize #}
    self
#endif
#endif

--------------------
-- Attributes

-- | Whether to display the column.
--
-- Default value: @True@
--
treeViewColumnVisible :: Attr TreeViewColumn Bool
treeViewColumnVisible = newAttr
  treeViewColumnGetVisible
  treeViewColumnSetVisible

-- | Column is user-resizable.
--
-- Default value: @False@
--
treeViewColumnResizable :: Attr TreeViewColumn Bool
treeViewColumnResizable = newAttr
  treeViewColumnGetResizable
  treeViewColumnSetResizable

-- | Current width of the column.
--
-- Allowed values: >= 0
--
-- Default value: 0
--
treeViewColumnWidth :: ReadAttr TreeViewColumn Int
treeViewColumnWidth = readAttrFromIntProperty "width"

-- | Space which is inserted between cells.
--
-- Allowed values: >= 0
--
-- Default value: 0
--
treeViewColumnSpacing :: Attr TreeViewColumn Int
treeViewColumnSpacing = newAttr
  treeViewColumnGetSpacing
  treeViewColumnSetSpacing

-- | Resize mode of the column.
--
-- Default value: 'TreeViewColumnGrowOnly'
--
treeViewColumnSizing :: Attr TreeViewColumn TreeViewColumnSizing
treeViewColumnSizing = newAttr
  treeViewColumnGetSizing
  treeViewColumnSetSizing

-- | Current fixed width of the column.
--
-- Allowed values: >= 1
--
-- Default value: 1
--
treeViewColumnFixedWidth :: Attr TreeViewColumn Int
treeViewColumnFixedWidth = newAttr
  treeViewColumnGetFixedWidth
  treeViewColumnSetFixedWidth

-- | Minimum allowed width of the column.
--
-- Allowed values: >= -1
--
-- Default value: -1
--
treeViewColumnMinWidth :: Attr TreeViewColumn Int
treeViewColumnMinWidth = newAttr
  treeViewColumnGetMinWidth
  treeViewColumnSetMinWidth

-- | Maximum allowed width of the column.
--
-- Allowed values: >= -1
--
-- Default value: -1
--
treeViewColumnMaxWidth :: Attr TreeViewColumn Int
treeViewColumnMaxWidth = newAttr
  treeViewColumnGetMaxWidth
  treeViewColumnSetMaxWidth

-- | Title to appear in column header.
--
-- Default value: \"\"
--
treeViewColumnTitle :: ReadWriteAttr TreeViewColumn (Maybe String) String
treeViewColumnTitle = newAttr
  treeViewColumnGetTitle
  treeViewColumnSetTitle

-- %hash c:800 d:eb1a
-- | Column gets share of extra width allocated to the widget.
--
-- Default value: @False@
--
treeViewColumnExpand :: Attr TreeViewColumn Bool
treeViewColumnExpand = newAttrFromBoolProperty "expand"

-- | Whether the header can be clicked.
--
-- Default value: @False@
--
treeViewColumnClickable :: Attr TreeViewColumn Bool
treeViewColumnClickable = newAttr
  treeViewColumnGetClickable
  treeViewColumnSetClickable

-- | Widget to put in column header button instead of column title.
--
treeViewColumnWidget :: WidgetClass widget => ReadWriteAttr TreeViewColumn (Maybe Widget) (Maybe widget)
treeViewColumnWidget = newAttr
  treeViewColumnGetWidget
  treeViewColumnSetWidget

-- | X Alignment of the column header text or widget.
--
-- Allowed values: [0,1]
--
-- Default value: 0
--
treeViewColumnAlignment :: Attr TreeViewColumn Float
treeViewColumnAlignment = newAttr
  treeViewColumnGetAlignment
  treeViewColumnSetAlignment

-- | Whether the column can be reordered around the headers.
--
-- Default value: @False@
--
treeViewColumnReorderable :: Attr TreeViewColumn Bool
treeViewColumnReorderable = newAttr
  treeViewColumnGetReorderable
  treeViewColumnSetReorderable

-- | Whether to show a sort indicator.
--
-- Default value: @False@
--
treeViewColumnSortIndicator :: Attr TreeViewColumn Bool
treeViewColumnSortIndicator = newAttr
  treeViewColumnGetSortIndicator
  treeViewColumnSetSortIndicator

-- | Sort direction the sort indicator should indicate.
--
-- Default value: 'SortAscending'
--
treeViewColumnSortOrder :: Attr TreeViewColumn SortType
treeViewColumnSortOrder = newAttr
  treeViewColumnGetSortOrder
  treeViewColumnSetSortOrder

-- | \'sortColumnId\' property. See 'treeViewColumnGetSortColumnId' and
-- 'treeViewColumnSetSortColumnId'
--
treeViewColumnSortColumnId :: Attr TreeViewColumn SortColumnId
treeViewColumnSortColumnId = newAttr
  treeViewColumnGetSortColumnId
  treeViewColumnSetSortColumnId

--------------------
-- Signals

-- | Emitted when the header of this column has been clicked on.
--
onColClicked, afterColClicked :: TreeViewColumnClass self => self
 -> IO ()
 -> IO (ConnectId self)
onColClicked = connect_NONE__NONE "clicked" False
afterColClicked = connect_NONE__NONE "clicked" True

{-# LANGUAGE CPP #-}
-- -*-haskell-*-
--  GIMP Toolkit (GTK) TreeViewColumn TreeView
--
--  Author : Axel Simon
--
--  Created: 9 May 2001
--
--  Copyright (C) 2001-2005 Axel Simon
--
--  This library is free software; you can redistribute it and/or
--  modify it under the terms of the GNU Lesser General Public
--  License as published by the Free Software Foundation; either
--  version 2.1 of the License, or (at your option) any later version.
--
--  This library 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
--  Lesser General Public License for more details.
--
-- |
-- Maintainer  : gtk2hs-users@lists.sourceforge.net
-- Stability   : provisional
-- Portability : portable (depends on GHC)
--
-- A visible column in a 'TreeView' widget
--
module Graphics.UI.Gtk.ModelView.TreeViewColumn (
-- * Detail
--
-- | The 'TreeViewColumn' object represents a visible column in a 'TreeView'
-- widget. It allows to set properties of the column header, and functions as a
-- holding pen for the cell renderers which determine how the data in the
-- column is displayed.
--

-- * Class Hierarchy
-- |
-- @
-- |  'GObject'
-- |   +----'Object'
-- |         +----TreeViewColumn
-- @

-- * Types
  TreeViewColumn,
  TreeViewColumnClass,
  castToTreeViewColumn, gTypeTreeViewColumn,
  toTreeViewColumn,

-- * Constructors
  treeViewColumnNew,

-- * Methods
  treeViewColumnPackStart,
  treeViewColumnPackEnd,
  treeViewColumnClear,
  treeViewColumnGetCellRenderers,
  treeViewColumnSetSpacing,
  treeViewColumnGetSpacing,
  treeViewColumnSetVisible,
  treeViewColumnGetVisible,
  treeViewColumnSetResizable,
  treeViewColumnGetResizable,
  TreeViewColumnSizing(..),
  treeViewColumnSetSizing,
  treeViewColumnGetSizing,
  treeViewColumnGetWidth,
  treeViewColumnSetFixedWidth,
  treeViewColumnGetFixedWidth,
  treeViewColumnSetMinWidth,
  treeViewColumnGetMinWidth,
  treeViewColumnSetMaxWidth,
  treeViewColumnGetMaxWidth,
  treeViewColumnClicked,
  treeViewColumnSetTitle,
  treeViewColumnGetTitle,
  treeViewColumnSetClickable,
  treeViewColumnGetClickable,
  treeViewColumnSetWidget,
  treeViewColumnGetWidget,
  treeViewColumnSetAlignment,
  treeViewColumnGetAlignment,
  treeViewColumnSetReorderable,
  treeViewColumnGetReorderable,
  treeViewColumnSetSortColumnId,
  treeViewColumnGetSortColumnId,
  treeViewColumnSetSortIndicator,
  treeViewColumnGetSortIndicator,
  treeViewColumnSetSortOrder,
  treeViewColumnGetSortOrder,
  SortType(..),
#if GTK_CHECK_VERSION(2,4,0)
  treeViewColumnSetExpand,
  treeViewColumnGetExpand,
#endif
  treeViewColumnCellIsVisible,
#if GTK_CHECK_VERSION(2,2,0)
  treeViewColumnFocusCell,
#if GTK_CHECK_VERSION(2,8,0)
  treeViewColumnQueueResize,
#endif
#endif

-- * Attributes
  treeViewColumnVisible,
  treeViewColumnResizable,
  treeViewColumnWidth,
  treeViewColumnSpacing,
  treeViewColumnSizing,
  treeViewColumnFixedWidth,
  treeViewColumnMinWidth,
  treeViewColumnMaxWidth,
  treeViewColumnTitle,
  treeViewColumnExpand,
  treeViewColumnClickable,
  treeViewColumnWidget,
  treeViewColumnAlignment,
  treeViewColumnReorderable,
  treeViewColumnSortIndicator,
  treeViewColumnSortOrder,
  treeViewColumnSortColumnId,

-- * Signals
  onColClicked,
  afterColClicked
  ) where

import Control.Monad	(liftM)

import System.Glib.FFI
import System.Glib.UTFString
{#import System.Glib.GList#}			(fromGList)
import System.Glib.Attributes
import System.Glib.Properties
import Graphics.UI.Gtk.Abstract.Object		(makeNewObject)
{#import Graphics.UI.Gtk.Types#}
{#import Graphics.UI.Gtk.Signals#}
import Graphics.UI.Gtk.General.Enums		(TreeViewColumnSizing(..),
						 SortType(..))
import Graphics.UI.Gtk.General.Structs          (SortColumnId)
{#import Graphics.UI.Gtk.ModelView.TreeModel#}	()

{# context lib="gtk" prefix="gtk" #}

--------------------
-- Constructors

-- | Generate a new TreeViewColumn widget.
--
treeViewColumnNew :: IO TreeViewColumn
treeViewColumnNew  = makeNewObject mkTreeViewColumn
  {# call tree_view_column_new #}

--------------------
-- Methods

-- | Add a cell renderer at the beginning of a column.
--
-- * Excess space is divided equally among all renderers which have
--   @expand@ set to True.
--
treeViewColumnPackStart :: CellRendererClass cell => TreeViewColumn
 -> cell
 -> Bool
 -> IO ()
treeViewColumnPackStart self cell expand =
  {# call unsafe tree_view_column_pack_start #}
    self
    (toCellRenderer cell)
    (fromBool expand)

-- | Add a cell renderer at the end of a column.
--
-- * Excess space is divided equally among all renderers which have
--   @expand@ set to True.
--
treeViewColumnPackEnd :: CellRendererClass cell => TreeViewColumn
 -> cell
 -> Bool
 -> IO ()
treeViewColumnPackEnd self cell expand =
  {# call unsafe tree_view_column_pack_end #}
    self
    (toCellRenderer cell)
    (fromBool expand)

-- | Remove the associations of attributes to a store for all 'CellRenderer's.
--
treeViewColumnClear :: TreeViewColumn -> IO ()
treeViewColumnClear self =
  {# call tree_view_column_clear #}
    self

-- | Retrieve all 'CellRenderer's that are contained in this column.
--
treeViewColumnGetCellRenderers :: TreeViewColumn -> IO [CellRenderer]
treeViewColumnGetCellRenderers self =
  {# call unsafe tree_view_column_get_cell_renderers #}
    self
  >>= fromGList
  >>= mapM (makeNewObject mkCellRenderer . return)

-- | Set the number of pixels between two cell renderers.
--
treeViewColumnSetSpacing :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetSpacing self spacing =
  {# call tree_view_column_set_spacing #}
    self
    (fromIntegral spacing)

-- | Get the number of pixels between two cell renderers.
--
treeViewColumnGetSpacing :: TreeViewColumn -> IO Int
treeViewColumnGetSpacing self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_spacing #}
    self

-- | Set the visibility of a given column.
--
treeViewColumnSetVisible :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetVisible self visible =
  {# call tree_view_column_set_visible #}
    self
    (fromBool visible)

-- | Get the visibility of a given column.
--
treeViewColumnGetVisible :: TreeViewColumn -> IO Bool
treeViewColumnGetVisible self =
  liftM toBool $
  {# call unsafe tree_view_column_get_visible #}
    self

-- | Set if a given column is resizable by the user.
--
treeViewColumnSetResizable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetResizable self resizable =
  {# call tree_view_column_set_resizable #}
    self
    (fromBool resizable)

-- | Get if a given column is resizable by the user.
--
treeViewColumnGetResizable :: TreeViewColumn -> IO Bool
treeViewColumnGetResizable self =
  liftM toBool $
  {# call unsafe tree_view_column_get_resizable #}
    self

-- | Set wether the column can be resized.
--
treeViewColumnSetSizing :: TreeViewColumn
 -> TreeViewColumnSizing
 -> IO ()
treeViewColumnSetSizing self type_ =
  {# call tree_view_column_set_sizing #}
    self
    ((fromIntegral . fromEnum) type_)

-- | Return the resizing type of the column.
--
treeViewColumnGetSizing :: TreeViewColumn
 -> IO TreeViewColumnSizing
treeViewColumnGetSizing self =
  liftM (toEnum . fromIntegral) $
  {# call unsafe tree_view_column_get_sizing #}
    self

-- | Query the current width of the column.
--
treeViewColumnGetWidth :: TreeViewColumn -> IO Int
treeViewColumnGetWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_width #}
    self

-- | Set the width of the column.
--
-- * This is meaningful only if the sizing type is 'TreeViewColumnFixed'.
--
treeViewColumnSetFixedWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetFixedWidth self fixedWidth =
  {# call tree_view_column_set_fixed_width #}
    self
    (fromIntegral fixedWidth)

-- | Gets the fixed width of the column.
--
-- * This is meaningful only if the sizing type is 'TreeViewColumnFixed'.
--
-- * This value is only meaning may not be the actual width of the column on the
-- screen, just what is requested.
--
treeViewColumnGetFixedWidth :: TreeViewColumn -> IO Int
treeViewColumnGetFixedWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_fixed_width #}
    self

-- | Set minimum width of the column.
--
treeViewColumnSetMinWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetMinWidth self minWidth =
  {# call tree_view_column_set_min_width #}
    self
    (fromIntegral minWidth)

-- | Get the minimum width of a column. Returns -1 if this width was not set.
--
treeViewColumnGetMinWidth :: TreeViewColumn -> IO Int
treeViewColumnGetMinWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_min_width #}
    self

-- | Set maximum width of the column.
--
treeViewColumnSetMaxWidth :: TreeViewColumn -> Int -> IO ()
treeViewColumnSetMaxWidth self maxWidth =
  {# call tree_view_column_set_max_width #}
    self
    (fromIntegral maxWidth)

-- | Get the maximum width of a column. Returns -1 if this width was not set.
--
treeViewColumnGetMaxWidth :: TreeViewColumn -> IO Int
treeViewColumnGetMaxWidth self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_max_width #}
    self

-- | Emit the @clicked@ signal on the column.
--
treeViewColumnClicked :: TreeViewColumn -> IO ()
treeViewColumnClicked self =
  {# call tree_view_column_clicked #}
    self

-- | Set the widget's title if a custom widget has not been set.
--
treeViewColumnSetTitle :: TreeViewColumn -> String -> IO ()
treeViewColumnSetTitle self title =
  withUTFString title $ \titlePtr ->
  {# call tree_view_column_set_title #}
    self
    titlePtr

-- | Get the widget's title.
--
treeViewColumnGetTitle :: TreeViewColumn -> IO (Maybe String)
treeViewColumnGetTitle self =
  {# call unsafe tree_view_column_get_title #}
    self
  >>= maybePeek peekUTFString

-- | Set if the column should be sensitive to mouse clicks.
--
treeViewColumnSetClickable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetClickable self clickable =
  {# call tree_view_column_set_clickable #}
    self
    (fromBool clickable)

-- | Returns True if the user can click on the header for the column.
--
treeViewColumnGetClickable :: TreeViewColumn -> IO Bool
treeViewColumnGetClickable self =
  liftM toBool $
  {# call tree_view_column_get_clickable #}
    self

-- | Set the column's title to this widget.
--
treeViewColumnSetWidget :: WidgetClass widget => TreeViewColumn
 -> widget
 -> IO ()
treeViewColumnSetWidget self widget =
  {# call tree_view_column_set_widget #}
    self
    (toWidget widget)

-- | Retrieve the widget responsible for
-- showing the column title. In case only a text title was set this will be a
-- 'Alignment' widget with a 'Label' inside.
--
treeViewColumnGetWidget :: TreeViewColumn -> IO Widget
treeViewColumnGetWidget self =
  makeNewObject mkWidget $
  {# call unsafe tree_view_column_get_widget #}
    self

-- | Sets the alignment of the title or custom widget inside the column
-- header. The alignment determines its location inside the button -- 0.0 for
-- left, 0.5 for center, 1.0 for right.
--
treeViewColumnSetAlignment :: TreeViewColumn
 -> Float          -- ^ @xalign@ - The alignment, which is between [0.0 and
                   -- 1.0] inclusive.
 -> IO ()
treeViewColumnSetAlignment self xalign =
  {# call tree_view_column_set_alignment #}
    self
    (realToFrac xalign)

-- | Returns the current x alignment of the tree column. This value can range
-- between 0.0 and 1.0.
--
treeViewColumnGetAlignment :: TreeViewColumn -> IO Float
treeViewColumnGetAlignment self =
  liftM realToFrac $
  {# call unsafe tree_view_column_get_alignment #}
    self

-- | Set if the column can be reordered by the end user dragging the header.
--
treeViewColumnSetReorderable :: TreeViewColumn -> Bool -> IO ()
treeViewColumnSetReorderable self reorderable =
  {# call tree_view_column_set_reorderable #}
    self
    (fromBool reorderable)

-- | Returns whether the column can be reordered by the user.
--
treeViewColumnGetReorderable :: TreeViewColumn -> IO Bool
treeViewColumnGetReorderable self =
  liftM toBool $
  {# call unsafe tree_view_column_get_reorderable #}
    self

-- | Set the column by which to sort.
--
-- * Sets the logical @columnId@ that this column sorts on when
--   this column is selected for sorting. The selected column's header
--   will be clickable after this call. Logical refers to the
--   'Graphics.UI.Gtk.ModelView.TreeSortable.SortColumnId' for which
--   a comparison function was set.
--
treeViewColumnSetSortColumnId :: TreeViewColumn -> SortColumnId -> IO ()
treeViewColumnSetSortColumnId self sortColumnId =
  {# call tree_view_column_set_sort_column_id #}
    self
    (fromIntegral sortColumnId)

-- | Get the column by which to sort.
--
-- * Retrieves the logical @columnId@ that the model sorts on when this column
--   is selected for sorting.
--
-- * Returns
--   'Graphics.UI.Gtk.ModelView.TreeSortable.treeSortableDefaultSortColumnId'
--   if this tree view column has no
--   'Graphics.UI.Gtk.ModelView.TreeSortable.SortColumnId' associated with it.
--
treeViewColumnGetSortColumnId :: TreeViewColumn -> IO SortColumnId
treeViewColumnGetSortColumnId self =
  liftM fromIntegral $
  {# call unsafe tree_view_column_get_sort_column_id #}
    self

-- | Set if a given column has sorting arrows in its heading.
--
treeViewColumnSetSortIndicator :: TreeViewColumn
 -> Bool -> IO ()
treeViewColumnSetSortIndicator self setting =
  {# call tree_view_column_set_sort_indicator #}
    self
    (fromBool setting)

-- | Query if a given column has sorting arrows in its heading.
--
treeViewColumnGetSortIndicator :: TreeViewColumn -> IO Bool
treeViewColumnGetSortIndicator self =
  liftM toBool $
  {# call unsafe tree_view_column_get_sort_indicator #}
    self

-- | Set if a given column is sorted in ascending or descending order.
--
-- * In order for sorting to work, it is necessary to either use automatic
--   sorting via 'treeViewColumnSetSortColumnId' or to use a
--   user defined sorting on the elements in a 'TreeModel'.
--
treeViewColumnSetSortOrder :: TreeViewColumn
 -> SortType -> IO ()
treeViewColumnSetSortOrder self order =
  {# call tree_view_column_set_sort_order #}
    self
    ((fromIntegral . fromEnum) order)

-- | Query if a given column is sorted in ascending or descending order.
--
treeViewColumnGetSortOrder :: TreeViewColumn -> IO SortType
treeViewColumnGetSortOrder self =
  liftM (toEnum . fromIntegral) $
  {# call unsafe tree_view_column_get_sort_order #}
    self

#if GTK_CHECK_VERSION(2,4,0)
-- %hash c:7808 d:942b
-- | Sets the column to take available extra space. This space is shared
-- equally amongst all columns that have the expand set to @True@. If no column
-- has this option set, then the last column gets all extra space. By default,
-- every column is created with this @False@.
--
-- * Available since Gtk+ version 2.4
--
treeViewColumnSetExpand :: TreeViewColumn
 -> Bool -- ^ @expand@ - @True@ if the column should take available extra
         -- space, @False@ if not
 -> IO ()
treeViewColumnSetExpand self expand =
  {# call gtk_tree_view_column_set_expand #}
    self
    (fromBool expand)

-- %hash c:ee41 d:f16b
-- | Return @True@ if the column expands to take any available space.
--
-- * Available since Gtk+ version 2.4
--
treeViewColumnGetExpand :: TreeViewColumn
 -> IO Bool -- ^ returns @True@, if the column expands
treeViewColumnGetExpand self =
  liftM toBool $
  {# call gtk_tree_view_column_get_expand #}
    self
#endif

-- %hash c:77e0 d:e1c7
-- | Returns @True@ if any of the cells packed into the @treeColumn@ are
-- visible. For this to be meaningful, you must first initialize the cells with
-- 'treeViewColumnCellSetCellData'
--
treeViewColumnCellIsVisible :: TreeViewColumn
 -> IO Bool -- ^ returns @True@, if any of the cells packed into the
            -- @treeColumn@ are currently visible
treeViewColumnCellIsVisible self =
  liftM toBool $
  {# call gtk_tree_view_column_cell_is_visible #}
    self

#if GTK_CHECK_VERSION(2,2,0)
-- %hash c:a202 d:1401
-- | Sets the current keyboard focus to be at @cell@, if the column contains 2
-- or more editable and activatable cells.
--
-- * Available since Gtk+ version 2.2
--
treeViewColumnFocusCell :: CellRendererClass cell => TreeViewColumn
 -> cell -- ^ @cell@ - A 'CellRenderer'
 -> IO ()
treeViewColumnFocusCell self cell =
  {# call gtk_tree_view_column_focus_cell #}
    self
    (toCellRenderer cell)

#if GTK_CHECK_VERSION(2,8,0)
-- %hash c:4420 d:bfde
-- | Flags the column, and the cell renderers added to this column, to have
-- their sizes renegotiated.
--
-- * Available since Gtk+ version 2.8
--
treeViewColumnQueueResize :: TreeViewColumn -> IO ()
treeViewColumnQueueResize self =
  {# call gtk_tree_view_column_queue_resize #}
    self
#endif
#endif

--------------------
-- Attributes

-- | Whether to display the column.
--
-- Default value: @True@
--
treeViewColumnVisible :: Attr TreeViewColumn Bool
treeViewColumnVisible = newAttr
  treeViewColumnGetVisible
  treeViewColumnSetVisible

-- | Column is user-resizable.
--
-- Default value: @False@
--
treeViewColumnResizable :: Attr TreeViewColumn Bool
treeViewColumnResizable = newAttr
  treeViewColumnGetResizable
  treeViewColumnSetResizable

-- | Current width of the column.
--
-- Allowed values: >= 0
--
-- Default value: 0
--
treeViewColumnWidth :: ReadAttr TreeViewColumn Int
treeViewColumnWidth = readAttrFromIntProperty "width"

-- | Space which is inserted between cells.
--
-- Allowed values: >= 0
--
-- Default value: 0
--
treeViewColumnSpacing :: Attr TreeViewColumn Int
treeViewColumnSpacing = newAttr
  treeViewColumnGetSpacing
  treeViewColumnSetSpacing

-- | Resize mode of the column.
--
-- Default value: 'TreeViewColumnGrowOnly'
--
treeViewColumnSizing :: Attr TreeViewColumn TreeViewColumnSizing
treeViewColumnSizing = newAttr
  treeViewColumnGetSizing
  treeViewColumnSetSizing

-- | Current fixed width of the column.
--
-- Allowed values: >= 1
--
-- Default value: 1
--
treeViewColumnFixedWidth :: Attr TreeViewColumn Int
treeViewColumnFixedWidth = newAttr
  treeViewColumnGetFixedWidth
  treeViewColumnSetFixedWidth

-- | Minimum allowed width of the column.
--
-- Allowed values: >= -1
--
-- Default value: -1
--
treeViewColumnMinWidth :: Attr TreeViewColumn Int
treeViewColumnMinWidth = newAttr
  treeViewColumnGetMinWidth
  treeViewColumnSetMinWidth

-- | Maximum allowed width of the column.
--
-- Allowed values: >= -1
--
-- Default value: -1
--
treeViewColumnMaxWidth :: Attr TreeViewColumn Int
treeViewColumnMaxWidth = newAttr
  treeViewColumnGetMaxWidth
  treeViewColumnSetMaxWidth

-- | Title to appear in column header.
--
-- Default value: \"\"
--
treeViewColumnTitle :: ReadWriteAttr TreeViewColumn (Maybe String) String
treeViewColumnTitle = newAttr
  treeViewColumnGetTitle
  treeViewColumnSetTitle

-- %hash c:800 d:eb1a
-- | Column gets share of extra width allocated to the widget.
--
-- Default value: @False@
--
treeViewColumnExpand :: Attr TreeViewColumn Bool
treeViewColumnExpand = newAttrFromBoolProperty "expand"

-- | Whether the header can be clicked.
--
-- Default value: @False@
--
treeViewColumnClickable :: Attr TreeViewColumn Bool
treeViewColumnClickable = newAttr
  treeViewColumnGetClickable
  treeViewColumnSetClickable

-- | Widget to put in column header button instead of column title.
--
treeViewColumnWidget :: WidgetClass widget => ReadWriteAttr TreeViewColumn Widget widget
treeViewColumnWidget = newAttr
  treeViewColumnGetWidget
  treeViewColumnSetWidget

-- | X Alignment of the column header text or widget.
--
-- Allowed values: [0,1]
--
-- Default value: 0
--
treeViewColumnAlignment :: Attr TreeViewColumn Float
treeViewColumnAlignment = newAttr
  treeViewColumnGetAlignment
  treeViewColumnSetAlignment

-- | Whether the column can be reordered around the headers.
--
-- Default value: @False@
--
treeViewColumnReorderable :: Attr TreeViewColumn Bool
treeViewColumnReorderable = newAttr
  treeViewColumnGetReorderable
  treeViewColumnSetReorderable

-- | Whether to show a sort indicator.
--
-- Default value: @False@
--
treeViewColumnSortIndicator :: Attr TreeViewColumn Bool
treeViewColumnSortIndicator = newAttr
  treeViewColumnGetSortIndicator
  treeViewColumnSetSortIndicator

-- | Sort direction the sort indicator should indicate.
--
-- Default value: 'SortAscending'
--
treeViewColumnSortOrder :: Attr TreeViewColumn SortType
treeViewColumnSortOrder = newAttr
  treeViewColumnGetSortOrder
  treeViewColumnSetSortOrder

-- | \'sortColumnId\' property. See 'treeViewColumnGetSortColumnId' and
-- 'treeViewColumnSetSortColumnId'
--
treeViewColumnSortColumnId :: Attr TreeViewColumn SortColumnId
treeViewColumnSortColumnId = newAttr
  treeViewColumnGetSortColumnId
  treeViewColumnSetSortColumnId

--------------------
-- Signals

-- | Emitted when the header of this column has been clicked on.
--
onColClicked, afterColClicked :: TreeViewColumnClass self => self
 -> IO ()
 -> IO (ConnectId self)
onColClicked = connect_NONE__NONE "clicked" False
afterColClicked = connect_NONE__NONE "clicked" True