Newsgroup: it.comp.os.linux.development
Titolo: il treeview ha colpito di nuovo.

non so più cosa dire. Ongi volta che ci metto mano non riesco ad andarne
fuori....
Questa volta vorrei fare in modo che se premo un bottone "su" mi venga
spostata la riga selezionata in su di una riga. Attualmente h oquesto
codice:
/* pressione di su */
void
on_button5_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
  extern GtkWidget *window1;
  GtkTreeIter iter;
  GtkTreeModel *model;
  GtkTreeSelection *selection;
  GtkTreeView *tree;
  char *nome;
 
  tree = (GtkTreeView *) lookup_widget (window1, "treeview1");
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
 
  if (gtk_tree_selection_get_selected
      (selection, &model, (GtkTreeIter *) & iter))
    {
      model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
      gtk_tree_store_move_before (GTK_TREE_STORE (model), 
                                  (GtkTreeIter *) &iter, 
                                  (GtkTreeIter *) &iter);
    }
}
Questo codice non fa niente, se come secondo puntatore (GtkTreeIter *)
passo NULL per far spostare la riga in fondo crasha.
Come diavolo si fa?



Premetto che in le gtk non le ho mai usate in C.
1) ma quando usi "get_selected", non salvi il modello in model?
Quindi perche' all'interno dell'if la prima cosa che fai e' recuperarlo di
nuovo? (potrei sbagliarmi, ma mi sembra funzioni così)
2) Al posto di move_before potresti usare
gtk_tree_view_set_cursor
Ciao,
Riccardo
-- 
-=Riccardo Galli=-
 _,e.
s~  ``
 ~@.   ideralis Programs
.   ol 
 `**~  
http://www.sideralis.net

 gtk_tree_view_set_cursor
ma con quello non sposto solo la selezione, giusto?

 Come diavolo si fa?
Non gli puoi passare lo stesso iteratore per spostarlo all'indietro.
Devi usare due iteratori. Con move_before ottieni l'iteratore alla nuova
posizione, dentro cui metterai i dati del modello, togliendoli in
seguito dalla posizione precedente.
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)           [ 
http://digilander.libero.it/ebassi/
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

 ma con quello non sposto solo la selezione, giusto?
Ah, ma tu vuoi spostare la selezione o spostare la riga?
Se vuoi spostare la selezione, devi usare il metodo "set_selected" di
GtkTreeSelection:
	* hai l'iteratore della selezione corrente;
	* recuperi l'iteratore precedente;
	* selezioni l'iteratore recuperato.
In Python:
	selection = treeview.get_selection()
	model, iter = selection.get_selected()
	new_iter = model.move_before(iter)
	selection.set_selected(new_iter)


 seguito dalla posizione precedente.
cioè tolgo e rimetto? Non c'è una funzione che sposta?

 Ah, ma tu vuoi spostare la selezione o spostare la riga?
la riga con tutti i suoi dati.

 cioè tolgo e rimetto? Non c'è una funzione che sposta?
No, abbastanza ovviamente: come fai a sapere cosa spostare e dove?
Esiste un altro modo, benché non l'abbia mai provato: recupera la row
reference, e sposta quella da un punto ad un altro del modello.
Il reordering delle linee tramite drag and drop viene fatto così,
internamente.


 reference, e sposta quella da un punto ad un altro del modello.
Ho detto una cavolata: troppo Python[1].
Devi recuperare i dati dal modello, ottenere il nuovo iteratore[2],
copiarci dentro i dati e eliminare la vecchia riga. Fine.
+++
[1] L'interfaccia per accedere ai dati è decisamente
"developer-friendly":
	row = liststore[2]	# terza riga del modello
	data = row[1]		# seconda cella della riga
 
	data = treestore[1,0][2]
				# terza cella del primo figlio del
				# secondo nodo
 
	del liststore[42]	# elimina la riga 42
 
	model = gtk.ListStore(str, int)
				# lista composta da due colonne, la
				# prima di stringe, la seconda di
				# interi.
	model.append(('stringa', 42))
				# aggiungi una riga e riempila
[2] move_down è triviale da implementare (hint: iter_next e
insert_after). move_up no, perché gli iteratori sono una lista linkata
singolarmente. Il trucco sta nell'iterare partendo dal primo elemento
della lista e controllare il path fino all'elemento con il path minore
di una unità al path di partenza. Che ti va bene se devi muovere la
terza linea, meno bene se devi muovere la duecentocinquantesima.
Consiglio: mantieni ordinato il modello usando una colonna "invisibile";
ti costa mediamente un po' di più, ma se devi muovere spesso dei dati,
ti conviene. Ovviamente, se offri la possibilità di ordinare i dati in
maniera custom, devi tenere conto di questo trucco.


 internamente.
no, niente drag&drop. Per fortuna....

 maniera custom, devi tenere conto di questo trucco.
Si puo' fare in maniera veloce, senza ricorrere a colonne in piu' o cicli
iter= iter corrente
--python--
path=model.get_path(iter)
prevPath=model.path_prev(path)
prevIter=model.get_iter(prevPath)


 prevIter=model.get_iter(prevPath)
k, ho scritto una balla
ho letto nel gtk+ Reference Manual, nella sezione GtkTreeModel
gboolean gtk_tree_path_prev(GtkTreePath *path);
e l'ho letto come gtk_tree_model_path_prev
cmq, in C la funzione e' quella, in Python non so.
Controllero' piu' tardi.


 no, niente drag&drop. Per fortuna....
Personalmente, io c'ho rinunciato.


 Personalmente, io c'ho rinunciato.
se me lo chiedono dico che non è possibile :-)

 Passi la prima, la secondo mi fa però incazzare un po'....
Manca qualcuno che abbia la gentilezza di scrivere documentazione per
gli umani. Come spesso accade.
+++
Alle volte, trovo utile leggere la documentazione dei wrapper per gli
altri linguaggi, e gli esempi inclusi. Purtroppo, non mostrano azioni
complesse (esempio, il DnD), ma perlomeno aiutano a capire i concetti
di base.
Altrimenti, si prendono i sorgenti delle GTK+ e si lancia vim.


 Altrimenti, si prendono i sorgenti delle GTK+ e si lancia vim.
Come ho dovuto fare io, solo che oltre all'esame del codice ho dovuto 
procedere pure ad un paio di modifiche :)
C'e' da dire che gli altri toolkit moderni disponibili (qt e wxwindows 
in primis) offrono una flessibilita' infinitamente minore di GTK, in 
particolare su (c)liste e alberi, che a mio parere sono la forza e nello 
stesso tempo il tallone di achille di GTK :)
Bye,
  Gabry

 solo a disegnarsi...
La Mandrake usa il wrapper Perl per le GTK2, per il suo sistema di
installazione/configurazione. Quando devono visualizzare alberi con
molti nodi, per evitare appunto lentezze nel ridisegno, riempiono i nodi
una volta espansi. Può darsi che possa essere una strategia utile anche
per la tua applicazione.
Trovi maggiori dettagli sulla mailing list gtk-perl, negli articoli
dell'ultimo mese.


 stesso tempo il tallone di achille di GTK :)
vero, verissimo

 dell'ultimo mese.
Thx, ci daro' un'occhiata.
Bye,
  Gabry