<!-- ##### SECTION Title ##### -->
GtkListStore

<!-- ##### SECTION Short_Description ##### -->
A list-like data structure that can be used with the GtkTreeView

<!-- ##### SECTION Long_Description ##### -->
<para>
The #GtkListStore object is a list model for use with a #GtkTreeView
widget.  It implements the #GtkTreeModel interface, and consequentialy,
can use all of the methods available there.  It also implements the
#GtkTreeSortable interface so it can be sorted by the view.
Finally, it also implements the tree <link linkend="gtktreednd">drag and
drop</link> interfaces.
</para>

<para>
The #GtkListStore can accept most GObject types as a column type, though
it can't accept all custom types.  Internally, it will keep a copy of
data passed in (such as a string or a boxed pointer).  Columns that
accept #GObject<!-- -->s are handled a little differently.  The
#GtkListStore will keep a reference to the object instead of copying the
value.  As a result, if the object is modified, it is up to the
application writer to call @gtk_tree_model_row_changed to emit the
"row_changed" signal.  This most commonly affects lists with
#GdkPixbuf<!-- -->s stored.
</para>

<example>
<title>Creating a simple list store.</title>
<programlisting>
enum {
  COLUMN_STRING,
  COLUMN_INT,
  COLUMN_BOOLEAN,
  N_COLUMNS
};

{
  GtkListStore *list_store;
  GtkTreePath *path;
  GtkTreeIter iter;
  gint i;

  list_store = gtk_list_store_new (N_COLUMNS,
                                   G_TYPE_STRING,
                                   G_TYPE_INT,
                                   G_TYPE_BOOLEAN);

  for (i = 0; i &lt; 10; i++)
    {
      gchar *some_data;

      some_data = get_some_data (i);

      /* Add a new row to the model */
      gtk_list_store_append (list_store, &amp;iter);
      gtk_list_store_set (list_store, &amp;iter,
                          COLUMN_STRING, some_data,
                          COLUMN_INT, i,
                          COLUMN_BOOLEAN,  FALSE,
                          -1);

      /* As the store will keep a copy of the string internally, we
       * free some_data.
       */
      g_free (some_data);
    }

  /* Modify a particular row */
  path = gtk_tree_path_new_from_string ("4");
  gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store),
                           &amp;iter,
                           path);
  gtk_tree_path_free (path);
  gtk_list_store_set (list_store, &amp;iter,
                      COLUMN_BOOLEAN, TRUE,
                      -1);
}
</programlisting>
</example>

<refsect2>
<title>Performance Considerations</title>
<para>
Internally, the #GtkListStore was implemented with a linked list with a
tail pointer prior to GTK+ 2.6.  As a result, it was fast at data
insertion and deletion, and not fast at random data access.  The
#GtkListStore sets the #GTK_TREE_MODEL_ITERS_PERSIST flag, which means
that #GtkTreeIter<!-- -->s can be cached while the row exists.  Thus, if
access to a particular row is needed often and your code is expected to
run on older versions of GTK+, it is worth keeping the iter around.
</para>
<title>Atomic Operations</title>
<para>
It is important to note that only the methods 
gtk_list_store_insert_with_values() and gtk_list_store_insert_with_valuesv() 
are atomic, in the sense that the row is being appended to the store and the 
values filled in in a single operation with regard to #GtkTreeModel signaling.
In contrast, using e.g. gtk_list_store_append() and then gtk_list_store_set() 
will first create a row, which triggers the #GtkTreeModel::row-inserted signal 
on #GtkListStore. The row, however, is still empty, and any signal handler 
connecting to "row-inserted" on this particular store should be prepared
for the situation that the row might be empty. This is especially important 
if you are wrapping the #GtkListStore inside a #GtkTreeModelFilter and are
using a #GtkTreeModelFilterVisibleFunc. Using any of the non-atomic operations 
to append rows to the #GtkListStore will cause the 
#GtkTreeModelFilterVisibleFunc to be visited with an empty row first; the 
function must be prepared for that.
</para>
</refsect2>
<refsect2 id="GtkListStore-BUILDER-UI">
<title>GtkListStore as GtkBuildable</title>
<para>
The GtkListStore implementation of the GtkBuildable interface allows
to specify the model columns with a &lt;columns&gt; element that may
contain multiple &lt;column&gt; elements, each specifying one model
column. The "type" attribute specifies the data type for the column.
</para>
<para>
Additionally, it is possible to specify content for the list store
in the UI definition, with the &lt;data&gt; element. It can contain
multiple &lt;row&gt; elements, each specifying to content for one
row of the list model. Inside a &lt;row&gt;, the &lt;col&gt; elements
specify the content for individual cells.
</para>
<para>
Note that it is probably more common to define your models 
in the code, and one might consider it a layering violation 
to specify the content of a list store in a UI definition,
<emphasis>data</emphasis>, not <emphasis>presentation</emphasis>, 
and common wisdom is to separate the two, as far as possible. 
<!-- FIXME a bit inconclusive -->
</para>
<example>
<title>A UI Definition fragment for a list store</title>
<programlisting><![CDATA[
<object class="GtkListStore">
  <columns>
    <column type="gchararray"/>
    <column type="gchararray"/>
    <column type="gint"/>
  </columns>
  <data>
    <row>
      <col id="0">John</col>
      <col id="1">Doe</col>
      <col id="2">25</col>
    </row>
    <row>
      <col id="0">Johan</col>
      <col id="1">Dahlin</col>
      <col id="2">50</col>
    </row>
  </data>
</object>
]]></programlisting>
</example>
</refsect2>

