| Gtk2-Ex-ListModelConcat documentation | view source | Contained in the Gtk2-Ex-ListModelConcat distribution. |
$concat->clear$concat->set_column_types$iter = $concat->append$iter = $concat->insert ($pos)$iter = $concat->insert_with_values ($pos, $col,$val, ...)$iter = $concat->insert_after ($iter)$iter = $concat->insert_before ($iter)bool = $concat->iter_is_valid ($iter)$concat->move_after ($iter, $iter_from, $iter_to)$concat->move_before ($iter, $iter_from, $iter_to)$iter = $concat->prependbool = $concat->remove ($iter)$concat->reorder (@neworder)$concat->swap ($iter_a, $iter_b)$concat->set ($iter, $col,$val, ...)$concat->set_value ($iter, $col, $val)
Gtk2::Ex::ListModelConcat -- concatenated list models
use Gtk2::Ex::ListModelConcat; my $model = Gtk2::Ex::ListModelConcat->new (models => [$m1,$m2]);
Gtk2::Ex::ListModelConcat is a subclass of Glib::Object.
Glib::Object
Gtk2::Ex::ListModelConcat
and implements the interfaces
Gtk2::TreeModel
Gtk2::TreeDragSource
Gtk2::TreeDragDest
Gtk2::Ex::ListModelConcat presents a set of list type TreeModels
concatenated together as a single list. A Concat doesn't hold any data
itself, it just presents the sub-models' content. Gtk2::ListStore
objects are suitable as the sub-models, but any similar list-type model can
be used.
+--------+
/ row 0 | apple | row 0 \
/ +--------+ \
| row 1 | orange | row 1 | first child
| +--------+ /
| row 2 | lemon | row 2 /
| +--------+
Concat | row 3 | potato | row 0 \
| +--------+ \
| row 4 | carrot | row 1 |
| +--------+ | second child
| row 5 | squash | row 2 |
\ +--------+ /
\ row 6 | onion | row 3 /
+--------+
Changes in the sub-models are reported up through the Concat with the usual
row-changed etc signals. Conversely change methods are implemented by
the Concat in the style of Gtk2::ListStore and if the sub-models have
those functions too (eg. if they're ListStores) then changes on the Concat
are applied down to the sub-models.
The sub-models should have the same number of columns and the same column types (or compatible types), though currently ListModelConcat doesn't try to enforce that. It works to put one Concat inside another, except of course it cannot be inside itself (directly or indirectly).
ListModelConcat implements Gtk2::TreeDragSource and Gtk2::TreeDragDest
interfaces, allowing rows to be moved by dragging in Gtk2::TreeView or
similar. The actual operations are delegated to the submodels, so a row can
be dragged if the originating submodel is a TreeDragSource and a location is
a drop point if its submodel is a TreeDragDest.
It's worth noting the standard Gtk2::ListStore models only accept drops
of their own rows, ie. a re-ordering, not movement of rows between different
models. This is reasonable since different models might have different
natures, but you might want to subclass or use a wrapper for a more liberal
policy among compatible models.
models (array reference, default empty [])Arrayref of sub-models to present. The sub-models can be any object
implementing the Gtk2::TreeModel interface. They should be list-only
type, but currently ListModelConcat doesn't enforce that.
Currently when the models property is changed there's no row-inserted
/ row-deleted etc signals emitted by the Concat to announce the new or
altered data presented. Perhaps this will change. The disadvantage would
be that adding or removing a big model could generate thousands of fairly
pointless signals. The suggestion is to treat models as if it were
"construct-only" and make a new Concat for a new set of models.
append-model (Gtk2::TreeModel, write-only)A write-only pseudo-property which appends a model to the Concat, per the
append_model method below. This can be used to add models from a
Gtk2::Builder (see BUILDABLE below).
$concat = Gtk2::Ex::ListModelConcat->new (key=>value,...)Create and return a new Concat object. Optional key/value pairs set initial
properties per Glib::Object->new. Eg.
my $concat = Gtk2::Ex::ListModelConcat->new (models => [$m1,$m2]);
$concat->append_model ($model, ...)Append each given $model to those already in $concat. See
PROPERTIES above for an equivalent append-model property and notes on
signal emission.
The following functions follow the style of Gtk2::ListStore and they call
down to corresponding functions in the sub-models. Those sub-models don't
have to be Gtk2::ListStore objects, they can be some other class
implementing the same methods.
$concat->clear$concat->set_column_typesThese are applied to all sub-models, so clear clears all the models or
set_column_types sets the types in all the models.
In the current implementation Concat doesn't keep track of column types itself, but asks the sub-models when required (using the first sub-model, currently).
$iter = $concat->append$iter = $concat->insert ($pos)$iter = $concat->insert_with_values ($pos, $col,$val, ...)$iter = $concat->insert_after ($iter)$iter = $concat->insert_before ($iter)bool = $concat->iter_is_valid ($iter)$concat->move_after ($iter, $iter_from, $iter_to)$concat->move_before ($iter, $iter_from, $iter_to)$iter = $concat->prependbool = $concat->remove ($iter)$concat->reorder (@neworder)$concat->swap ($iter_a, $iter_b)$concat->set ($iter, $col,$val, ...)$concat->set_value ($iter, $col, $val)These are per the Gtk2::ListStore methods.
Note set overrides the set from Glib::Object which normally sets
object properties. You can use its set_property name instead.
$model->set_property ('propname' => $value);
As of Gtk2-Perl 1.200 set_value in Gtk2::ListStore is actually an
alias for set and so accepts multiple $col,$val pairs.
ListModelConcat passes all set_value arguments through to the sub-model
set_value (after converting the $iter), so it's up to it what should
work.
The following functions convert Concat iters to iters on the child model, or vice versa. They're similar to what TreeModelFilter offers (see Gtk2::TreeModelFilter), except that a particular child model is returned and must be specified since a Concat can have multiple children.
($childmodel, $childiter, $childnum) = $concat->convert_iter_to_child_iter ($iter)Convert a ListModelConcat iter to an iter on the child model corresponding to that row.
The return includes the $childnum which is an index into the models
property arrayref. If a child model appears more than once in the models
then this identifies which occurrence the $iter refers to. Often this is
of no interest and can be ignored.
my ($childmodel, $childiter)
= $concat->convert_iter_to_child_iter ($iter);
$childmodel->something($childiter) ...
$iter = $concat->convert_child_iter_to_iter ($childmodel, $childiter)$iter = $concat->convert_childnum_iter_to_iter ($childnum, $childiter)Convert an iter on one of the child models to an iter on the ListModelConcat.
The childnum func takes an index into the models list, counting from 0
for the first model. If you've got a child model appearing more than once
then this lets you identify which one you mean. The plain $childmodel
func gives the first occurrence of that model.
The TreeModel interface implemented by ListModelConcat provides the following usual signals
row-changed ($concat, $path, $iter, $userdata)
row-inserted ($concat, $path, $iter, $userdata)
row-deleted ($concat, $path, $userdata)
rows-reordered ($concat, $path, $iter, $arrayref, $userdata)
Because ListModelConcat is list-only, the path to row-changed,
row-inserted and row-deleted is always depth 1, and the path to
rows-reordered is always depth 0 and the iter there always undef.
When a change occurs in a sub-model the corresponding signal is reported up through Concat. The path and iter are of course reported up in the "concatenated" coordinates and iters, not the sub-model's.
ListModelConcat implements the Gtk2::Buildable interface of Gtk 2.12 and
up, allowing Gtk2::Builder to construct a Concat with child sub-model
objects. Sub-models can be added either through the append-model
pseudo-property for separately created model objects,
<object class="Gtk2__Ex__ListModelConcat" id="mylmc">
<property name="append-model">mysubmodel-one</property>
<property name="append-model">mysubmodel-two</property>
</object>
Or with <child> elements constructing sub-model objects at that
point,
<object class="Gtk2__Ex__ListModelConcat" id="mylmc">
<child>
<object class="GtkListStore" id="list1">
<columns><column type="gint"/></columns>
<data><row><col id="0">123</col></row></data>
</object>
</child>
</object>
The two styles are just a matter of whether you prefer to create the sub-models at the top-level and add to a Concat by name, or make them in the concat and refer to them elsewhere by name.
It's not a good idea to mix <child> and append-model since the
order among the different settings may not be preserved. As of Gtk 2.20 the
builder works by adding all <child> objects and then setting
properties a bit later, or something like that, so <child> objects
end up before append-model even if written the other way around.
See examples/builder-append.pl and examples/builder-children.pl in the ListModelConcat sources for complete sample programs.
ref_node and unref_node are no-ops. The intention is to apply them
down on the sub-models, but hopefully without needing lots of bookkeeping in
the Concat as to what's currently reffed.
It mostly works to have a sub-model appear more than once in a Concat. The
only real problem is with the row-deleted and row-inserted signals.
They're emitted on the Concat the right number of times, but the multiple
inserts/deletes are all present in the data as of the first emit, which
could confuse handler code. Perhaps some sort of temporary index mapping
could make the changes seem one-at-a-time, except the deleted row contents
have already gone.
What does work fine though is to have multiple TreeModelFilters (or similar) selecting different parts of a single underlying model. As long as a given row only appears once it doesn't matter where its ultimate storage is.
Gtk2::TreeModel, Gtk2::TreeDragSource, Gtk2::TreeDragDest, Gtk2::ListStore, Glib::Object
Copyright 2008, 2009, 2010 Kevin Ryde
Gtk2-Ex-ListModelConcat 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 3, or (at your option) any later version.
Gtk2-Ex-ListModelConcat 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.
You should have received a copy of the GNU General Public License along with Gtk2-Ex-ListModelConcat. If not, see http://www.gnu.org/licenses/.
| Gtk2-Ex-ListModelConcat documentation | view source | Contained in the Gtk2-Ex-ListModelConcat distribution. |