1. ----------------------------------------------------------------------- 
  2. --              GtkAda - Ada95 binding for Gtk+/Gnome                -- 
  3. --                                                                   -- 
  4. --                Copyright (C) 2006 AdaCore                         -- 
  5. --                                                                   -- 
  6. -- This library is free software; you can redistribute it and/or     -- 
  7. -- modify it under the terms of the GNU General Public               -- 
  8. -- License as published by the Free Software Foundation; either      -- 
  9. -- version 2 of the License, or (at your option) any later version.  -- 
  10. --                                                                   -- 
  11. -- This library is distributed in the hope that it will be useful,   -- 
  12. -- but WITHOUT ANY WARRANTY; without even the implied warranty of    -- 
  13. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -- 
  14. -- General Public License for more details.                          -- 
  15. --                                                                   -- 
  16. -- You should have received a copy of the GNU General Public         -- 
  17. -- License along with this library; if not, write to the             -- 
  18. -- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      -- 
  19. -- Boston, MA 02111-1307, USA.                                       -- 
  20. --                                                                   -- 
  21. -- As a special exception, if other files instantiate generics from  -- 
  22. -- this unit, or you link this unit with other files to produce an   -- 
  23. -- executable, this  unit  does not  by itself cause  the resulting  -- 
  24. -- executable to be covered by the GNU General Public License. This  -- 
  25. -- exception does not however invalidate any other reasons why the   -- 
  26. -- executable file  might be covered by the  GNU Public License.     -- 
  27. ----------------------------------------------------------------------- 
  28.  
  29. --  <description> 
  30. --  A Gtk_Tree_Model_Filter is a tree model which wraps another tree model, and 
  31. --  can do the following things: 
  32. -- 
  33. --  - Filter specific rows, based on data from a "visible column", a column 
  34. --    storing booleans indicating whether the row should be filtered or not, or 
  35. --    based on the return value of a "visible function", which gets a model, 
  36. --    iter and user_data and returns a boolean indicating whether the row 
  37. --    should be filtered or not. 
  38. -- 
  39. --  - Modify the "appearance" of the model, using a modify function. This is 
  40. --    extremely powerful and allows for just changing some values and also for 
  41. --    creating a completely different model based on the given child model. 
  42. -- 
  43. --  - Set a different root node, also known as a "virtual root". You can pass 
  44. --    in a Gtk_Tree_Path indicating the root node for the filter at 
  45. --    construction time. 
  46. --  </description> 
  47. --  <c_version>2.8.17</c_version> 
  48. --  <group>Trees and Lists</group> 
  49. --  <testgtk>create_tree_filter.adb</testgtk> 
  50.  
  51. with Glib.Types; 
  52. with Glib.Values; 
  53. with Gtk.Tree_Dnd; 
  54. with Gtk.Tree_Model; 
  55.  
  56. package Gtk.Tree_Model_Filter is 
  57.    type Gtk_Tree_Model_Filter_Record is 
  58.      new Gtk.Tree_Model.Gtk_Tree_Model_Record with null record; 
  59.    type Gtk_Tree_Model_Filter is access all Gtk_Tree_Model_Filter_Record'Class; 
  60.  
  61.    procedure Gtk_New 
  62.      (Model       : out Gtk_Tree_Model_Filter; 
  63.       Child_Model : access Gtk.Tree_Model.Gtk_Tree_Model_Record'Class; 
  64.       Root        : Gtk.Tree_Model.Gtk_Tree_Path := null); 
  65.    procedure Initialize 
  66.      (Model       : access Gtk_Tree_Model_Filter_Record'Class; 
  67.       Child_Model : access Gtk.Tree_Model.Gtk_Tree_Model_Record'Class; 
  68.       Root        : Gtk.Tree_Model.Gtk_Tree_Path := null); 
  69.    --  Creates a new tree model, with Child_Model as the child_model 
  70.    --  and Root as the virtual root (or the same root as Child_Model by 
  71.    --  default). 
  72.  
  73.    function Get_Type return Glib.GType; 
  74.    --  Returns the internal type used for a Gtk_Tree_Model_Filter 
  75.  
  76.    ----------------- 
  77.    -- Child model -- 
  78.    ----------------- 
  79.    --  The tree model filter wraps another model, and offers functions to 
  80.    --  convert from one to the other. Generally speaking, you can change data 
  81.    --  on either of the two models, and these changes will be reflected 
  82.    --  graphically automatically. 
  83.  
  84.    function Get_Model 
  85.      (Filter : access Gtk_Tree_Model_Filter_Record) 
  86.       return Gtk.Tree_Model.Gtk_Tree_Model; 
  87.    --  Returns a pointer to the child model of Filter. 
  88.  
  89.    procedure Convert_Child_Iter_To_Iter 
  90.      (Filter      : access Gtk_Tree_Model_Filter_Record; 
  91.       Filter_Iter : out Gtk.Tree_Model.Gtk_Tree_Iter; 
  92.       Child_Iter  : Gtk.Tree_Model.Gtk_Tree_Iter); 
  93.    --  Sets Filter_Iter to point to the row in Filter that corresponds to the 
  94.    --  row pointed at by Child_Iter. 
  95.  
  96.    function Convert_Child_Path_To_Path 
  97.      (Filter     : access Gtk_Tree_Model_Filter_Record; 
  98.       Child_Path : Gtk.Tree_Model.Gtk_Tree_Path) 
  99.       return Gtk.Tree_Model.Gtk_Tree_Path; 
  100.    --  Converts Child_Path to a path relative to Filter. That is, Child_Path 
  101.    --  points to a path in the child model. The returned path will point to the 
  102.    --  same row in the filtered model. If Child_Path isn't a valid path on the 
  103.    --  child model, then null is returned. 
  104.    --  The returned value must be freed with Path_Free. 
  105.  
  106.    procedure Convert_Iter_To_Child_Iter 
  107.      (Filter      : access Gtk_Tree_Model_Filter_Record; 
  108.       Child_Iter  : out Gtk.Tree_Model.Gtk_Tree_Iter; 
  109.       Filter_Iter : Gtk.Tree_Model.Gtk_Tree_Iter); 
  110.    --  Sets Child_Iter to point to the row pointed to by Filter_Iter. 
  111.  
  112.    function Convert_Path_To_Child_Path 
  113.      (Filter      : access Gtk_Tree_Model_Filter_Record; 
  114.       Filter_Path : Gtk.Tree_Model.Gtk_Tree_Path) 
  115.       return Gtk.Tree_Model.Gtk_Tree_Path; 
  116.    --  Converts Filter_Path to a path on the child model of Filter. That is, 
  117.    --  Filter_Path points to a location in Filter. The returned path will point 
  118.    --  to the same location in the model not being filtered. If Filter_Path 
  119.    --  does not point to a location in the child model, null is returned. 
  120.    --  The returned value must be freed with Path_Free. 
  121.  
  122.    -------------------------- 
  123.    --  Changing visibility -- 
  124.    -------------------------- 
  125.    --  One of the capabilities of a Gtk_Tree_Model_Filter is to hide some of 
  126.    --  the rows of its child model, so that they are not visible on the screen. 
  127.  
  128.    procedure Set_Visible_Column 
  129.      (Filter : access Gtk_Tree_Model_Filter_Record; Column : Gint); 
  130.    --  Sets Column of the child_model to be the column where Filter should 
  131.    --  look for visibility information. Columns should be a column of type 
  132.    --  GType_Boolean, where True means that a row is visible, and False 
  133.    --  if not. 
  134.  
  135.    type Gtk_Tree_Model_Filter_Visible_Func is access function 
  136.      (Model : access Gtk.Tree_Model.Gtk_Tree_Model_Record'Class; 
  137.       Iter  : Gtk.Tree_Model.Gtk_Tree_Iter) return Boolean; 
  138.    --  Called for each row in the model to decide whether or not it should be 
  139.    --  visible. True indicates the row should be made visible. 
  140.    --  Model is the child model, and Iter points into it. 
  141.  
  142.    procedure Set_Visible_Func 
  143.      (Filter  : access Gtk_Tree_Model_Filter_Record; 
  144.       Func    : Gtk_Tree_Model_Filter_Visible_Func); 
  145.    --  Sets the visible function used when filtering the Filter to be Func. The 
  146.    --  function should return True if the given row should be visible and False 
  147.    --  otherwise. 
  148.    --  If the condition calculated by the function changes over time (e.g. 
  149.    --  because it depends on some global parameters), you must call Refilter to 
  150.    --  keep the visibility information of the model uptodate. 
  151.  
  152.    generic 
  153.       type Data_Type (<>) is private; 
  154.    package Visible_Funcs is 
  155.       type Gtk_Tree_Model_Filter_Visible_Func is access function 
  156.         (Model : access Gtk.Tree_Model.Gtk_Tree_Model_Record'Class; 
  157.          Iter  : Gtk.Tree_Model.Gtk_Tree_Iter; 
  158.          Data  : Data_Type) return Boolean; 
  159.  
  160.       type Destroy_Notify is access procedure (Data : in out Data_Type); 
  161.       --  Destroys the memory allocated for Data 
  162.  
  163.       procedure Set_Visible_Func 
  164.         (Filter  : access Gtk_Tree_Model_Filter_Record'Class; 
  165.          Func    : Gtk_Tree_Model_Filter_Visible_Func; 
  166.          Data    : Data_Type; 
  167.          Destroy : Destroy_Notify := null); 
  168.       --  Same as above, but the application can pass addition data to the 
  169.       --  function 
  170.  
  171.    private 
  172.       --  <doc_ignore> 
  173.       type Data_Type_Access is access Data_Type; 
  174.       type Data_Type_Record is record 
  175.          Func    : Gtk_Tree_Model_Filter_Visible_Func; 
  176.          Destroy : Destroy_Notify; 
  177.          Data    : Data_Type_Access; 
  178.       end record; 
  179.       type Data_Type_Record_Access is access Data_Type_Record; 
  180.       pragma Convention (C, Data_Type_Record_Access); 
  181.  
  182.       procedure Internal_Destroy_Notify (Data : Data_Type_Record_Access); 
  183.       pragma Convention (C, Internal_Destroy_Notify); 
  184.  
  185.       function Internal_Filter_Visible_Func 
  186.         (Model : System.Address; 
  187.          Iter  : System.Address; 
  188.          Data  : Data_Type_Record_Access) return Gboolean; 
  189.       pragma Convention (C, Internal_Filter_Visible_Func); 
  190.  
  191.       --  </doc_ignore> 
  192.    end Visible_Funcs; 
  193.  
  194.    procedure Refilter (Filter : access Gtk_Tree_Model_Filter_Record); 
  195.    --  Emits row_changed for each row in the child model, which causes 
  196.    --  the filter to re-evaluate whether a row is visible or not. 
  197.  
  198.    -------------------------------- 
  199.    -- Modifying displayed values -- 
  200.    -------------------------------- 
  201.    --  The other capability of a Gtk_Tree_Model_Filter is to modify on the fly 
  202.    --  the displayed value (ie we do not display directly what is in the child 
  203.    --  model, but change the value in memory, not in the model, on the fly) 
  204.  
  205.    type Gtk_Tree_Model_Filter_Modify_Func is access procedure 
  206.      (Model  : access Gtk_Tree_Model_Filter_Record'Class; 
  207.       Iter   : Gtk.Tree_Model.Gtk_Tree_Iter; 
  208.       Value  : out Glib.Values.GValue; 
  209.       Column : Gint); 
  210.    --  A function which calculates display values from raw values in the model. 
  211.    --  It must fill value with the display value for the column column in the 
  212.    --  row indicated by iter. 
  213.    --  Since this function is called for each data access, it's not a 
  214.    --  particularly efficient operation. 
  215.    --  Value has already been initializes to the right type (ie the one defined 
  216.    --  in Set_Modify_Func for this column). Iter references the filter model, 
  217.    --  not the child model. When implementating this procedure, make sure you 
  218.    --  do not call Get_String, Get_Int,... on Model itself, since that would 
  219.    --  create a recursion. You must apply all operations to Get_Model (Model), 
  220.    --  after converting Iter to a Child_Iter through Convert_Iter_To_Child_Iter 
  221.  
  222.    procedure Set_Modify_Func 
  223.      (Filter    : access Gtk_Tree_Model_Filter_Record; 
  224.       Types     : Glib.GType_Array; 
  225.       Func      : Gtk_Tree_Model_Filter_Modify_Func); 
  226.    --  Types can be used to override the column types that will be made visible 
  227.    --  to the parent model/view. 
  228.    --  Func is used to specify the modify function. The modify function will 
  229.    --  get called for *each* data access, the goal of the modify function is to 
  230.    --  return the data which should be displayed at the location specified 
  231.    --  using the parameters of the modify function. 
  232.  
  233.    generic 
  234.       type Data_Type (<>) is private; 
  235.    package Modify_Funcs is 
  236.       type Gtk_Tree_Model_Filter_Modify_Func is access procedure 
  237.         (Model     : access Gtk_Tree_Model_Filter_Record'Class; 
  238.          Iter      : Gtk.Tree_Model.Gtk_Tree_Iter; 
  239.          Value     : out Glib.Values.GValue; 
  240.          Column    : Gint; 
  241.          User_Data : Data_Type); 
  242.  
  243.       type Destroy_Notify is access procedure (Data : in out Data_Type); 
  244.       --  Destroys the memory allocated for Data 
  245.  
  246.       procedure Set_Modify_Func 
  247.         (Filter    : access Gtk_Tree_Model_Filter_Record'Class; 
  248.          Types     : Glib.GType_Array; 
  249.          Func      : Gtk_Tree_Model_Filter_Modify_Func; 
  250.          Data      : Data_Type; 
  251.          Destroy   : Destroy_Notify := null); 
  252.       --  Same as above, but the application can pass extra data to the 
  253.       --  function. 
  254.  
  255.    private 
  256.       --  <doc_ignore> 
  257.       type Data_Type_Access is access Data_Type; 
  258.       type Data_Type_Record is record 
  259.          Func    : Gtk_Tree_Model_Filter_Modify_Func; 
  260.          Destroy : Destroy_Notify; 
  261.          Data    : Data_Type_Access; 
  262.       end record; 
  263.       type Data_Type_Record_Access is access Data_Type_Record; 
  264.       pragma Convention (C, Data_Type_Record_Access); 
  265.  
  266.       procedure Internal_Destroy_Notify (Data : Data_Type_Record_Access); 
  267.       pragma Convention (C, Internal_Destroy_Notify); 
  268.  
  269.       procedure Internal_Filter_Modify_Func 
  270.         (Model  : System.Address; 
  271.          Iter   : System.Address; 
  272.          Value  : out Glib.Values.GValue; 
  273.          Column : Gint; 
  274.          Data   : Data_Type_Record_Access); 
  275.       pragma Convention (C, Internal_Filter_Modify_Func); 
  276.       --  </doc_ignore> 
  277.    end Modify_Funcs; 
  278.  
  279.    ---------- 
  280.    -- Misc -- 
  281.    ---------- 
  282.  
  283.    procedure Clear_Cache (Filter : access Gtk_Tree_Model_Filter_Record); 
  284.    --  This function should almost never be called. It clears the Filter of any 
  285.    --  cached iterators that haven't been reffed with Gtk.Tree_Model.Ref_Node. 
  286.    --  This might be useful if the child model being filtered is static (and 
  287.    --  doesn't change often) and there has been a lot of unreffed access to 
  288.    --  nodes. As a side effect of this function, all unrefed iters will be 
  289.    --  invalid. 
  290.  
  291.    ---------------- 
  292.    -- Interfaces -- 
  293.    ---------------- 
  294.    --  This class implements several interfaces. See Glib.Types 
  295.    -- 
  296.    --  - "Gtk_Tree_Drag_Source" 
  297.    --    This interface allows this widget to act as a dnd source 
  298.  
  299.    package Implements_Drag_Source is new Glib.Types.Implements 
  300.      (Gtk.Tree_Dnd.Gtk_Tree_Drag_Source, 
  301.       Gtk_Tree_Model_Filter_Record, 
  302.       Gtk_Tree_Model_Filter); 
  303.    function "+" 
  304.      (Model : access Gtk_Tree_Model_Filter_Record'Class) 
  305.       return Gtk.Tree_Dnd.Gtk_Tree_Drag_Source 
  306.       renames Implements_Drag_Source.To_Interface; 
  307.    function "-" 
  308.      (Drag_Source : Gtk.Tree_Dnd.Gtk_Tree_Drag_Source) 
  309.       return Gtk_Tree_Model_Filter 
  310.       renames Implements_Drag_Source.To_Object; 
  311.    --  Converts to and from the Gtk_Tree_Drag_Source interface 
  312.  
  313. private 
  314.    pragma Import (C, Get_Type, "gtk_tree_model_filter_get_type"); 
  315. end Gtk.Tree_Model_Filter;