Gtk2::Ex::TreeOfTreesModel -- concatenated list models
use Gtk2::Ex::TreeOfTreesModel; my $model = Gtk2::Ex::TreeOfTreesModel->new (models => [$m1,$m2]);
Gtk2::Ex::TreeOfTreesModel is a subclass of Glib::Object.
Gtk2::Ex::TreeOfTreesModel
Glib::Object
Glib::Object Gtk2::Ex::TreeOfTreesModel
and implements the interfaces
Gtk2::TreeModel Gtk2::TreeDragSource Gtk2::TreeDragDest
Gtk2::Ex::TreeOfTreesModel 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 too.
Gtk2::ListStore
Changes in the sub-models are reported up through the Concat with the usual row-changed etc signals. Conversely change methods are implemented by 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.
row-changed
The sub-models should all have the same number of columns and the same column types (or compatible types), though currently TreeOfTreesModel 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).
TreeOfTreesModel implements TreeDragSource and TreeDragDest, allowing rows to be moved by dragging in a Gtk2::TreeView or similar.
Gtk2::TreeView
A row can be dragged if its sub-model implements the TreeDragSource interface. A position can be a drag destination if its sub-model implements either the TreeDragDest interface or a Gtk2::ListStore style insert_with_values method. TreeDragDest is preferred, letting the submodel take care of data conversion, but the insert_with_values fallback is needed for drags between different ListStores, since its TreeDragDest only accepts its own rows.
insert_with_values
models
[]
Arrayref of sub-models to concatenate. The sub-models can be any object implementing the Gtk2::TreeModel interface. They should be list-only type, though currently TreeOfTreesModel doesn't enforce that.
Gtk2::TreeModel
list-only
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.
row-inserted
row-deleted
$concat = Gtk2::Ex::TreeOfTreesModel->new (key=>value,...)
Create and return a new Concat object. Optional key/value pairs set initial properties as per Glib::Object->new. Eg.
Glib::Object->new
my $concat = Gtk2::Ex::TreeOfTreesModel->new (models => [$m1,$m2]);
The following functions are implemented in 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_types
These are applied to all sub-models, so clear clears all the models or set_column_types sets the types in all the models.
clear
set_column_types
In the current implementation Concat doesn't keep column types itself, but asks the sub-models when required (using the first sub-model, curently).
$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->prepend
bool = $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 in Glib::Object which normally sets object properties. You can use the set_property alias instead.
set
set_property
$model->set_property ('propname' => $value);
The TreeModel interface (implemented by TreeOfTreesModel) 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 TreeOfTreesModel is list-only, the path to row-changed, row-inserted and row-deleted always has depth 1, and the path to rows-reordered is always depth 0 and the iter there is always undef.
rows-reordered
undef
When a change occurs in a sub-model the corresponding signal is reported up through Concat too. Of course the path and iter reported by the Concat are in its "concatenated" coordinates and iters, not the sub-model's.
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.
ref_node
unref_node
It mostly works to have a sub-model appear more than once in a Concat. The only outright bug is in the remove method which doesn't update its iter correctly when removing a row from a second or subsequent copy of a submodel. The row-deleted and row-inserted signals are 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 might confuse handler code. (The idea could be some sort of temporary index mapping to make the changes seem one-at-a-time for the handlers.)
remove
What does work fine is to have multiple TreeModelFilters 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 location is.
Gtk2::TreeModel, Gtk2::TreeDragSource, Gtk2::TreeDragDest, Gtk2::ListStore, Glib::Object
http://user42.tuxfamily.org/gtk2-ex-listmodelconcat/index.html
Copyright 2008, 2009, 2010, 2011, 2015 Kevin Ryde
Chart 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.
Chart 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 Chart. If not, see http://www.gnu.org/licenses/.
To install App::Chart, copy and paste the appropriate command in to your terminal.
cpanm
cpanm App::Chart
CPAN shell
perl -MCPAN -e shell install App::Chart
For more information on module installation, please visit the detailed CPAN module installation guide.