From: Axel S. <A....@ke...> - 2007-07-16 10:33:32
|
Mon Jul 16 03:27:22 PDT 2007 A....@ke... * Make the new ModelView interface self contained. This patch moves a few model functions from CustomStore to TreeModel. Also, it duplicates the TreeIter and TreePath definitions by copying them into the ModelView.Types file. The TreeModel module is now complete. However, another step would be to re-export all functions from CustomStore via TreeModel and hide CustomStore. The user would then be able to define a new store by just importing TreeModel. move ./gtk/Graphics/UI/Gtk/TreeList/TreeRowReference.chs.pp ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp hunk ./Makefile.am 515 - gtk/Graphics/UI/Gtk/TreeList/TreeRowReference.chs.pp \ hunk ./Makefile.am 542 + gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp \ hunk ./Makefile.am 590 - gtk/Graphics/UI/Gtk/TreeList/TreeRowReference.hs \ - gtk/Graphics/UI/Gtk/ModelView/TreePath.hs \ - gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.hs \ hunk ./gtk/Graphics/UI/Gtk/ModelView.hs 49 + module Graphics.UI.Gtk.ModelView.TreeRowReference, hunk ./gtk/Graphics/UI/Gtk/ModelView.hs 53 - module Graphics.UI.Gtk.ModelView.TreeViewColumn, - module Graphics.UI.Gtk.ModelView.Types, + module Graphics.UI.Gtk.ModelView.TreeViewColumn hunk ./gtk/Graphics/UI/Gtk/ModelView.hs 72 +import Graphics.UI.Gtk.ModelView.TreeRowReference hunk ./gtk/Graphics/UI/Gtk/ModelView.hs 77 -import Graphics.UI.Gtk.ModelView.Types hunk ./gtk/Graphics/UI/Gtk/ModelView/CellLayout.chs.pp 71 -{#import Graphics.UI.Gtk.TreeList.TreeIter#} hunk ./gtk/Graphics/UI/Gtk/ModelView/CellRendererPixbuf.chs.pp 29 --- [_$_] +-- hunk ./gtk/Graphics/UI/Gtk/ModelView/CellRendererToggle.chs.pp 208 --- | The ::toggled signal is emitted when the cell is toggled. +-- | The 'toggled' signal is emitted when the cell is toggled. hunk ./gtk/Graphics/UI/Gtk/ModelView/ComboBox.chs.pp 144 -import Graphics.UI.Gtk.ModelView.Types (TypedTreeModelClass) +{#import Graphics.UI.Gtk.ModelView.Types#} (TypedTreeModelClass, + TreeIter, + receiveTreeIter) hunk ./gtk/Graphics/UI/Gtk/ModelView/ComboBox.chs.pp 148 -{#import Graphics.UI.Gtk.TreeList.TreeIter#} (TreeIter(..), receiveTreeIter) hunk ./gtk/Graphics/UI/Gtk/ModelView/ComboBox.chs.pp 648 -popupShownNotify = Signal (Connect_NONE__NONE "notify::popup-shown") +popupShownNotify = Signal (connect_NONE__NONE "notify::popup-shown") hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 28 + TreeModelFlags(..), + [_$_] hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 43 - - -- * View notification functions - treeModelRowChanged, - treeModelRowInserted, - treeModelRowHasChildToggled, - treeModelRowDeleted, - treeModelRowsReordered, hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 48 -import System.Glib.Flags (fromFlags) +import System.Glib.Flags (Flags, fromFlags) hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 52 -{#import Graphics.UI.Gtk.ModelView.TreeModel#} -{#import Graphics.UI.Gtk.TreeList.TreeIter#} -{#import Graphics.UI.Gtk.TreeList.TreePath#} - hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 63 +-- | These flags indicate various properties of a 'TreeModel'. +-- +-- * If a model has "TreeModelItersPersist" set, iterators remain valid +-- after a "TreeModel" signal was emitted. +-- +-- * The "TreeModelListOnly" flag is set if the rows are arranged in a +-- simple flat list. This is set in the "ListStore" implementation. +-- +{#enum TreeModelFlags {underscoreToCase} deriving(Bounded)#} + +instance Flags TreeModelFlags + hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 367 - hunk ./gtk/Graphics/UI/Gtk/ModelView/CustomStore.chs 370 --- | Emits the \"row_changed\" signal on the 'CustomTreeModel'. --- -treeModelRowChanged :: - CustomTreeModel private row - -> TreePath -- ^ @path@ - A 'TreePath' pointing to the changed row - -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the changed row - -> IO () -treeModelRowChanged model path iter = - withTreePath path $ \pathPtr -> - customTreeModelGetStamp model >>= \stamp -> - with (iterSetStamp stamp iter) $ \iterPtr -> - {# call gtk_tree_model_row_changed #} - (toTreeModel model) - pathPtr - iterPtr - --- | Emits the \"row_inserted\" signal on the 'CustomTreeModel' --- -treeModelRowInserted :: - CustomTreeModel private row - -> TreePath -- ^ @path@ - A 'TreePath' pointing to the inserted row - -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the inserted row - -> IO () -treeModelRowInserted model path iter = - withTreePath path $ \pathPtr -> - customTreeModelGetStamp model >>= \stamp -> - with (iterSetStamp stamp iter) $ \iterPtr -> - {# call gtk_tree_model_row_inserted #} - (toTreeModel model) - pathPtr - iterPtr - --- | Emits the \"row_has_child_toggled\" signal on the 'CustomTreeModel'. This should --- be called by models after a node went from having no children to having --- at least one child or vice versa. --- -treeModelRowHasChildToggled :: - CustomTreeModel private row - -> TreePath -- ^ @path@ - A 'TreePath' pointing to the changed row - -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the changed row - -> IO () -treeModelRowHasChildToggled model path iter = - withTreePath path $ \pathPtr -> - customTreeModelGetStamp model >>= \stamp -> - with (iterSetStamp stamp iter) $ \iterPtr -> - {# call gtk_tree_model_row_has_child_toggled #} - (toTreeModel model) - pathPtr - iterPtr - --- | Emits the \"row_deleted\" signal the 'CustomTreeModel'. This should be called by --- models after a row has been removed. The location pointed to by @path@ --- should be the location that the row previously was at. It may not be a valid --- location anymore. --- -treeModelRowDeleted :: - CustomTreeModel private row - -> TreePath -- ^ @path@ - A 'TreePath' pointing to the previous location of - -- the deleted row. - -> IO () -treeModelRowDeleted model path = - withTreePath path $ \pathPtr -> - {# call gtk_tree_model_row_deleted #} - (toTreeModel model) - pathPtr - --- | Emits the \"rows_reordered\" signal on the 'CustomTreeModel'. This should be --- called by models when their rows have been reordered. --- -treeModelRowsReordered :: - CustomTreeModel private row - -> TreePath -- ^ @path@ - A 'TreePath' pointing to the tree node whose - -- children have been reordered - -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the node whose - -- children have been reordered, or {@NULL@, FIXME: this should - -- probably be converted to a Maybe data type} if the depth of - -- @path@ is 0. - -> [Int] -- ^ @newOrder@ - an array of integers mapping the current - -- position of each child to its old position before the - -- re-ordering, i.e. @newOrder@@[newpos] = oldpos@. - -> IO () -treeModelRowsReordered model path iter newOrder = - withTreePath path $ \pathPtr -> - customTreeModelGetStamp model >>= \stamp -> - with (iterSetStamp stamp iter) $ \iterPtr -> - withArrayLen (map fromIntegral newOrder) $ \newLength newOrderArrPtr -> do - --check newOrder is the right length or it'll overrun - curLength <- treeModelIterNChildren model (Just iter) - when (curLength /= newLength) - (fail "treeModelRowsReordered: mapping wrong length for store") - {# call gtk_tree_model_rows_reordered #} - (toTreeModel model) - pathPtr - iterPtr - newOrderArrPtr hunk ./gtk/Graphics/UI/Gtk/ModelView/EntryCompletion.chs.pp 133 -{#import Graphics.UI.Gtk.TreeList.TreeIter#} (TreeIter) hunk ./gtk/Graphics/UI/Gtk/ModelView/IconView.chs.pp 148 -{#import Graphics.UI.Gtk.TreeList.TreePath#} hunk ./gtk/Graphics/UI/Gtk/ModelView/ListStore.hs.pp 60 -import Graphics.UI.Gtk.ModelView.Types (TypedTreeModelClass) -import Graphics.UI.Gtk.ModelView.TreeModel (TreeModelFlags(TreeModelListOnly)) +import Graphics.UI.Gtk.ModelView.Types (TypedTreeModelClass, TreeIter(..)) hunk ./gtk/Graphics/UI/Gtk/ModelView/ListStore.hs.pp 62 -import Graphics.UI.Gtk.TreeList.TreeIter +import Graphics.UI.Gtk.ModelView.TreeModel hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 8 --- Copyright (C) 1999-2005 Axel Simon +-- Copyright (C) 1999-2007 Axel Simon hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 25 --- The tree interface used by 'TreeView' +-- The tree interface used by 'TreeView'. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 29 --- [_$_] +-- [_$_] hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 31 --- 'TreeView' widget. It is purely abstract, concrete implementations that --- store data for a list or tree are 'ListStore' and 'TreeStore'. +-- 'TreeView' widget. In other words, this module exposes the C interface that +-- Gtk uses to populate the 'TreeView' widget. While this module is an +-- interface from the perspective of Gtk, this module provides a skeleton to +-- create an object that implements this interface. Two implementations that +-- come with Gtk2Hs are 'ListStore' and 'TreeStore'. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 37 --- The model is represented as a hierarchical tree of strongly-typed, --- columned data. In other words, the model can be seen as a tree where every --- node has different values depending on which column is being queried. The --- type of data found in a column can be arbitrary, ranging from basic --- types like 'String's or 'Int' to user specific types. The types are --- homogeneous per column across all nodes. It is important to note that this --- interface only provides a way of examining a model and observing changes. --- The implementation of each individual model decides how and if changes are --- made. +-- The model is represented as a hierarchical tree of values. It is important +-- to note that this interface only provides a way of examining a model and +-- observing changes. The implementation of each individual model decides how +-- and if changes are made. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 43 --- the --- 'TreeStore' and the 'ListStore'. To use these, the developer simply pushes --- data into these models as necessary. These models provide the data [_$_] +-- the 'TreeStore' and the 'ListStore'. To use these, the developer simply +-- inserts data into these models as necessary. These models provide the data hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 46 --- other interfaces making drag --- and drop, sorting, and storing data trivial. +-- other interfaces making drag and drop and storing data trivial. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 48 --- Models are accessed on a node\/column level of granularity. One can query --- for the value of a model at a certain node and a certain column on that --- node. There are two structures used to reference a particular node in a --- model. They are the 'TreePath' and the 'TreeIter' Most of the interface --- consists of operations on a 'TreeIter'. +-- Models are accessed on a node level of granularity. There are two index +-- types used to reference a particular node in a model. They are the +-- 'TreePath' and the 'TreeIter'. Most of the interface consists of operations +-- on a 'TreeIter'. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 55 --- 'TreePath' is in fact just a list of 'Int's and hence are easy to --- manipulate. Each number refers to the offset at that level. Thus, the [_$_] --- path @[0]@ refers to the --- root node and the path @[2,4]@ refers to the fifth child of the third node. +-- 'TreePath' is in fact a synonym for a list of 'Int's and hence are easy to +-- manipulate. Each number refers to the offset at that level. Thus, the path +-- @[0]@ refers to the root node and the path @[2,4]@ refers to the fifth +-- child of the third node. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 61 --- model. It is an abstract data type filled in by the model. One can convert a --- path to an iterator by calling 'treeModelGetIter'. These iterators are the --- primary way of accessing a model and are similar to the iterators used by --- 'TextBuffer'. The model interface defines a set of operations using --- them for navigating the model. --- --- The lifecycle of an iterator can be a little confusing at first. --- Iterators are expected to always be valid for as long as the model is --- unchanged (and doesn't emit a signal). [_$_] --- Additionally, the 'TreeStore' and 'ListStore' models guarantee that [_$_] --- an iterator is valid for as long as the node it refers to is valid. --- Although generally uninteresting, as one --- always has to allow for the case where iterators do not persist beyond a --- signal, some very important performance enhancements were made in the sort --- model. As a result, the 'TreeModelItersPersist' flag was added to indicate --- this behavior. +-- model. It is an abstract data type filled in by the model. One can convert +-- a path to an iterator by calling 'treeModelGetIter'. These iterators are +-- the primary way of accessing a model and are similar to the iterators used +-- by 'TextBuffer'. The model interface defines a set of operations using them +-- for navigating the model. Iterators are expected to always be valid for as +-- long as the model is unchanged (and doesn't emit a signal). hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 74 +-- | +--------TypedTreeModel hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 82 + + TypedTreeModel, + TypedTreeModelClass, + toTypedTreeModel, + [_$_] hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 88 + TreeIter(..), hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 90 - TreeRowReference, - TreeIter, hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 92 + stringToTreePath, hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 94 - treeModelGetNColumns, - treeModelGetColumnType, - treeModelGetValue, - treeRowReferenceNew, - treeRowReferenceGetPath, - treeRowReferenceValid, hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 96 - gtk_tree_model_get_iter_from_string, -- internal hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 103 - treeModelIterParent + treeModelIterParent, + treeModelForeach, +#if GTK_CHECK_VERSION(2,2,0) + treeModelGetStringFromIter, +#endif + treeModelRefNode, + treeModelUnrefNode, + treeModelRowChanged, + treeModelRowInserted, + treeModelRowHasChildToggled, + treeModelRowDeleted, + treeModelRowsReordered, + +-- * Signals + rowChanged, + rowInserted, + rowHasChildToggled, + rowDeleted, + rowsReordered, + hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 128 -import System.Glib.Flags (Flags, toFlags) +import System.Glib.Flags (toFlags) hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 130 +{#import Graphics.UI.Gtk.Signals#} hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 135 -{#import Graphics.UI.Gtk.TreeList.TreeIter#} -{#import Graphics.UI.Gtk.TreeList.TreePath#} -{#import Graphics.UI.Gtk.TreeList.TreeRowReference#} +{#import Graphics.UI.Gtk.ModelView.CustomStore#} (TreeModelFlags(..), + treeModelGetRow) +{#import Graphics.UI.Gtk.ModelView.Types#} (TypedTreeModel, + TypedTreeModelClass, + toTypedTreeModel, + TreeIter(..), + receiveTreeIter, + peekTreeIter, + TreePath, + NativeTreePath(..), + withTreePath, + fromTreePath, + peekTreePath, + stringToTreePath) hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 152 --- | These flags indicate various properties of a 'TreeModel'. --- --- * If a model has "TreeModelItersPersist" set, iterators remain valid --- after a "TreeModel" signal was emitted. --- --- * The "TreeModelListOnly" flag is set if the rows are arranged in a --- simple flat list. This is set in the "ListStore" implementation. --- -{#enum TreeModelFlags {underscoreToCase} deriving(Bounded)#} - -instance Flags TreeModelFlags hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 156 +-- %hash d:35ea hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 168 --- | Returns the number of columns supported by the tree model. --- -treeModelGetNColumns :: TreeModelClass self => self - -> IO Int -- ^ returns The number of columns. -treeModelGetNColumns self = - liftM fromIntegral $ - {# call gtk_tree_model_get_n_columns #} - (toTreeModel self) - --- | Returns the type of the column. --- -treeModelGetColumnType :: TreeModelClass self => self - -> Int -- ^ @index@ - The column index. - -> IO TMType -treeModelGetColumnType self index = - liftM (toEnum.fromIntegral) $ - {# call tree_model_get_column_type #} - (toTreeModel self) - (fromIntegral index) - --- | Read the value of at a specific column and 'TreeIter'. --- -treeModelGetValue :: TreeModelClass self => self - -> TreeIter - -> Int -- ^ @column@ - The column to lookup the value at. - -> IO GenericValue -treeModelGetValue self iter column = - allocaGValue $ \vaPtr -> - with iter $ \iterPtr -> do - {# call tree_model_get_value #} - (toTreeModel self) - iterPtr - (fromIntegral column) - vaPtr - valueGetGenericValue vaPtr - --- | Maps a function over each node in model in a depth-first fashion. If it --- returns @True@, then the tree ceases to be walked, and 'treeModelForeach' --- returns. --- -treeModelForeach :: TreeModelClass self => self -> (TreeIter -> IO Bool) -> IO () -treeModelForeach self fun = do - fPtr <- mkTreeModelForeachFunc (\_ _ iterPtr _ -> do - -- make a deep copy of the iterator. This makes it possible to store this - -- iterator in Haskell land somewhere. The TreeModel parameter is not - -- passed to the function due to performance reasons. But since it is - -- a constant this does not matter. - iter <- peek iterPtr - liftM (fromIntegral.fromBool) $ fun iter - ) - {# call tree_model_foreach #} - (toTreeModel self) - fPtr - nullPtr - freeHaskellFunPtr fPtr - -{#pointer TreeModelForeachFunc#} - -foreign import ccall "wrapper" mkTreeModelForeachFunc :: - (Ptr () -> Ptr () -> Ptr TreeIter -> Ptr () -> IO CInt) -> IO TreeModelForeachFunc - +-- %hash c:35a1 d:49a2 hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 185 +-- %hash c:4cd2 d:ad96 hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 204 +-- %hash c:103f d:8041 hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 217 +-- %hash c:ec20 d:d43e hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 231 --- | Retrieve an iterator to the next child. +-- %hash c:5c12 d:d7db +-- | Retrieve an iterator to the node following it at the current level. If +-- there is no next node, @Nothing@ is returned. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 243 --- | Retrieve an iterator to the first child. +-- %hash c:7eba d:27e8 +-- | Retrieve an iterator to the first child of @parent@. If @parent@ has no +-- children, @Nothing@. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 248 - -> TreeIter + -> TreeIter -- ^ @parent@ - a pointer to the parent hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 258 +-- %hash c:dcc3 hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 271 +-- %hash c:eed hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 285 --- | Retrieve the @n@th child. --- --- If @Nothing@ is specified for the @self@ argument, the function will work --- on toplevel elements. +-- %hash c:6950 d:6f4d +-- | Retrieve the @n@th child of @parent@, counting from zero. If @n@ is too +-- big or @parent@ has no children, @Nothing@ is returned. If @Nothing@ is +-- specified for the @parent@ argument, the function will return the @n@th +-- root node. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 305 +-- %hash c:8f01 d:70ff hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModel.chs.pp 319 +-- %hash c:154f d:a6d +-- | Maps a function over each node in model in a depth-first fashion. If it +-- returns @True@, then the tree ceases to be walked, and 'treeModelForeach' +-- returns. +-- +treeModelForeach :: TreeModelClass self => self -> (TreeIter -> IO Bool) -> IO () +treeModelForeach self fun = do + fPtr <- mkTreeModelForeachFunc (\_ _ iterPtr _ -> do + -- make a deep copy of the iterator. This makes it possible to store this + -- iterator in Haskell land somewhere. The TreeModel parameter is not + -- passed to the function due to performance reasons. But since it is + -- a constant this does not matter. + iter <- peek iterPtr + liftM (fromIntegral.fromBool) $ fun iter + ) + {# call tree_model_foreach #} + (toTreeModel self) + fPtr + nullPtr + freeHaskellFunPtr fPtr + +{#pointer TreeModelForeachFunc#} + +foreign import ccall "wrapper" mkTreeModelForeachFunc :: + (Ptr () -> Ptr () -> Ptr TreeIter -> Ptr () -> IO CInt) -> + IO TreeModelForeachFunc + +#if GTK_CHECK_VERSION(2,2,0) +-- %hash c:f04a d:94fd +-- | Generates a string representation of the iter. This string is a \':\' +-- separated list of numbers. For example, \"4:10:0:3\" would be an acceptable +-- return value for this string. +-- +-- * Available since Gtk+ version 2.2 +-- +treeModelGetStringFromIter :: TreeModelClass self => self + -> TreeIter -- ^ @iter@ - An 'TreeIter'. + -> IO String -- ^ returns A newly-allocated string. Must be freed with + -- 'gFree'. +treeModelGetStringFromIter self iter = with iter $ \iter -> + {# call gtk_tree_model_get_string_from_iter #} + (toTreeModel self) + iter + >>= readUTFString +#endif + +-- %hash c:228e d:304e +-- | Lets the tree ref the node. This is an optional method for models to +-- implement. To be more specific, models may ignore this call as it exists +-- primarily for performance reasons. +-- +-- This function is primarily meant as a way for views to let caching model +-- know when nodes are being displayed (and hence, whether or not to cache that +-- node.) For example, a file-system based model would not want to keep the +-- entire file-hierarchy in memory, just the sections that are currently being +-- displayed by every current view. +-- +-- A model should be expected to be able to get an iter independent of its +-- reffed state. +-- +treeModelRefNode :: TreeModelClass self => self + -> TreeIter -- ^ @iter@ - The 'TreeIter'. + -> IO () +treeModelRefNode self iter = with iter $ \iter -> + {# call gtk_tree_model_ref_node #} + (toTreeModel self) + iter + +-- %hash c:f5d7 d:22a6 +-- | Lets the tree unref the node. This is an optional method for models to +-- implement. To be more specific, models may ignore this call as it exists +-- primarily for performance reasons. +-- +-- For more information on what this means, see 'treeModelRefNode'. Please +-- note that nodes that are deleted are not unreffed. +-- +treeModelUnrefNode :: TreeModelClass self => self + -> TreeIter -- ^ @iter@ - The 'TreeIter'. + -> IO () +treeModelUnrefNode self iter = with iter $ \iter -> + {# call gtk_tree_model_unref_node #} + (toTreeModel self) + iter + +-- %hash c:8d25 d:a7c9 +-- | Emits the 'rowChanged' signal on the model. +-- +-- * This function is only necessary to implement a custom tree model. When +-- using 'Graphics.UI.Gtk.ModelView.ListStore' or +-- 'Graphics.UI.Gtk.ModelView.TreeStore', this function is called +-- automatically. +-- +treeModelRowChanged :: TreeModelClass self => self + -> TreePath -- ^ @path@ - A 'TreePath' pointing to the changed row + -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the changed row + -> IO () +treeModelRowChanged self path iter = + with iter $ \iter -> + withTreePath path $ \path -> + {# call gtk_tree_model_row_changed #} + (toTreeModel self) + path + iter + +-- %hash c:f809 d:57af +-- | Emits the 'rowInserted' signal on the model. +-- +-- * This function is only necessary to implement a custom tree model. When +-- using 'Graphics.UI.Gtk.ModelView.ListStore' or +-- 'Graphics.UI.Gtk.ModelView.TreeStore', this function is called +-- automatically. +-- +treeModelRowInserted :: TreeModelClass self => self + -> TreePath -- ^ @path@ - A 'TreePath' pointing to the inserted row + -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the inserted row + -> IO () +treeModelRowInserted self path iter = + with iter $ \iter -> + withTreePath path $ \path -> + {# call gtk_tree_model_row_inserted #} + (toTreeModel self) + path + iter + +-- %hash c:e917 d:6534 +-- | Emits the 'rowHasChildToggled' signal on the model. This should be +-- called by models after the child state of a node changes. +-- +-- * This function is only necessary to implement a custom tree model. When +-- using 'Graphics.UI.Gtk.ModelView.ListStore' or +-- 'Graphics.UI.Gtk.ModelView.TreeStore', this function is called +-- automatically. +-- +treeModelRowHasChildToggled :: TreeModelClass self => self + -> TreePath -- ^ @path@ - A 'TreePath' pointing to the changed row + -> TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the changed row + -> IO () +treeModelRowHasChildToggled self path iter = + with iter $ \iter -> + withTreePath path $ \path -> + {# call gtk_tree_model_row_has_child_toggled #} + (toTreeModel self) + path + iter + +-- %hash c:c0a2 d:7ca6 +-- | Emits the 'rowDeleted' signal on the model. This should be called by +-- models after a row has been removed. The location pointed to by @path@ +-- should be the location that the row previously was at. It may not be a +-- valid location anymore. +-- +-- * This function is only necessary to implement a custom tree model. When +-- using 'Graphics.UI.Gtk.ModelView.ListStore' or +-- 'Graphics.UI.Gtk.ModelView.TreeStore', this function is called +-- automatically. +-- +treeModelRowDeleted :: TreeModelClass self => self + -> TreePath -- ^ @path@ - A 'TreePath' pointing to the previous location of + -- the deleted row. + -> IO () +treeModelRowDeleted self path = + withTreePath path $ \path -> + {# call gtk_tree_model_row_deleted #} + (toTreeModel self) + path + +-- %hash c:f0f3 d:a8c5 +-- | Emits the 'rowsReordered' signal on the model. This should be called by +-- models when their rows have been reordered. The length of @newOrder@ must +-- be equal to the value returned by @treeModelIterNChildren self iter@. +-- +-- * This function is only necessary to implement a custom tree model. When +-- using 'Graphics.UI.Gtk.ModelView.ListStore' or +-- 'Graphics.UI.Gtk.ModelView.TreeStore', this function is called +-- automatically. +-- +treeModelRowsReordered :: TreeModelClass self => self + -> TreePath -- ^ @path@ - A 'TreePath' pointing to the tree node whose + -- children have been reordered + -> Maybe TreeIter -- ^ @iter@ - A valid 'TreeIter' pointing to the node whose + -- children have been reordered, or @Nothing@ if [_$_] + -- @path@ is @[]@. + -> [Int] -- ^ @newOrder@ - a list of integers giving the previous position + -- of each node at this hierarchy level. + [_$_] + -> IO () +treeModelRowsReordered self path iter array = do + n <- treeModelIterNChildren self iter + let l = length array + if n/=l then error ("treeModelRowsReordered: passed-in array is of size " + ++show l++" but there are "++show n++ + " children at path "++show path) else + withTreePath path $ \path -> + maybeWith with iter $ \iter -> + withArray (map fromIntegral array) $ \newOrderPtr -> + {# call gtk_tree_model_rows_reordered #} + (toTreeModel self) + path + iter + newOrderPtr + +-------------------- +-- Signals + +-- %hash c:50c7 d:8da5 +-- | This signal is emitted when a row in the model has changed. +-- +rowChanged :: TreeModelClass self => Signal self (TreePath -> TreeIter -> IO ()) +rowChanged = Signal (connect_BOXED_BOXED__NONE "row_changed" peekTreePath peekTreeIter) + +-- %hash c:f31a d:3c6b +-- | This signal is emitted when a new row has been inserted in the model. +-- +-- +rowInserted :: TreeModelClass self => Signal self (TreePath -> TreeIter -> IO ()) +rowInserted = Signal (connect_BOXED_BOXED__NONE "row_inserted" peekTreePath peekTreeIter) + +-- %hash c:7279 d:5ef +-- | This signal is emitted when a row has gotten the first child row or lost +-- its last child row. +-- +rowHasChildToggled :: TreeModelClass self => Signal self (TreePath -> TreeIter -> IO ()) +rowHasChildToggled = Signal (connect_BOXED_BOXED__NONE "row_has_child_toggled" peekTreePath peekTreeIter) + +-- %hash c:f669 d:367f +-- | This signal is emitted when a row has been deleted. +-- +-- Note that no iterator is passed to the signal handler, since the row is +-- already deleted. +-- +-- Implementations of 'TreeModel' must emit row-deleted /before/ removing the +-- node from its internal data structures. This is because models and views +-- which access and monitor this model might have references on the node which +-- need to be released in the 'rowDeleted' handler. +-- +rowDeleted :: TreeModelClass self => Signal self (TreePath -> IO ()) +rowDeleted = Signal (connect_BOXED__NONE "row_deleted" peekTreePath) + +-- %hash c:46dd d:b2e5 +-- | This signal is emitted when the children of a node in the 'TreeModel' +-- have been reordered. See 'treeModelRowsReordered' for more information +-- about the parameters that this signal carries. +-- +-- Note that this signal is /not/ emitted when rows are reordered by DND, +-- since this is implemented by removing and then reinserting the row. +-- +rowsReordered :: TreeModelClass self => + Signal self (TreePath -> Maybe TreeIter -> [Int] -> IO ()) +rowsReordered = Signal $ \after model user -> + connect_BOXED_BOXED_PTR__NONE "rows_reordered" peekTreePath + (maybePeek peekTreeIter) after model $ \path iter arrayPtr -> do + n <- treeModelIterNChildren model iter + -- hopefully the model is never buggy, otherwise this can segfault + newOrder <- peekArray n arrayPtr + user path iter (map fromIntegral (newOrder :: [{#type gint#}])) hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeModelSort.chs.pp 73 -{#import Graphics.UI.Gtk.TreeList.TreePath#} -{#import Graphics.UI.Gtk.TreeList.TreeIter#} +{#import Graphics.UI.Gtk.ModelView.Types#} hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 20 --- #hide - hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 25 --- [_$_] +-- A persistent index into a tree model. +-- +module Graphics.UI.Gtk.ModelView.TreeRowReference ( +-- * Detail +-- +-- | A 'RowReference' is an index into a +-- 'Graphics.UI.Gtk.ModelView.TreeModel.TreeModel' that is persistent even if +-- rows are inserted, deleted or reordered. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 34 -module Graphics.UI.Gtk.TreeList.TreeRowReference ( hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 50 -{#import Graphics.UI.Gtk.TreeList.TreePath#} +{#import Graphics.UI.Gtk.ModelView.Types#} hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 64 --- to the node pointed to by the given path, so long as it exists. +-- to the node pointed to by the given path, so long as it exists. Returns @Nothing@ if there is no node at the given path. hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 67 - -> NativeTreePath - -> IO TreeRowReference -treeRowReferenceNew self path = do - rowRefPtr <- throwIfNull "treeRowReferenceNew: invalid path given" $ + -> TreePath + -> IO (Maybe TreeRowReference) +treeRowReferenceNew self path = withTreePath path $ \path -> do + rowRefPtr <- [_$_] hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 72 - liftM TreeRowReference $ + if rowRefPtr==nullPtr then return Nothing else + liftM (Just . TreeRowReference) $ hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeRowReference.chs.pp 86 - >>= fromTreePath + >>= fromTreePath -- path must be freed hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeSelection.chs.pp 112 -{#import Graphics.UI.Gtk.TreeList.TreePath#} -{#import Graphics.UI.Gtk.TreeList.TreeIter#} +{#import Graphics.UI.Gtk.ModelView.Types#} hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeStore.hs 58 -import Graphics.UI.Gtk.TreeList.TreePath (TreePath) hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeStore.hs 59 -import Graphics.UI.Gtk.TreeList.TreeIter +import Graphics.UI.Gtk.ModelView.TreeModel hunk ./gtk/Graphics/UI/Gtk/ModelView/Types.chs 8 --- Copyright (C) 2006 Duncan Coutts +-- Copyright (C) 2006-2007 Duncan Coutts, Axel Simon hunk ./gtk/Graphics/UI/Gtk/ModelView/Types.chs 20 +-- #hide + hunk ./gtk/Graphics/UI/Gtk/ModelView/Types.chs 32 - toTypedTreeModel + toTypedTreeModel, + [_$_] + -- TreeIter + TreeIter(..), + receiveTreeIter, + peekTreeIter, + [_$_] + -- TreePath + TreePath, + NativeTreePath(..), + newTreePath, + withTreePath, + peekTreePath, + fromTreePath, + stringToTreePath [_$_] hunk ./gtk/Graphics/UI/Gtk/ModelView/Types.chs 53 +import Data.Char ( isDigit ) +import Control.Monad ( liftM ) hunk ./gtk/Graphics/UI/Gtk/ModelView/Types.chs 70 +-- | Tree Iterator: a pointer to an entry in a +-- 'Graphics.UI.Gtk.ModelView.TreeModel'. The constructor of this structure is +-- public for the sake of creating custom tree models. The first value is a +-- time stamp that is handled by the functions that interface with Gtk. The +-- time stamps are used to print warnings if programmers use an iter to a +-- model that has changed meanwhile. The other three fields are used by the +-- custom model implementation to implement an indexing scheme. The precise +-- use of the three words is therefore implementation specific. See also +-- 'TreePath'. +-- +data TreeIter = TreeIter {-# UNPACK #-} !CInt !Word !Word !Word + deriving Show + +{#pointer *TreeIter as TreeIterPtr -> TreeIter #} + +instance Storable TreeIter where + sizeOf _ = {# sizeof TreeIter #} + alignment _ = alignment (undefined :: CInt) + peek ptr = do + stamp <- {# get TreeIter->stamp #} ptr + user_data <- {# get TreeIter->user_data #} ptr + user_data2 <- {# get TreeIter->user_data2 #} ptr + user_data3 <- {# get TreeIter->user_data3 #} ptr + return (TreeIter stamp (ptrToWord user_data) + (ptrToWord user_data2) + (ptrToWord user_data3)) + + where ptrToWord :: Ptr a -> Word + ptrToWord ptr = fromIntegral (ptr `minusPtr` nullPtr) + + poke ptr (TreeIter stamp user_data user_data2 user_data3) = do + {# set TreeIter->stamp #} ptr stamp + {# set TreeIter->user_data #} ptr (wordToPtr user_data) + {# set TreeIter->user_data2 #} ptr (wordToPtr user_data2) + {# set TreeIter->user_data3 #} ptr (wordToPtr user_data3) + + where wordToPtr :: Word -> Ptr a + wordToPtr word = nullPtr `plusPtr` fromIntegral word + +-- Pass a pointer to a structure large enough to hold a GtkTreeIter +-- structure. If the function returns true, read the tree iter and +-- return it. +receiveTreeIter :: (Ptr TreeIter -> IO CInt) -> IO (Maybe TreeIter) +receiveTreeIter body = + alloca $ \iterPtr -> do + result <- body iterPtr + if toBool result + then liftM Just (peek iterPtr) + else return Nothing + +-- Note that this function does throw an error if the pointer is NULL rather +-- than returning some random tree iterator. +peekTreeIter :: Ptr TreeIter -> IO TreeIter +peekTreeIter ptr + | ptr==nullPtr = fail "peekTreeIter: ptr is NULL, tree iterator is invalid" + | otherwise = peek ptr + +-- | TreePath : a list of indices to specify a subtree or node in a +-- 'Graphics.UI.Gtk.ModelView.TreeModel.TreeModel'. The node that correspond +-- to a given 'TreePath' might change if nodes are removed or added and a +-- 'TreePath' may refer to a different or even non-existent node after a +-- modification of the model. In contrast, a 'TreeIter' is a more compact +-- representation of a 'TreePath' which becomes invalid after each +-- modification of the underlying model. An intelligent index that is adjusted +-- with each update of the model to point to the same node (whenever possible) +-- is 'Graphics.UI.Gtk.ModelView.TreeRowReference.TreeRowReference'. +-- +type TreePath = [Int] + +{#pointer * TreePath as NativeTreePath newtype#} + +nativeTreePathFree :: NativeTreePath -> IO () +nativeTreePathFree = + {# call unsafe tree_path_free #} + +newTreePath :: TreePath -> IO NativeTreePath +newTreePath path = do + nativePath <- liftM NativeTreePath {# call unsafe tree_path_new #} + mapM_ ({#call unsafe tree_path_append_index#} nativePath . fromIntegral) path + return nativePath + +withTreePath :: TreePath -> (NativeTreePath -> IO a) -> IO a +withTreePath tp act = do + nativePath <- newTreePath tp + res <- act nativePath + nativeTreePathFree nativePath + return res + +nativeTreePathGetIndices :: NativeTreePath -> IO [Int] +nativeTreePathGetIndices tp = do + depth <- liftM fromIntegral $ {# call unsafe tree_path_get_depth #} tp + arrayPtr <- {# call unsafe tree_path_get_indices #} tp + if (depth==0 || arrayPtr==nullPtr) + then return [] + else liftM (map fromIntegral) $ peekArray depth arrayPtr + +-- | Convert the given pointer to a tree path. +peekTreePath :: Ptr NativeTreePath -> IO TreePath +peekTreePath tpPtr | tpPtr==nullPtr = return [] + | otherwise = + nativeTreePathGetIndices (NativeTreePath tpPtr) + +-- | Convert the given pointer to a tree path. Frees the pointer. +fromTreePath :: Ptr NativeTreePath -> IO TreePath +fromTreePath tpPtr | tpPtr==nullPtr = return [] + | otherwise = do + path <- nativeTreePathGetIndices (NativeTreePath tpPtr) + nativeTreePathFree (NativeTreePath tpPtr) + return path + +-- | Convert a comma or colon separated string into a 'TreePath'. Any +-- non-digit characters are assumed to separate indices, thus, the function +-- always is always successful. +stringToTreePath :: String -> TreePath +stringToTreePath "" = [] +stringToTreePath path = getNum 0 (dropWhile (not . isDigit) path) + where + getNum acc ('0':xs) = getNum (10*acc) xs + getNum acc ('1':xs) = getNum (10*acc+1) xs + getNum acc ('2':xs) = getNum (10*acc+2) xs + getNum acc ('3':xs) = getNum (10*acc+3) xs + getNum acc ('4':xs) = getNum (10*acc+4) xs + getNum acc ('5':xs) = getNum (10*acc+5) xs + getNum acc ('6':xs) = getNum (10*acc+6) xs + getNum acc ('7':xs) = getNum (10*acc+7) xs + getNum acc ('8':xs) = getNum (10*acc+8) xs + getNum acc ('9':xs) = getNum (10*acc+9) xs + getNum acc xs = acc:stringToTreePath (dropWhile (not . isDigit) xs) hunk ./gtk/Graphics/UI/Gtk/TreeList/TreeModel.chs.pp 98 - TreeRowReference, hunk ./gtk/Graphics/UI/Gtk/TreeList/TreeModel.chs.pp 105 - treeRowReferenceNew, - treeRowReferenceGetPath, - treeRowReferenceValid, hunk ./gtk/Graphics/UI/Gtk/TreeList/TreeModel.chs.pp 129 -{#import Graphics.UI.Gtk.TreeList.TreeRowReference#} hunk ./tools/callbackGen/gtkmarshal.list 58 -#VOID:BOXED,BOXED,POINTER +VOID:BOXED,BOXED,POINTER |