<!-- ##### SECTION See_Also ##### -->
<para>
#GtkTreeModel, #GtkTreeStore
</para>

<!-- ##### SECTION Stability_Level ##### -->


<!-- ##### SECTION Image ##### -->


<!-- ##### STRUCT GtkListStore ##### -->
<para>

</para>


<!-- ##### FUNCTION gtk_list_store_new ##### -->
<para>

</para>

@n_columns: 
@...: 
@Returns: 


<!-- ##### FUNCTION gtk_list_store_newv ##### -->
<para>

</para>

@n_columns: 
@types: 
@Returns: 


<!-- ##### FUNCTION gtk_list_store_set_column_types ##### -->
<para>

</para>

@list_store: 
@n_columns: 
@types: 


<!-- ##### FUNCTION gtk_list_store_set ##### -->
<para>

</para>

@list_store: 
@iter: 
@...: 


<!-- ##### FUNCTION gtk_list_store_set_valist ##### -->
<para>

</para>

@list_store: 
@iter: 
@var_args: 


<!-- ##### FUNCTION gtk_list_store_set_value ##### -->
<para>

</para>

@list_store: 
@iter: 
@column: 
@value: 


<!-- ##### FUNCTION gtk_list_store_set_valuesv ##### -->
<para>

</para>

@list_store: 
@iter: 
@columns: 
@values: 
@n_values: 


<!-- ##### FUNCTION gtk_list_store_remove ##### -->
<para>

</para>

@list_store: 
@iter: 
@Returns: 


<!-- ##### FUNCTION gtk_list_store_insert ##### -->
<para>

</para>

@list_store: 
@iter: 
@position: 


<!-- ##### FUNCTION gtk_list_store_insert_before ##### -->
<para>

</para>

@list_store: 
@iter: 
@sibling: 


<!-- ##### FUNCTION gtk_list_store_insert_after ##### -->
<para>

</para>

@list_store: 
@iter: 
@sibling: 


<!-- ##### FUNCTION gtk_list_store_insert_with_values ##### -->
<para>

</para>

@list_store: 
@iter: 
@position: 
@...: 


<!-- ##### FUNCTION gtk_list_store_insert_with_valuesv ##### -->
<para>

</para>

@list_store: 
@iter: 
@position: 
@columns: 
@values: 
@n_values: 


<!-- ##### FUNCTION gtk_list_store_prepend ##### -->
<para>

</para>

@list_store: 
@iter: 


<!-- ##### FUNCTION gtk_list_store_append ##### -->
<para>

</para>

@list_store: 
@iter: 


<!-- ##### FUNCTION gtk_list_store_clear ##### -->
<para>

</para>

@list_store: 


<!-- ##### FUNCTION gtk_list_store_iter_is_valid ##### -->
<para>

</para>

@list_store: 
@iter: 
@Returns: 


<!-- ##### FUNCTION gtk_list_store_reorder ##### -->
<para>

</para>

@store: 
@new_order: 


<!-- ##### FUNCTION gtk_list_store_swap ##### -->
<para>

</para>

@store: 
@a: 
@b: 


<!-- ##### FUNCTION gtk_list_store_move_before ##### -->
<para>

</para>

@store: 
@iter: 
@position: 


<!-- ##### FUNCTION gtk_list_store_move_after ##### -->
<para>

</para>

@store: 
@iter: 
@position: 


