From 6570f9ef698b4a924894837fc04d6e98c0c6bc80 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Wed, 23 Oct 2013 13:08:42 +0000
Subject: [PATCH] - Added buttons to move accross received signals

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4268 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 common/utils/itti_analyzer/itti_analyzer.c    |   3 +
 .../utils/itti_analyzer/libbuffers/socket.c   |   4 +-
 .../utils/itti_analyzer/libui/ui_callbacks.c  |  63 +++++++--
 .../utils/itti_analyzer/libui/ui_callbacks.h  |  16 +++
 .../utils/itti_analyzer/libui/ui_interface.c  |   2 +-
 .../itti_analyzer/libui/ui_main_screen.c      |   6 -
 .../itti_analyzer/libui/ui_main_screen.h      |  13 ++
 .../utils/itti_analyzer/libui/ui_menu_bar.c   | 122 +++++++++++++-----
 .../utils/itti_analyzer/libui/ui_tree_view.c  |  21 ++-
 .../utils/itti_analyzer/libui/ui_tree_view.h  |   2 +
 10 files changed, 193 insertions(+), 59 deletions(-)

diff --git a/common/utils/itti_analyzer/itti_analyzer.c b/common/utils/itti_analyzer/itti_analyzer.c
index 2a61e57824..8e90cf0e0a 100644
--- a/common/utils/itti_analyzer/itti_analyzer.c
+++ b/common/utils/itti_analyzer/itti_analyzer.c
@@ -82,5 +82,8 @@ int main(int argc, char *argv[])
 
     CHECK_FCT(ui_gtk_initialize(argc, argv));
 
+    /* Enter the main event loop, and wait for user interaction */
+    gtk_main ();
+
     return ret;
 }
diff --git a/common/utils/itti_analyzer/libbuffers/socket.c b/common/utils/itti_analyzer/libbuffers/socket.c
index cc048d7f3c..9d4a4bd11e 100644
--- a/common/utils/itti_analyzer/libbuffers/socket.c
+++ b/common/utils/itti_analyzer/libbuffers/socket.c
@@ -97,7 +97,7 @@ static int socket_read_itti_message(socket_data_t        *socket_data,
 
     g_assert(message_header != NULL);
 
-    g_debug("Attempting to read signal header from socket");
+//     g_debug("Attempting to read signal header from socket");
 
     /* Read the sub-header of signal */
     while (data_read != sizeof(itti_signal_header_t)) {
@@ -126,7 +126,7 @@ static int socket_read_itti_message(socket_data_t        *socket_data,
     }
 
     buffer->message_number = itti_signal_header.message_number;
-    buffer_dump(buffer, stdout);
+//     buffer_dump(buffer, stdout);
 
     /* Update the number of signals received since last GUI update */
     socket_data->nb_signals_since_last_update++;
diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.c b/common/utils/itti_analyzer/libui/ui_callbacks.c
index 4b1fc42505..ea8e347dbf 100644
--- a/common/utils/itti_analyzer/libui/ui_callbacks.c
+++ b/common/utils/itti_analyzer/libui/ui_callbacks.c
@@ -54,14 +54,9 @@ ui_callback_on_select_signal(GtkTreeSelection *selection,
 
     if (gtk_tree_model_get_iter(model, &iter, path))
     {
-//         gchar *name;
         GValue buffer_store = G_VALUE_INIT;
         gpointer buffer;
 
-//         g_value_init (&buffer_store, G_TYPE_POINTER);
-
-//         gtk_tree_model_get(model, &iter, 0, &name, -1);
-
         gtk_tree_model_get_value(model, &iter, COL_BUFFER, &buffer_store);
 
         buffer = g_value_get_pointer(&buffer_store);
@@ -74,16 +69,11 @@ ui_callback_on_select_signal(GtkTreeSelection *selection,
             /* Dissect the signal */
             CHECK_FCT_DO(dissect_signal((buffer_t*)buffer, ui_signal_set_text, text_view), return FALSE);
         }
-//         else
-//         {
-//             g_debug("%s is going to be unselected", name);
-//         }
-// 
-//         g_free(name);
     }
     return TRUE;
 }
 
+static
 void ui_signal_add_to_list(gpointer data, gpointer user_data)
 {
     buffer_t *signal_buffer;
@@ -97,6 +87,9 @@ void ui_signal_add_to_list(gpointer data, gpointer user_data)
                                 get_origin_task_id(signal_buffer),
                                 get_destination_task_id(signal_buffer),
                                 data);
+
+    /* Increment number of messages */
+    ui_main_data.nb_message_received++;
 }
 
 static gboolean ui_handle_update_signal_list(gint fd, void *data,
@@ -104,6 +97,12 @@ static gboolean ui_handle_update_signal_list(gint fd, void *data,
 {
     pipe_new_signals_list_message_t *signal_list_message;
 
+    /* Enable buttons to move in the list of signals */
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_clear_button), TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_button), TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), TRUE);
+
     signal_list_message = (pipe_new_signals_list_message_t *)data;
 
     g_assert(signal_list_message != NULL);
