rendered paste body<?phperror_reporting(E_ALL);/** * * Marc Quinton - 2006 december. * * PhpGtkCustomTreeModel sample examples ; * * PhpGtkCustomTreeModel implements a customisable GtkTreeView model. * * a good tutorial about this in python : * http://www.moeraki.com/pygtktutorial/pygtk2tutorial/sec-GenericTreeModel.html * * * here is a list of available methods for PhpGtkCustomTreeModel : * * on_get_flags(); * on_get_n_columns(); * on_get_column_type($index); * on_get_path($node); * on_get_iter($path); * on_iter_children($iter); * on_iter_has_child($iter); * on_iter_n_children($iter); * on_iter_nth_child($iter, $n); * on_iter_parent($iter); * on_get_value($iter, $colum); * on_iter_next($iter) * * * * this file contains : * * - TreeIter - a basic iterator class for Trees * - FlatTextModel - implements all methods needed for a flat list textual model (based on Andrei example) * - FlatTextRandomListModel - generate a list of random numbers * - FlatTextArrayModel - give an array list in contructor to build model * - CrazyFlatTextRandomListModel - a really random list model * - OrderedListModel - an ordered list * - ReverseOrderedListModel - some model in reverse ordered * * class hierarchy tree : * * PhpGtkCustomTreeModel * FlatTextModel * FlatTextRandomListModel * FlatTextRandomListModel * FlatTextArrayModel * CrazyFlatTextRandomListModel * OrderedListModel * ReverseOrderedListModel * * TODO : work on non-flats models. * */class TreeIter { public $idx = null; public $array = null; public $path = null; private $value = null; public $keys = null; public $parent_iter = null;}/** * an abtract class that implements basic methods for a flat (text) list. * */class TreeModel extends PhpGtkCustomTreeModel{ protected $iters = null; protected $debug; protected $model; protected $external_model; function __construct($external_model) { parent::__construct(); $this->debug=true; $this->model = null; $this->external_model = $external_model; $this->model = $this->model_convert($external_model); $this->iters = array(); } public function on_get_value($iter, $n){ $this->debug("on_get_value (" . $this->path_to_key($iter->path) . ", $n)\n"); if($iter == null){ echo "iter is null : this : " ; print_r($this); die ("error here ! iter should not be null here"); # return 'null'; } if(!is_array($iter->array)){ echo "this : " ; print_r($this); die ("error here ! iter->array should be an array"); } # should not come here ... (don't know howto) if(count($iter->array) == 0) return 'empty'; $key = $iter->keys[$iter->idx]; if(!is_array($iter->array[$key])) $val = $iter->array[$key]; else $val = $key; $this->debug("on_get_value($n, {$iter->idx}, $key, $val)\n"); return $val; } public function on_iter_next($iter){ $this->debug("on_iter_next {$iter->idx}\n"); if(count($iter->array) == 0) return null; if($iter->idx == count($iter->keys)-1) return null; $iter->idx++; return $iter; } # can handle only List feature. public function on_get_flags() { $this->debug("on_get_flags\n"); return 0; } # number of colums. public function on_get_n_columns() { $this->debug("on_get_n_columns\n"); return 1; } # only one column of type string. public function on_get_column_type($index) { $this->debug("on_get_column_type\n"); return Gtk::TYPE_STRING; } public function on_get_path($iter) { $this->debug("on_get_path\n"); print_r($this); die("to be done\n"); return $node; } # flat list public function on_get_iter($path) { $parent_path_key = $this->path_to_key($this->path_parent($path)); $this->debug("on_get_iter(" . $this->path_to_key($path) . ", $parent_path_key)\n"); # echo "iters : " ; print_r($this->iters); if(count($path) == 1){ if(!isset($this->iters[$parent_path_key])){ # echo "on_get_iter() : new Iter - 1\n"; $this->iters[$parent_path_key] = new TreeIter(); $iter = $this->iters[$parent_path_key]; $iter->array = &$this->external_model; $iter->keys = array_keys($this->external_model); } $iter = $this->iters[$parent_path_key]; $key = $path[0]; $iter->idx = $key; $iter->path = $path; return $iter; } else { if(!isset($this->iters[$parent_path_key])){ # $parent_iter = $this->iters[$this->path_to_key($this->path_parent($this->path_parent($path)))]; $parent_iter = &$this->iters[$this->path_to_key($this->path_parent($this->path_parent($path)))]; $key = $path; $key = array_pop($key); # get last element of $path $this->iters[$parent_path_key] = new TreeIter(); $iter = $this->iters[$parent_path_key]; $iter->array = $parent_iter->array[$parent_iter->keys[$parent_iter->idx]]; $iter->keys = array_keys($iter->array); $iter->parent_iter = $parent_iter; # echo "on_get_iter() : new Iter - 2\n"; # echo "key = $key\n"; # echo "path = " . $this->path_to_key($path) . "\n"; # echo "parent_path_key = $parent_path_key\n"; # echo "parent_iter = " ; print_r($parent_iter); # echo "path : " ; print_r($path); # echo "new_iter : " ; print_r($iter); # echo "this : " ; print_r($this); # trigger_error("to be defined"); exit(0); } $key = $path; $key = array_pop($key); # get last element of $path $iter = $this->iters[$parent_path_key]; $iter->idx = $key; $iter->path=$path; return $iter; } } # flat list. public function on_iter_children($iter) { $this->debug("on_iter_children()\n"); # print_r($iter); if(count($iter->array) == 0) # empty array return null; $key = $iter->keys[$iter->idx]; if(!is_array($iter->array[$key])) return null; $new_iter = new TreeIter(); $key = $iter->keys[$iter->idx]; # echo "key = $key\n"; # $new_iter->keys = array_keys($iter->array[$key]); $new_iter->idx = 0; $new_iter->path = $iter->path; array_push($new_iter->path, 0); $new_iter->array = &$iter->array[$key]; $new_iter->keys = array_keys($new_iter->array); $new_iter->parent_iter = $iter; # print_r($new_iter); return $new_iter; } ## flat list. public function on_iter_has_child($iter) { $this->debug("on_iter_has_child()\n"); if($iter == null) return false; if(count($iter->array) == 0) return false; $key = $iter->keys[$iter->idx]; if(is_array($iter->array[$key])) $bool = true; else $bool = false; return $bool; /* if($iter == null) $bool = false; print_r($iter); $key = $iter->keys[$iter->idx]; if(is_array($iter->array[$key])) $bool = true; else $bool = false; $this->debug("on_iter_has_child({$iter->idx}) : $bool\n"); # print_r($iter); return $bool; */ } # flat list. public function on_iter_n_children($iter) { $this->debug("on_iter_n_child()\n"); die ("on_iter_n_children : to be done"); return 0; } # flat list. public function on_iter_nth_child($iter, $n) { $this->debug("on_iter_nth_child(), $n\n"); if($iter == null){ # echo "iter = null\n"; # echo "this = " ; print_r($this); $iter = $this->iters[':']; } # die ("on_iter_nth_children : to be done"); return $iter; } # flat list. public function on_iter_parent($iter) { $this->debug("on_iter_parent()\n"); # print_r($iter); return $iter->parent_iter; # return null; } protected function debug($txt){ if($this->debug) echo $txt; } protected function model_convert($array, $path=null){ $items = array(); if($path == null) $path = '0'; if(is_array($array)){ foreach($array as $key=>$val){ if(!is_array($val)){ $items[ "$path:$key" ] = $val; } else{ $sub_items = $this->model_convert($val, "$path:$key"); $items = array_merge($items, $sub_items); } } } return $items; } public function path_to_key($path){ if(count($path) == 0) return ':'; return ':' . join(':', $path); } public function key_to_path($key){ # remove heading ':' $key = substr($key, 1); if(strlen($key) == 0) return array(0); return split(':', $key); } public function path_parent($path){ array_pop($path); return $path; }}# $model2 = array(0,1,2,3,4, array(6,7,8,9), 11,12,13);# $model2 = array(0,1,2, 10 =>array(array()));# $model2 = array(0,1,2 => array(6,7,8,9 => array(11,12, 13=> array(20,21), 14=> array(30,31), 50),21,22),8,9);$model2 = array(0,1,2 => array(16,17,'error-here-when-select'), 8,9);# $model2 = array(0, 1, 2=>array(6,7));print_r($model2);$model = new TreeModel($model2);$w = new GtkWindow();$w->set_default_size(100, 250);$w->connect_simple('destroy', array('gtk', 'main_quit')); $sc = new GtkScrolledWindow(); $sc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $w->add($sc); $tree_view = new GtkTreeView($model); # $tree_view->expand_all(); $tree_view->expand_row(array(0), true); $cell = new GtkCellRendererText(); $col = new GtkTreeViewColumn("example", $cell, 'text', 0); $tree_view->append_column($col); $sc->add($tree_view); $w->show_all();gtk::main();?>