diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.c b/common/utils/itti_analyzer/libui/ui_callbacks.c index f4be4438e9d9bf737348a98131b3a42d1718275a..1ae52ee580fd992448f98cc7998787d279927e86 100644 --- a/common/utils/itti_analyzer/libui/ui_callbacks.c +++ b/common/utils/itti_analyzer/libui/ui_callbacks.c @@ -9,6 +9,7 @@ #include "ui_notif_dlg.h" #include "ui_main_screen.h" +#include "ui_menu_bar.h" #include "ui_callbacks.h" #include "ui_interface.h" #include "ui_notifications.h" @@ -21,45 +22,59 @@ static gboolean ui_handle_socket_connection_failed(gint fd); -gboolean ui_callback_on_open(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_on_open_messages(GtkWidget *widget, GdkEvent *event, gpointer data) { - g_debug("Open event occurred"); - CHECK_FCT(ui_file_chooser()); + g_debug("Open replay event occurred"); + CHECK_FCT(ui_messages_open_file_chooser()); + + return TRUE; +} + +gboolean ui_callback_on_save_messages(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("Save replay event occurred"); + // CHECK_FCT(ui_file_chooser()); + return TRUE; +} + +gboolean ui_callback_on_open_filters(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("Open filters event occurred"); + CHECK_FCT(ui_filters_open_file_chooser()); + return TRUE; +} + +gboolean ui_callback_on_save_filters(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("Save filters event occurred"); + CHECK_FCT(ui_filters_save_file_chooser()); return TRUE; } -gboolean ui_callback_on_about(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_on_about(GtkWidget *widget, GdkEvent *event, gpointer data) { return TRUE; } -gboolean -ui_callback_on_select_signal(GtkTreeSelection *selection, - GtkTreeModel *model, - GtkTreePath *path, - gboolean path_currently_selected, - gpointer user_data) +gboolean ui_callback_on_select_signal(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, + gboolean path_currently_selected, gpointer user_data) { ui_text_view_t *text_view; GtkTreeIter iter; - text_view = (ui_text_view_t *)user_data; + text_view = (ui_text_view_t *) user_data; g_assert(text_view != NULL); - if (gtk_tree_model_get_iter(model, &iter, path)) + if (gtk_tree_model_get_iter (model, &iter, path)) { GValue buffer_store = G_VALUE_INIT; gpointer buffer; - gtk_tree_model_get_value(model, &iter, COL_BUFFER, &buffer_store); + gtk_tree_model_get_value (model, &iter, COL_BUFFER, &buffer_store); - buffer = g_value_get_pointer(&buffer_store); + buffer = g_value_get_pointer (&buffer_store); if (!path_currently_selected) { @@ -76,43 +91,47 @@ ui_callback_on_select_signal(GtkTreeSelection *selection, void ui_signal_add_to_list(gpointer data, gpointer user_data) { buffer_t *signal_buffer; + GtkTreePath *path; + GtkTreeViewColumn *focus_column; - signal_buffer = (buffer_t *)data; + gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.signalslist), &path, &focus_column); - get_message_id(root, signal_buffer, &signal_buffer->message_id); + signal_buffer = (buffer_t *) data; - ui_tree_view_new_signal_ind(signal_buffer->message_number, - message_id_to_string(signal_buffer->message_id), - get_origin_task_id(signal_buffer), - get_destination_task_id(signal_buffer), - data); + get_message_id (root, signal_buffer, &signal_buffer->message_id); + + ui_tree_view_new_signal_ind (signal_buffer->message_number, message_id_to_string (signal_buffer->message_id), + get_origin_task_id (signal_buffer), get_destination_task_id (signal_buffer), data); /* Increment number of messages */ ui_main_data.nb_message_received++; + + /* Check if no signal was selected in the list or if it was the last signal */ + if ((ui_main_data.path_last == NULL) || (gtk_tree_path_compare(ui_main_data.path_last, path) == 0)) + { + /* Advance to the new last signal */ + ui_callback_signal_go_to_last (NULL, NULL, NULL); + } } -static gboolean ui_handle_update_signal_list(gint fd, void *data, - size_t data_length) +static gboolean ui_handle_update_signal_list(gint fd, void *data, size_t data_length) { 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); + ui_set_sensitive_move_buttons (TRUE); - signal_list_message = (pipe_new_signals_list_message_t *)data; + signal_list_message = (pipe_new_signals_list_message_t *) data; g_assert(signal_list_message != NULL); g_assert(signal_list_message->signal_list != NULL); - g_list_foreach(signal_list_message->signal_list, ui_signal_add_to_list, NULL); + g_list_foreach (signal_list_message->signal_list, ui_signal_add_to_list, NULL); /* Free the list but not user data associated with each element */ - g_list_free(signal_list_message->signal_list); + g_list_free (signal_list_message->signal_list); /* Free the message */ - free(signal_list_message); + free (signal_list_message); return TRUE; } @@ -121,17 +140,15 @@ static gboolean ui_handle_socket_connection_failed(gint fd) { GtkWidget *dialogbox; - dialogbox = gtk_message_dialog_new(GTK_WINDOW(ui_main_data.window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Failed to connect to provided host/ip address"); + dialogbox = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "Failed to connect to provided host/ip address"); - gtk_dialog_run(GTK_DIALOG(dialogbox)); - gtk_widget_destroy(dialogbox); + gtk_dialog_run (GTK_DIALOG(dialogbox)); + gtk_widget_destroy (dialogbox); /* Re-enable connect button */ - ui_enable_connect_button(); + ui_enable_connect_button (); return TRUE; } @@ -139,45 +156,42 @@ static gboolean ui_handle_socket_connection_lost(gint fd) { GtkWidget *dialogbox; - dialogbox = gtk_message_dialog_new(GTK_WINDOW(ui_main_data.window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Connection with remote host has been lost"); + dialogbox = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "Connection with remote host has been lost"); - gtk_dialog_run(GTK_DIALOG(dialogbox)); - gtk_widget_destroy(dialogbox); + gtk_dialog_run (GTK_DIALOG(dialogbox)); + gtk_widget_destroy (dialogbox); /* Re-enable connect button */ - ui_enable_connect_button(); + ui_enable_connect_button (); return TRUE; } -static gboolean ui_handle_socket_xml_definition(gint fd, void *data, - size_t data_length) +static gboolean ui_handle_socket_xml_definition(gint fd, void *data, size_t data_length) { pipe_xml_definition_message_t *xml_definition_message; - xml_definition_message = (pipe_xml_definition_message_t *)data; + xml_definition_message = (pipe_xml_definition_message_t *) data; g_assert(xml_definition_message != NULL); g_assert(data_length == sizeof(pipe_xml_definition_message_t)); - xml_parse_buffer(xml_definition_message->xml_definition, - xml_definition_message->xml_definition_length); + xml_parse_buffer (xml_definition_message->xml_definition, xml_definition_message->xml_definition_length); - free(data); + free (data); return TRUE; } gboolean ui_pipe_callback(gint source, gpointer user_data) { - void *input_data = NULL; - size_t input_data_length = 0; - pipe_input_header_t input_header; + void *input_data = NULL; + size_t input_data_length = 0; + pipe_input_header_t input_header; /* Read the header */ - if (read(source, &input_header, sizeof(input_header)) < 0) { + if (read (source, &input_header, sizeof(input_header)) < 0) + { g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno)); return FALSE; } @@ -185,24 +199,27 @@ gboolean ui_pipe_callback(gint source, gpointer user_data) input_data_length = input_header.message_size - sizeof(input_header); /* Checking for non-header part */ - if (input_data_length > 0) { - input_data = malloc(input_data_length); + if (input_data_length > 0) + { + input_data = malloc (input_data_length); - if (read(source, input_data, input_data_length) < 0) { + if (read (source, input_data, input_data_length) < 0) + { g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno)); return FALSE; } } - switch (input_header.message_type) { + switch (input_header.message_type) + { case UI_PIPE_CONNECTION_FAILED: - return ui_handle_socket_connection_failed(source); + return ui_handle_socket_connection_failed (source); case UI_PIPE_XML_DEFINITION: - return ui_handle_socket_xml_definition(source, input_data, input_data_length); + return ui_handle_socket_xml_definition (source, input_data, input_data_length); case UI_PIPE_CONNECTION_LOST: - return ui_handle_socket_connection_lost(source); + return ui_handle_socket_connection_lost (source); case UI_PIPE_UPDATE_SIGNAL_LIST: - return ui_handle_update_signal_list(source, input_data, input_data_length); + return ui_handle_update_signal_list (source, input_data, input_data_length); default: g_debug("[gui] Unhandled message type %u", input_header.message_type); g_assert_not_reached(); @@ -210,105 +227,108 @@ gboolean ui_pipe_callback(gint source, gpointer user_data) return FALSE; } -gboolean ui_callback_on_connect(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_on_connect(GtkWidget *widget, GdkEvent *event, gpointer data) { /* We have to retrieve the ip address and port of remote host */ const char *ip; - uint16_t port; - int pipe_fd[2]; + uint16_t port; + int pipe_fd[2]; g_debug("Connect event occurred"); - port = atoi(gtk_entry_get_text(GTK_ENTRY(ui_main_data.portentry))); - ip = gtk_entry_get_text(GTK_ENTRY(ui_main_data.ipentry)); + port = atoi (gtk_entry_get_text (GTK_ENTRY(ui_main_data.portentry))); + ip = gtk_entry_get_text (GTK_ENTRY(ui_main_data.ipentry)); - if ((ip == NULL) || (port == 0)) { + if ((ip == NULL) || (port == 0)) + { g_warning("NULL parameter given for ip address or port = 0"); /* TODO: add dialog box here */ return FALSE; } - ui_pipe_new(pipe_fd, ui_pipe_callback, NULL); + ui_pipe_new (pipe_fd, ui_pipe_callback, NULL); - memcpy(ui_main_data.pipe_fd, pipe_fd, sizeof(int) * 2); + memcpy (ui_main_data.pipe_fd, pipe_fd, sizeof(int) * 2); /* Disable the connect button */ - ui_disable_connect_button(); + ui_disable_connect_button (); - /* 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); - - if (socket_connect_to_remote_host(ip, port, pipe_fd[1]) != 0) { - ui_enable_connect_button(); + ui_callback_signal_clear_list (widget, event, data); + + if (socket_connect_to_remote_host (ip, port, pipe_fd[1]) != 0) + { + ui_enable_connect_button (); return FALSE; } return TRUE; } -gboolean ui_callback_on_disconnect(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_on_disconnect(GtkWidget *widget, GdkEvent *event, gpointer data) { /* We have to retrieve the ip address and port of remote host */ g_debug("Disconnect event occurred"); - ui_pipe_write_message(ui_main_data.pipe_fd[0], UI_PIPE_DISCONNECT_EVT, - NULL, 0); + ui_pipe_write_message (ui_main_data.pipe_fd[0], UI_PIPE_DISCONNECT_EVT, NULL, 0); - ui_enable_connect_button(); + ui_enable_connect_button (); return TRUE; } -gboolean ui_callback_signal_go_to(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_signal_go_to(GtkWidget *widget, GdkEvent *event, gpointer data) { + ui_tree_view_select_row (ui_main_data.nb_message_received / 2, NULL); return TRUE; } -gboolean ui_callback_signal_go_to_first(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_signal_go_to_first(GtkWidget *widget, GdkEvent *event, gpointer data) { - ui_tree_view_select_row(0); + ui_tree_view_select_row (0, NULL); return TRUE; } -gboolean ui_callback_signal_go_to_last(GtkWidget *widget, - GdkEvent *event, - gpointer data) +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); + GtkTreePath *path; + + ui_tree_view_select_row (ui_main_data.nb_message_received - 1, &path); + ui_main_data.path_last = path; + return TRUE; } -gboolean ui_callback_signal_clear_list(GtkWidget *widget, - GdkEvent *event, - gpointer data) +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_set_sensitive_move_buttons (FALSE); - ui_tree_view_destroy_list(ui_main_data.signalslist); + /* Clear list of signals */ + ui_tree_view_destroy_list (ui_main_data.signalslist); return TRUE; } -gboolean ui_callback_on_tree_view_select(GtkWidget *widget, - GdkEvent *event, - gpointer data) +gboolean ui_callback_on_tree_view_select(GtkWidget *widget, GdkEvent *event, gpointer data) { /* We have to retrieve the ip address and port of remote host */ g_debug("List selection event occurred"); return TRUE; } + +gboolean ui_callback_on_tree_column_header_click_signal(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("ui_callback_on_tree_column_header_click_signal\n"); + return TRUE; +} + +gboolean ui_callback_on_tree_column_header_click_from(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("ui_callback_on_tree_column_header_click_from\n"); + return TRUE; +} + +gboolean ui_callback_on_tree_column_header_click_to(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_debug("ui_callback_on_tree_column_header_click_to\n"); + return TRUE; +} diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.h b/common/utils/itti_analyzer/libui/ui_callbacks.h index be3ccb9041419b014952a2966af2b9f58bade53f..9524b7c8d383166e390d1a6ab7c74e835c9ef8df 100644 --- a/common/utils/itti_analyzer/libui/ui_callbacks.h +++ b/common/utils/itti_analyzer/libui/ui_callbacks.h @@ -1,9 +1,21 @@ #ifndef UI_CALLBACKS_H_ #define UI_CALLBACKS_H_ -gboolean ui_callback_on_open(GtkWidget *widget, - GdkEvent *event, - gpointer data); +gboolean ui_callback_on_open_messages(GtkWidget *widget, + GdkEvent *event, + gpointer data); + +gboolean ui_callback_on_save_messages(GtkWidget *widget, + GdkEvent *event, + gpointer data); + +gboolean ui_callback_on_open_filters(GtkWidget *widget, + GdkEvent *event, + gpointer data); + +gboolean ui_callback_on_save_filters(GtkWidget *widget, + GdkEvent *event, + gpointer data); gboolean ui_callback_on_about(GtkWidget *widget, GdkEvent *event, @@ -49,4 +61,16 @@ gboolean ui_callback_signal_clear_list(GtkWidget *widget, gboolean ui_pipe_callback(gint source, gpointer user_data); +gboolean ui_callback_on_tree_column_header_click_signal(GtkWidget *widget, + GdkEvent *event, + gpointer data); + +gboolean ui_callback_on_tree_column_header_click_from(GtkWidget *widget, + GdkEvent *event, + gpointer data); + +gboolean ui_callback_on_tree_column_header_click_to(GtkWidget *widget, + GdkEvent *event, + gpointer data); + #endif /* UI_CALLBACKS_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_main_screen.h b/common/utils/itti_analyzer/libui/ui_main_screen.h index b9d2a5770cafd40e6f4e886a880e7ac186929721..c30b1843294cdf053bc7f0d8abb03d15dd183c18 100644 --- a/common/utils/itti_analyzer/libui/ui_main_screen.h +++ b/common/utils/itti_analyzer/libui/ui_main_screen.h @@ -14,6 +14,9 @@ typedef struct { /* Buttons */ GtkToolItem *open_replay_file; + GtkToolItem *save_replay_file; + GtkToolItem *open_filters_file; + GtkToolItem *save_filters_file; GtkToolItem *connect; GtkToolItem *disconnect; @@ -25,6 +28,7 @@ typedef struct { GtkToolItem *signals_go_to_first_button; GtkTreeSelection *selection; + GtkTreePath *path_last; /* Nb of messages received */ guint nb_message_received; diff --git a/common/utils/itti_analyzer/libui/ui_menu_bar.c b/common/utils/itti_analyzer/libui/ui_menu_bar.c index c23ed2d2221e0c2ef20f75f637b4d32aee89510f..e2f5d2b396e7329f3fd03ea1c242a5264cfb19a0 100644 --- a/common/utils/itti_analyzer/libui/ui_menu_bar.c +++ b/common/utils/itti_analyzer/libui/ui_menu_bar.c @@ -5,12 +5,24 @@ #include "ui_menu_bar.h" #include "ui_callbacks.h" +void ui_set_sensitive_move_buttons(gboolean enable) +{ + // gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_clear_button), enable); + // gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_button), enable); + gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), enable); + gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), enable); +} + int ui_menu_bar_create(GtkWidget *vbox) { GtkWidget *menubar; GtkWidget *filemenu, *helpmenu; GtkWidget *file; GtkWidget *help; + GtkWidget *open_messages; + GtkWidget *save_messages; + GtkWidget *open_filters; + GtkWidget *save_filters; GtkWidget *quit; GtkWidget *about; @@ -23,11 +35,19 @@ int ui_menu_bar_create(GtkWidget *vbox) filemenu = gtk_menu_new(); file = gtk_menu_item_new_with_label("File"); + open_messages = gtk_menu_item_new_with_label("Open messages file"); + save_messages = gtk_menu_item_new_with_label("Save messages file"); + open_filters = gtk_menu_item_new_with_label("Open filters file"); + save_filters = gtk_menu_item_new_with_label("Save filters file"); quit = gtk_menu_item_new_with_label("Quit"); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file); + gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), open_messages); + gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), save_messages); + gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), open_filters); + gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), save_filters); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit); /* Create the Help submenu */ @@ -44,6 +64,18 @@ int ui_menu_bar_create(GtkWidget *vbox) /* Add the menubar to the vbox */ gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3); + g_signal_connect(G_OBJECT(open_messages), "activate", + G_CALLBACK(ui_callback_on_open_messages), NULL); + + g_signal_connect(G_OBJECT(save_messages), "activate", + G_CALLBACK(ui_callback_on_save_messages), NULL); + + g_signal_connect(G_OBJECT(open_filters), "activate", + G_CALLBACK(ui_callback_on_open_filters), NULL); + + g_signal_connect(G_OBJECT(save_filters), "activate", + G_CALLBACK(ui_callback_on_save_filters), NULL); + g_signal_connect(G_OBJECT(quit), "activate", G_CALLBACK(gtk_main_quit), NULL); @@ -70,6 +102,7 @@ int ui_toolbar_create(GtkWidget *vbox) gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2); +#if 0 /* Not useful anymore, signals list is cleared before every new replay file opening or remote connection */ /* 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); @@ -83,18 +116,55 @@ int ui_toolbar_create(GtkWidget *vbox) g_signal_connect(G_OBJECT(ui_main_data.signals_clear_button), "clicked", G_CALLBACK(ui_callback_signal_clear_list), NULL); } +#endif /* 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"); + "Open messages 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); + G_CALLBACK(ui_callback_on_open_messages), NULL); + } + + /* Button to save replay file */ + { + ui_main_data.save_replay_file = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE); + gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.save_replay_file), + "Save messages file"); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.save_replay_file, -1); + + g_signal_connect(G_OBJECT(ui_main_data.save_replay_file), "clicked", + G_CALLBACK(ui_callback_on_save_messages), NULL); + } + +#if 0 /* Too much button in the bar, it is confusing ! */ + /* Button to open filters file */ + { + ui_main_data.open_filters_file = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); + gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.open_filters_file), + "Open filters file"); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.open_filters_file, -1); + + g_signal_connect(G_OBJECT(ui_main_data.open_filters_file), "clicked", + G_CALLBACK(ui_callback_on_open_filters), NULL); + } + + /* Button to save filters file */ + { + ui_main_data.save_filters_file = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE); + gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.save_filters_file), + "Save filters file"); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), ui_main_data.save_filters_file, -1); + + g_signal_connect(G_OBJECT(ui_main_data.save_filters_file), "clicked", + G_CALLBACK(ui_callback_on_save_filters), NULL); } +#endif +#if 0 /* This function is already handled by GTK */ /* Button to go given signal number */ { ui_main_data.signals_go_to_button = gtk_tool_button_new_from_stock(GTK_STOCK_INDEX); @@ -108,6 +178,7 @@ int ui_toolbar_create(GtkWidget *vbox) g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_button), "clicked", G_CALLBACK(ui_callback_signal_go_to), NULL); } +#endif /* Button to go to first signal in list */ { diff --git a/common/utils/itti_analyzer/libui/ui_menu_bar.h b/common/utils/itti_analyzer/libui/ui_menu_bar.h index 22532079455e19d734527e8cc1b23b12af2be3fd..529a0674c384907a97ea01a26deb792e264e7e86 100644 --- a/common/utils/itti_analyzer/libui/ui_menu_bar.h +++ b/common/utils/itti_analyzer/libui/ui_menu_bar.h @@ -1,6 +1,8 @@ #ifndef UI_MENU_BAR_H_ #define UI_MENU_BAR_H_ +void ui_set_sensitive_move_buttons(gboolean enable); + int ui_menu_bar_create(GtkWidget *vbox); int ui_toolbar_create(GtkWidget *vbox); diff --git a/common/utils/itti_analyzer/libui/ui_notifications.c b/common/utils/itti_analyzer/libui/ui_notifications.c index 15caa49c89b1e07ab4140e26f38d825eeb448e05..dbafad8511536e4da86ff67fd3a6cfcc7bd42003 100644 --- a/common/utils/itti_analyzer/libui/ui_notifications.c +++ b/common/utils/itti_analyzer/libui/ui_notifications.c @@ -10,6 +10,7 @@ #include "ui_interface.h" #include "ui_main_screen.h" +#include "ui_menu_bar.h" #include "ui_notifications.h" #include "ui_callbacks.h" @@ -33,14 +34,16 @@ int ui_enable_connect_button(void) return RC_OK; } -int ui_file_chooser(void) +int ui_messages_open_file_chooser(void) { GtkWidget *filechooser; int result = RC_OK; filechooser = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (ui_main_data.window), - GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); /* Process the response */ if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) @@ -50,14 +53,22 @@ int ui_file_chooser(void) int read_data = 0; void *input_data = NULL; size_t input_data_length = 0; + int read_messages = 0; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); source = open (filename, O_RDONLY); - if (source >= 0) + if (source < 0) + { + g_warning ("Failed to open file \"%s\": %s", filename, g_strerror (errno)); + result = RC_FAIL; + } + else { itti_socket_header_t message_header; + ui_callback_signal_clear_list(NULL, NULL, NULL); + do { read_data = read (source, &message_header, sizeof(itti_socket_header_t)); @@ -106,6 +117,7 @@ int ui_file_chooser(void) buffer->message_number = itti_signal_header->message_number; ui_signal_add_to_list (buffer, NULL); + read_messages ++; break; } @@ -124,7 +136,13 @@ int ui_file_chooser(void) } } while (read_data > 0); - g_debug ("Read %d message from file \"%s\"\n", ui_main_data.nb_message_received, filename); + if (read_messages > 0) + { + /* Enable buttons to move in the list of signals */ + ui_set_sensitive_move_buttons(TRUE); + } + + g_debug ("Read %d messages from file \"%s\"\n", read_messages, filename); close (source); } @@ -137,6 +155,63 @@ int ui_file_chooser(void) return result; } +int ui_filters_open_file_chooser(void) +{ + GtkWidget *filechooser; + int result = RC_OK; + + filechooser = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (ui_main_data.window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + + /* Process the response */ + if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) + { + char *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); + + g_free (filename); + } + + gtk_widget_destroy (filechooser); + + return RC_OK; +} + +int ui_filters_save_file_chooser(void) +{ + GtkWidget *filechooser; + int result = RC_OK; + + filechooser = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (ui_main_data.window), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filechooser), TRUE); + + //gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filechooser), "filters.xml"); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser), "./filters.xml"); + + /* Process the response */ + if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) + { + char *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); + + g_free (filename); + } + + gtk_widget_destroy (filechooser); + + return RC_OK; +} + int ui_progress_bar_set_fraction(double fraction) { // /* If not exist instantiate */ diff --git a/common/utils/itti_analyzer/libui/ui_notifications.h b/common/utils/itti_analyzer/libui/ui_notifications.h index 4cee44c3546b5fd1c4578fd53106ca2a9a719c58..fcb38540f82328da751a8909e8527e731675c26c 100644 --- a/common/utils/itti_analyzer/libui/ui_notifications.h +++ b/common/utils/itti_analyzer/libui/ui_notifications.h @@ -5,7 +5,11 @@ int ui_disable_connect_button(void); int ui_enable_connect_button(void); -int ui_file_chooser(void); +int ui_messages_open_file_chooser(void); + +int ui_filters_open_file_chooser(void); + +int ui_filters_save_file_chooser(void); int ui_progress_bar_set_fraction(double fraction); diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.c b/common/utils/itti_analyzer/libui/ui_tree_view.c index 269f65ad2c1719da94e382f7f322593642b8b50b..dcbadd65593ba05d6d3250a93a19ae3eaed6788c 100644 --- a/common/utils/itti_analyzer/libui/ui_tree_view.c +++ b/common/utils/itti_analyzer/libui/ui_tree_view.c @@ -28,14 +28,20 @@ ui_tree_view_init_list(GtkWidget *list) column = gtk_tree_view_column_new_with_attributes( "Signal", renderer, "text", COL_SIGNAL, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); + g_signal_connect(G_OBJECT(column), "clicked", + G_CALLBACK(ui_callback_on_tree_column_header_click_signal), NULL); column = gtk_tree_view_column_new_with_attributes( "From", renderer, "text", COL_FROM_TASK, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); + g_signal_connect(G_OBJECT(column), "clicked", + G_CALLBACK(ui_callback_on_tree_column_header_click_from), NULL); column = gtk_tree_view_column_new_with_attributes( "To", renderer, "text", COL_TO_TASK, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); + g_signal_connect(G_OBJECT(column), "clicked", + G_CALLBACK(ui_callback_on_tree_column_header_click_to), NULL); store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, @@ -86,6 +92,9 @@ void ui_tree_view_destroy_list(GtkWidget *list) store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); gtk_list_store_clear(store); + + /* Reset number of messages */ + ui_main_data.nb_message_received = 0; } int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox) @@ -112,6 +121,7 @@ int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox) ui_main_data.signalslist); ui_tree_view_init_list(ui_main_data.signalslist); + gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(ui_main_data.signalslist), TRUE); gtk_widget_set_size_request(GTK_WIDGET(scrolled_window), 500, -1); gtk_box_pack_start(GTK_BOX(hbox), scrolled_window, FALSE, FALSE, 0); @@ -141,13 +151,21 @@ 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) +void ui_tree_view_select_row(gint row, GtkTreePath **path) { - GtkTreePath *path; + GtkTreePath *path_row; 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); + path_row = gtk_tree_path_new_from_string(indice); + /* Select the message in requested row */ + gtk_tree_view_set_cursor(GTK_TREE_VIEW(ui_main_data.signalslist), path_row, NULL, FALSE); + /* Center the message in the middle of the list if possible */ + gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(ui_main_data.signalslist), path_row, NULL, TRUE, 0.5, 0.0); + + if (path != NULL) + { + *path = path_row; + } } diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.h b/common/utils/itti_analyzer/libui/ui_tree_view.h index 83691c664121506582e28ccd5a19e7678cae5505..e04224c8578dbb0eac11a955818009d691637e51 100644 --- a/common/utils/itti_analyzer/libui/ui_tree_view.h +++ b/common/utils/itti_analyzer/libui/ui_tree_view.h @@ -1,7 +1,7 @@ #ifndef UI_TREE_VIEW_H_ #define UI_TREE_VIEW_H_ -enum +typedef enum { COL_MSG_NUM = 0, COL_SIGNAL, @@ -9,7 +9,7 @@ enum COL_TO_TASK, COL_BUFFER, NUM_COLS -}; +} col_type_e; int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox); @@ -18,6 +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); +void ui_tree_view_select_row(gint row, GtkTreePath **path); #endif /* UI_TREE_VIEW_H_ */