@@ -111,7 +110,10 @@ static gboolean ui_handle_update_signal_list(gint fd, void *data,
 
     g_list_foreach(signal_list_message->signal_list, ui_signal_add_to_list, NULL);
 
-    free(data);
+    /* Free the list but not user data associated with each element */
+    g_list_free(signal_list_message->signal_list);
+    /* Free the message */
+    free(signal_list_message);
 
     return TRUE;
 }
@@ -259,6 +261,43 @@ gboolean ui_callback_on_disconnect(GtkWidget *widget,
     return TRUE;
 }
 
+gboolean ui_callback_signal_go_to(GtkWidget *widget,
+                                  GdkEvent  *event,
+                                  gpointer   data)
+{
+    return TRUE;
+}
+
+gboolean ui_callback_signal_go_to_first(GtkWidget *widget,
+                                        GdkEvent  *event,
+                                        gpointer   data)
+{
+    ui_tree_view_select_row(0);
+    return TRUE;
+}
+
+gboolean ui_callback_signal_go_to_last(GtkWidget *widget,
+                                       GdkEvent  *event,
+                                       gpointer   data)
+{
+    ui_tree_view_select_row(ui_main_data.nb_message_received - 1);
+    return TRUE;
+}
+
+gboolean ui_callback_signal_clear_list(GtkWidget *widget,
+                                       GdkEvent  *event,
+                                       gpointer   data)
+{
+    /* Disable buttons to move in the list of signals */
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_clear_button), FALSE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_button), FALSE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), FALSE);
+    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), FALSE);
+
+    ui_tree_view_destroy_list(ui_main_data.signalslist);
+    return TRUE;
+}
+
 gboolean ui_callback_on_tree_view_select(GtkWidget *widget,
                                          GdkEvent  *event,
                                          gpointer   data)
diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.h b/common/utils/itti_analyzer/libui/ui_callbacks.h
index 2f60a711f8..d565c85ae8 100644
--- a/common/utils/itti_analyzer/libui/ui_callbacks.h
+++ b/common/utils/itti_analyzer/libui/ui_callbacks.h
@@ -28,6 +28,22 @@ ui_callback_on_select_signal(GtkTreeSelection *selection,
                              gboolean          path_currently_selected,
                              gpointer          userdata);
 
+gboolean ui_callback_signal_go_to(GtkWidget *widget,
+                                  GdkEvent  *event,
+                                  gpointer   data);
+
+gboolean ui_callback_signal_go_to_first(GtkWidget *widget,
+                                        GdkEvent  *event,
+                                        gpointer   data);
+
+gboolean ui_callback_signal_go_to_last(GtkWidget *widget,
+                                       GdkEvent  *event,
+                                       gpointer   data);
+
+gboolean ui_callback_signal_clear_list(GtkWidget *widget,
+                                       GdkEvent  *event,
+                                       gpointer   data);
+
 gboolean ui_pipe_callback(gint source, gpointer user_data);
 
 #endif /* UI_CALLBACKS_H_ */
