This is part of an exercise, in which I am creating a small network packet analyzer "as Wireshark".
I'm trying to store the Data of packets in a gtk_tree_store which can be revealed:
structures used:
packet's data is stored in a trame.
typedef struct trame_{
unsigned int *tab;
int id;
int nb_ligne_erreur;
int nb_octet_erreur;
//couche ethernet
char *mac_dest;
char *mac_source;
char *ip_type;
//couche ip
char *version;
char *header_length;
int *total_length;
int *identification;
int *flags_frag_offset;
int TTL;
int protocol;
int *header_checksum;
int *ip_source;
int *ip_dest;
//couche tcp
int source_port;
int destination_port;
int stream_index;
int tcp_seg_len;
char* sequence_number;
int sequence_number_raw;
char *next_sequence_number;
char *acknowledgment_number;
int acknowledgment_number_raw;
char *tcp_header_length;
}trame;
chained list of trames with buttons (upper window, arbre (revealers on the lower window)
typedef struct cell_{
trame *obj;
GtkWidget *arbre;
GtkWidget *bouton;
struct cell_ *suiv;
int status_bouton_ip;
}cell;
this function create a new gtk_store_tree
with all the data collected in a packet
void remplir_arbre(GtkWidget *pWidget, gpointer pData){
cell *tmp_cell=(cell *)pData;
GtkTreeStore *arbre=gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
GtkTreeIter header_ethernet;
GtkTreeIter contenu_ethernet;
GtkTreeIter header_IP;
GtkTreeIter contenu_IP;
gtk_tree_store_insert (arbre,&header_ethernet,NULL,-1);
gtk_tree_store_set(arbre, &header_ethernet,0,"Ethernet II",1,NULL, -1);
gtk_tree_store_insert (arbre,&contenu_ethernet,&header_ethernet,-1);
gtk_tree_store_set(arbre,&contenu_ethernet, 0, "Source:",1,tmp_cell->obj->mac_source, -1);
gtk_tree_store_insert (arbre,&contenu_ethernet,&header_ethernet,-1);
gtk_tree_store_set(arbre,&contenu_ethernet, 0, "Destination:",1,tmp_cell->obj->mac_dest, -1);
gtk_tree_store_insert (arbre,&contenu_ethernet,&header_ethernet,-1);
gtk_tree_store_set(arbre,&contenu_ethernet, 0, "type:",1,tmp_cell->obj->ip_type, -1);
gtk_tree_store_insert(arbre,&header_IP,NULL,-1);
gtk_tree_store_set(arbre,&header_IP,0,"Internet Protocol",1,"", -1);
gtk_tree_store_insert(arbre,&contenu_IP,&header_IP,-1);
gtk_tree_store_set(arbre,&contenu_IP,0,"IP Version:",1,tmp_cell->obj->version, -1);
gtk_tree_store_insert(arbre,&contenu_IP,&header_IP,-1);
gtk_tree_store_set(arbre,&contenu_IP,0,"IP Version:",1,tmp_cell->obj->version, -1);
gtk_tree_store_insert(arbre,&contenu_IP,&header_IP,-1);
gtk_tree_store_set(arbre,&contenu_IP,0,"IP Version:",1,tmp_cell->obj->version, -1);
tmp_cell->arbre = gtk_tree_view_new_with_model(GTK_TREE_MODEL(arbre));
GtkCellRenderer *renderer_col1;
GtkCellRenderer *renderer_col2;
GtkTreeViewColumn *column;
GtkTreeViewColumn *column_2;
char label[20];
sprintf(label,"trame n°%d",tmp_cell->obj->id);
renderer_col1 = gtk_cell_renderer_text_new();
renderer_col2 = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(label, renderer_col1, "text", 0, NULL);
column_2 = gtk_tree_view_column_new_with_attributes(NULL, renderer_col2, "text",1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tmp_cell->arbre), column);
gtk_tree_view_append_column(GTK_TREE_VIEW(tmp_cell->arbre), column_2);
return;
}
this Function call remplir_arbre() and create and new revealer which is going to be stacked in the lower window
void ajout_liste(cell **liste,trame *elem,GtkWidget* box_haut, GtkWidget* box_bas){
char label[80];
sprintf(label,"%d\t%d:%d:%d:%d\t%d:%d:%d:%d",elem->id,(elem->ip_source)[0],(elem->ip_source)[1],(elem->ip_source)[2],(elem->ip_source)[3],(elem->ip_dest)[0],(elem->ip_dest)[1],(elem->ip_dest)[2],(elem->ip_dest)[3]);
GtkWidget* tmp_bouton=gtk_toggle_button_new_with_label(label);
if (elem->nb_ligne_erreur==-1){
gtk_widget_set_name(tmp_bouton,"button_dark_mode");
}else {
gtk_widget_set_name(tmp_bouton,"button_dark_mode_erreur");
}
cell *new_cell=(cell *) malloc(sizeof(cell));
GtkWidget *revealer = gtk_revealer_new();
new_cell->obj=elem;
new_cell->arbre=NULL;
new_cell->bouton=tmp_bouton;
new_cell->suiv=(*liste);
new_cell->status_bouton_ip=0;
*liste=new_cell;
remplir_arbre(NULL, new_cell);
gtk_widget_set_name(new_cell->arbre,"tree_dark_mode");
gtk_container_add(GTK_CONTAINER(revealer), new_cell->arbre);
gtk_revealer_set_reveal_child(GTK_REVEALER(revealer), FALSE);
gtk_box_pack_start(GTK_BOX(box_haut),tmp_bouton, FALSE,TRUE, 0);
gtk_box_pack_start(GTK_BOX(box_bas),revealer, FALSE, FALSE, 0); #box_bas is a gtk_box were all revealers are stacked ( the lower box on the screen)
gtk_widget_show (tmp_bouton);
gtk_widget_show_all(box_bas);
g_signal_connect(G_OBJECT(tmp_bouton), "clicked", G_CALLBACK(action_bouton_ip),new_cell);
g_object_bind_property(tmp_bouton, "active", revealer, "reveal-child", 1);
}
Revealers don't show all of the rows of their child until all of the revealers are not activated:
activated revealers hide non-activated other ones:
I was wondering if it was because i was using a gtk_box to stack revealers but it does not seems to be it.
I removed the revealer to see if i could at first , try to see all of the tree's childs and then find a solution to hide them.
i noticed some things :
Finally i found another structure provided by GTK which fits to my needs. Instead of using gtk_trees , i'm using some gtk_expanders combined with gtk_box to stack widgets into.
https://developer.gnome.org/gtk3/stable/GtkExpander.html
void remplir_ethernet(GtkWidget *box_ethernet,cell *tmp_cell){
char label[80];
GtkWidget *tmp_label=NULL;
sprintf(label,"\tSource\t\t: %s\n",(tmp_cell->obj->mac_source));
tmp_label=gtk_label_new(label);
gtk_label_set_xalign (GTK_LABEL(tmp_label),0);
gtk_box_pack_start(GTK_BOX(box_ethernet),tmp_label, FALSE, FALSE, 0);
sprintf(label,"\tDestination\t: %s\n",(tmp_cell->obj->mac_dest));
tmp_label=gtk_label_new(label);
gtk_label_set_xalign (GTK_LABEL(tmp_label),0);
gtk_box_pack_start(GTK_BOX(box_ethernet),tmp_label, FALSE, FALSE, 0);
sprintf(label,"\ttype\t\t: %s\n",(tmp_cell->obj->ip_type));
tmp_label=gtk_label_new(label);
gtk_label_set_xalign (GTK_LABEL(tmp_label),0);
gtk_box_pack_start(GTK_BOX(box_ethernet),tmp_label, FALSE, FALSE, 0);
}
void remplir_ip(GtkWidget *box_ip,cell *tmp_cell){
char label[80];
GtkWidget *tmp_label=NULL;
sprintf(label,"\tVersion\t\t: %s\n",(tmp_cell->obj->version));
tmp_label=gtk_label_new(label);
gtk_label_set_xalign (GTK_LABEL(tmp_label),0);
gtk_box_pack_start(GTK_BOX(box_ip),tmp_label, FALSE, FALSE, 0);
}
void remplir_arbre(GtkWidget *new_box, gpointer pData){
cell *tmp_cell=(cell *)pData;
GtkWidget *ethernet=gtk_expander_new ("Ethernet II");
gtk_expander_set_resize_toplevel (GTK_EXPANDER(ethernet),FALSE);
gtk_box_pack_start (GTK_BOX(new_box),ethernet,FALSE,FALSE,0);
GtkWidget *box_ethernet=gtk_box_new(FALSE,0);
gtk_orientable_set_orientation (GTK_ORIENTABLE (box_ethernet),GTK_ORIENTATION_VERTICAL);
gtk_container_add(GTK_CONTAINER(ethernet),box_ethernet);
remplir_ethernet(box_ethernet,tmp_cell);
GtkWidget *IP=gtk_expander_new ("Internet Protocol");
gtk_expander_set_resize_toplevel (GTK_EXPANDER(IP),FALSE);
gtk_box_pack_start (GTK_BOX(new_box),IP,FALSE,FALSE,0);
GtkWidget *box_ip=gtk_box_new(FALSE,0);
gtk_orientable_set_orientation (GTK_ORIENTABLE (box_ip),GTK_ORIENTATION_VERTICAL);
gtk_container_add(GTK_CONTAINER(IP),box_ip);
remplir_ip(box_ip,tmp_cell);
return;
}
I still don't know why gtk_tree did not work.