diff --git a/common/utils/itti_analyzer/libui/ui_interface.c b/common/utils/itti_analyzer/libui/ui_interface.c
index 56a0e92c57..00547cbc03 100644
--- a/common/utils/itti_analyzer/libui/ui_interface.c
+++ b/common/utils/itti_analyzer/libui/ui_interface.c
@@ -22,7 +22,7 @@ gboolean ui_callback_on_pipe_notification(
     /* avoid reentrancy problems and stack overflow */
     g_source_remove(pipe_input->pipe_input_id);
 
-    g_debug("Received new data on pipe %d", pipe_input->pipe_input_id);
+//     g_debug("Received new data on pipe %d", pipe_input->pipe_input_id);
 
     if (pipe_input->input_cb(pipe_input->source_fd, pipe_input->user_data)) {
         /* restore pipe handler */
diff --git a/common/utils/itti_analyzer/libui/ui_main_screen.c b/common/utils/itti_analyzer/libui/ui_main_screen.c
index 288c75551d..b1ce58c1a6 100644
--- a/common/utils/itti_analyzer/libui/ui_main_screen.c
+++ b/common/utils/itti_analyzer/libui/ui_main_screen.c
@@ -52,11 +52,5 @@ int ui_gtk_initialize(int argc, char *argv[])
     /* Show the application window */
     gtk_widget_show_all (ui_main_data.window);
 
-    /* Enter the main event loop, and wait for user interaction */
-    gtk_main ();
-
-    /* Release gtk's global lock */
-    gdk_threads_leave();
-
     return RC_OK;
 }
diff --git a/common/utils/itti_analyzer/libui/ui_main_screen.h b/common/utils/itti_analyzer/libui/ui_main_screen.h
index 370326f39d..b9d2a5770c 100644
--- a/common/utils/itti_analyzer/libui/ui_main_screen.h
+++ b/common/utils/itti_analyzer/libui/ui_main_screen.h
@@ -13,9 +13,22 @@ typedef struct {
     ui_text_view_t *text_view;
 
     /* Buttons */
+    GtkToolItem *open_replay_file;
     GtkToolItem *connect;
     GtkToolItem *disconnect;
 
+    /* Signal list buttons */
+    /* Clear signals button */
+    GtkToolItem *signals_clear_button;
+    GtkToolItem *signals_go_to_button;
+    GtkToolItem *signals_go_to_last_button;
+    GtkToolItem *signals_go_to_first_button;
+
+    GtkTreeSelection *selection;
+
+    /* Nb of messages received */
+    guint nb_message_received;
+
     int pipe_fd[2];
 } ui_main_data_t;
 
diff --git a/common/utils/itti_analyzer/libui/ui_menu_bar.c b/common/utils/itti_analyzer/libui/ui_menu_bar.c
index 2ea1506d79..c23ed2d222 100644
--- a/common/utils/itti_analyzer/libui/ui_menu_bar.c
+++ b/common/utils/itti_analyzer/libui/ui_menu_bar.c
@@ -59,7 +59,6 @@ int ui_toolbar_create(GtkWidget *vbox)
     GtkWidget *hbox;
     GtkWidget *iplabel;
     GtkWidget *portlabel;
-    GtkToolItem *open;
 
     if (!vbox)
         return RC_BAD_PARAM;
@@ -71,28 +70,99 @@ int ui_toolbar_create(GtkWidget *vbox)
 
     gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);
 
-    /* Button to open file */
-    open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(open),
-                                   "Open new dump file");
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), open, -1);
+    /* Button to clear signal list and clear signal dissect view */
+    {
+        ui_main_data.signals_clear_button = gtk_tool_button_new_from_stock(GTK_STOCK_NEW);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_clear_button),
+                                       "Start a new acquisition or replay");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.signals_clear_button, -1);
+
+        gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_clear_button), FALSE);
+
+        g_signal_connect(G_OBJECT(ui_main_data.signals_clear_button), "clicked",
+                        G_CALLBACK(ui_callback_signal_clear_list), NULL);
+    }
+
+    /* Button to open replay file */
+    {
+        ui_main_data.open_replay_file = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.open_replay_file),
+                                    "Open new replay file");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.open_replay_file, -1);
+
+        g_signal_connect(G_OBJECT(ui_main_data.open_replay_file), "clicked",
+                        G_CALLBACK(ui_callback_on_open), NULL);
+    }
+
+    /* Button to go given signal number */
+    {
+        ui_main_data.signals_go_to_button = gtk_tool_button_new_from_stock(GTK_STOCK_INDEX);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_go_to_button),
+                                    "Goto signal");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.signals_go_to_button, -1);
+
+        gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_button), FALSE);
+
+        g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_button), "clicked",
+                        G_CALLBACK(ui_callback_signal_go_to), NULL);
+    }
+
+    /* Button to go to first signal in list */
+    {
+        ui_main_data.signals_go_to_first_button = gtk_tool_button_new_from_stock(GTK_STOCK_GOTO_FIRST);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_go_to_first_button),
+                                    "Goto first signal");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.signals_go_to_first_button, -1);
+
+        gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), FALSE);
+
+        g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_first_button), "clicked",
+                        G_CALLBACK(ui_callback_signal_go_to_first), NULL);
+    }
+
+    /* Button to go to last signal in list */
+    {
+        ui_main_data.signals_go_to_last_button = gtk_tool_button_new_from_stock(GTK_STOCK_GOTO_LAST);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_go_to_last_button),
+                                    "Goto last signal");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.signals_go_to_last_button, -1);
+
+        gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), FALSE);
+
+        g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_last_button), "clicked",
+                        G_CALLBACK(ui_callback_signal_go_to_last), NULL);
+    }
 
     /* Button to connect to remote */
-    ui_main_data.connect = gtk_tool_button_new_from_stock(GTK_STOCK_CONNECT);
-    /* Set the tooltip text */
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.connect),
-                                   "Connect to remote host");
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.connect, -1);
-
-    /* Button to connect to remote */
-    ui_main_data.disconnect = gtk_tool_button_new_from_stock(GTK_STOCK_DISCONNECT);
-    /* Set the tooltip text */
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.disconnect),
-                                   "Disconnect from remote host");
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.disconnect, -1);
-
-    /* Disabled at startup. Will be activated when a connection is established */
-    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.disconnect), FALSE);
+    {
+        ui_main_data.connect = gtk_tool_button_new_from_stock(GTK_STOCK_CONNECT);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.connect),
+                                    "Connect to remote host");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.connect, -1);
+
+        g_signal_connect(G_OBJECT(ui_main_data.connect), "clicked",
+                        G_CALLBACK(ui_callback_on_connect), NULL);
+    }
+
+    /* Button to disconnect from remote */
+    {
+        ui_main_data.disconnect = gtk_tool_button_new_from_stock(GTK_STOCK_DISCONNECT);
+        /* Set the tooltip text */
+        gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.disconnect),
+                                    "Disconnect from remote host");
+        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.disconnect, -1);
+
+        /* Disabled at startup. Will be activated when a connection is established */
+        gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.disconnect), FALSE);
+
+        g_signal_connect(G_OBJECT(ui_main_data.disconnect), "clicked",
+                        G_CALLBACK(ui_callback_on_disconnect), NULL);
+    }
 
     /* No overflow menu */
     gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), FALSE);
@@ -117,15 +187,5 @@ int ui_toolbar_create(GtkWidget *vbox)
     gtk_box_pack_start(GTK_BOX(hbox), ui_main_data.portentry, FALSE, FALSE, 5);
     gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
 
-    /* Some callbacks associated to buttons */
-    g_signal_connect(G_OBJECT(open), "clicked",
-                     G_CALLBACK(ui_callback_on_open), NULL);
-
-    g_signal_connect(G_OBJECT(ui_main_data.connect), "clicked",
-                     G_CALLBACK(ui_callback_on_connect), NULL);
-
-    g_signal_connect(G_OBJECT(ui_main_data.disconnect), "clicked",
-                     G_CALLBACK(ui_callback_on_disconnect), NULL);
-
     return RC_OK;
 }
diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.c b/common/utils/itti_analyzer/libui/ui_tree_view.c
index 8a738fcc6d..3d5ca15ea4 100644
--- a/common/utils/itti_analyzer/libui/ui_tree_view.c
+++ b/common/utils/itti_analyzer/libui/ui_tree_view.c
@@ -93,15 +93,12 @@ int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox)
     GtkWidget *hbox;
     GtkTreeSelection *selection;
     GtkWidget *scrolled_window;
-//     gint width;
 
     scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
 
-    //gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 5);
-
     ui_main_data.signalslist = gtk_tree_view_new();
     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(ui_main_data.signalslist), TRUE);
 
@@ -116,20 +113,18 @@ int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox)
 
     ui_tree_view_init_list(ui_main_data.signalslist);
 
-//     gtk_widget_get_size_request(GTK_WIDGET(ui_main_data.signalslist), &width, NULL);
     gtk_widget_set_size_request(GTK_WIDGET(scrolled_window), 350, -1);
     gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, FALSE, FALSE, 0);
     ui_main_data.text_view = ui_signal_dissect_new(hbox);
 
     gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
 
-//     g_signal_connect(G_OBJECT(ui_main_data.signalslist), "cursor-changed",
-//                      G_CALLBACK(ui_callback_on_select_signal), NULL);
-
     /* Connect callback on row selection */
     gtk_tree_selection_set_select_function(selection, ui_callback_on_select_signal,
                                            ui_main_data.text_view, NULL);
 
+    ui_main_data.selection = selection;
+
     return 0;
 }
 
@@ -145,3 +140,15 @@ int ui_tree_view_new_signal_ind(const uint32_t message_number, const char *signa
 
     return RC_OK;
 }
+
+void ui_tree_view_select_row(gint row)
+{
+    GtkTreePath *path;
+    gchar        indice[10];
+
+    sprintf(indice, "%d", row);
+
+    path = gtk_tree_path_new_from_string(indice);
+    gtk_tree_view_set_cursor(GTK_TREE_VIEW(ui_main_data.signalslist), path, NULL,
+                             FALSE);
+}
diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.h b/common/utils/itti_analyzer/libui/ui_tree_view.h
index 9bfdcbbe0b..83691c6641 100644
--- a/common/utils/itti_analyzer/libui/ui_tree_view.h
+++ b/common/utils/itti_analyzer/libui/ui_tree_view.h
@@ -18,4 +18,6 @@ int ui_tree_view_new_signal_ind(const uint32_t message_number, const char *signa
 
 void ui_tree_view_destroy_list(GtkWidget *list);
 
+void ui_tree_view_select_row(gint row);
+
 #endif /* UI_TREE_VIEW_H_ */
-- 
GitLab