git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7885 818b1a75-f10b-46b9-bf7c-635c3b92a50f
620 lines
23 KiB
C
620 lines
23 KiB
C
/*
|
|
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* The views and conclusions contained in the software and documentation are those
|
|
* of the authors and should not be interpreted as representing official policies,
|
|
* either expressed or implied, of the FreeBSD Project.
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
#define G_LOG_DOMAIN ("UI_TREE")
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "logs.h"
|
|
#include "rc.h"
|
|
|
|
#include "buffers.h"
|
|
|
|
#include "ui_main_screen.h"
|
|
#include "ui_tree_view.h"
|
|
#include "ui_callbacks.h"
|
|
#include "ui_filters.h"
|
|
|
|
#include "ui_signal_dissect_view.h"
|
|
|
|
typedef struct
|
|
{
|
|
GtkListStore *store;
|
|
GtkTreeModelFilter *filtered;
|
|
uint32_t filtered_last_msg;
|
|
uint32_t filtered_msg_number;
|
|
uint32_t instance_number;
|
|
} ui_store_t;
|
|
|
|
static ui_store_t ui_store;
|
|
|
|
GtkWidget *ui_tree_view_menu;
|
|
ui_tree_view_menu_enable_t ui_tree_view_menu_enable[NUM_MENU_TYPE];
|
|
|
|
GdkEventButton *ui_tree_view_last_event;
|
|
|
|
static gboolean ui_tree_filter_messages(GtkTreeModel *model, GtkTreeIter *iter, ui_store_t *store)
|
|
{
|
|
uint32_t msg_number;
|
|
uint32_t message_id;
|
|
uint32_t origin_task_id;
|
|
uint32_t destination_task_id;
|
|
uint32_t instance;
|
|
|
|
gboolean enabled = TRUE;
|
|
|
|
if (ui_filters.filters_enabled)
|
|
{
|
|
gtk_tree_model_get (model, iter, COL_MSG_NUM, &msg_number, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID,
|
|
&origin_task_id, COL_TO_TASK_ID, &destination_task_id, COL_INSTANCE_ID, &instance, -1);
|
|
if (msg_number != 0)
|
|
{
|
|
enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance);
|
|
|
|
if ((enabled) && (store->filtered_last_msg < msg_number))
|
|
{
|
|
store->filtered_last_msg = msg_number;
|
|
store->filtered_msg_number++;
|
|
}
|
|
g_debug("ui_tree_filter_messages: %p %p %d m:%d o:%d d:%d i:%d %d %d", model, iter, msg_number, message_id, origin_task_id, destination_task_id, instance, enabled, store->filtered_msg_number);
|
|
}
|
|
}
|
|
|
|
return enabled;
|
|
}
|
|
|
|
static gboolean onButtonPressed(GtkWidget *treeview, GdkEventButton *event, gpointer userdata)
|
|
{
|
|
g_info("onButtonPressed %p %p %p %d %d", treeview, event, userdata, event->type, event->button);
|
|
ui_tree_view_last_event = event;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
static gboolean onButtonRelease(GtkWidget *treeview, GdkEventButton *event, gpointer userdata)
|
|
{
|
|
g_info("onButtonRelease %p %p %p %d %d", treeview, event, userdata, event->type, event->button);
|
|
// last_event = event;
|
|
|
|
return FALSE;
|
|
}
|
|
*/
|
|
|
|
static void ui_tree_view_init_list(GtkWidget *list)
|
|
{
|
|
GtkCellRenderer *renderer_left;
|
|
GtkCellRenderer *renderer_right;
|
|
GtkTreeViewColumn *column;
|
|
|
|
renderer_left = gtk_cell_renderer_text_new ();
|
|
gtk_cell_renderer_set_padding (renderer_left, 5, 0);
|
|
|
|
renderer_right = gtk_cell_renderer_text_new ();
|
|
gtk_cell_renderer_set_alignment (renderer_right, 1, 0.5);
|
|
gtk_cell_renderer_set_padding (renderer_right, 5, 0);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("MN", renderer_right, "text", COL_MSG_NUM, "foreground",
|
|
COL_FOREGROUND, "background", COL_BACKGROUND, NULL);
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW(list), column);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("LTE Time", renderer_right, "text", COL_LTE_TIME, NULL);
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW(list), column);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("Message", renderer_left, "text", COL_MESSAGE, "foreground",
|
|
COL_FOREGROUND, "background", COL_BACKGROUND, "strikethrough",
|
|
COL_STRIKETHROUGH, "style", COL_STYLE, "weight", COL_WEIGHT, "underline", COL_UNDERLINE, NULL);
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
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),
|
|
(gpointer) COL_MESSAGE);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("From", renderer_left, "text", COL_FROM_TASK, NULL);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
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),
|
|
(gpointer) COL_FROM_TASK);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("To", renderer_left, "text", COL_TO_TASK, NULL);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
|
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),
|
|
(gpointer) COL_TO_TASK);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes ("Ins", renderer_right, "text", COL_INSTANCE, NULL);
|
|
gtk_tree_view_column_set_alignment (column, 0.5);
|
|
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),
|
|
(gpointer) COL_INSTANCE);
|
|
|
|
ui_store.store = gtk_list_store_new (NUM_COLS, // Number of columns
|
|
// Displayed columns
|
|
G_TYPE_UINT, // COL_MSG_NUM
|
|
G_TYPE_STRING, // COL_LTE_TIME
|
|
G_TYPE_STRING, // COL_MESSAGE
|
|
G_TYPE_STRING, // COL_FROM_TASK
|
|
G_TYPE_STRING, // COL_TO_TASK
|
|
G_TYPE_STRING, // COL_INSTANCE
|
|
// Not displayed columns
|
|
// Id of some message fields to speed-up filtering
|
|
G_TYPE_UINT, // COL_MESSAGE_ID
|
|
G_TYPE_UINT, // COL_FROM_TASK_ID
|
|
G_TYPE_UINT, // COL_TO_TASK_ID
|
|
G_TYPE_UINT, // COL_INSTANCE_ID
|
|
G_TYPE_STRING, // COL_FOREGROUND
|
|
G_TYPE_STRING, // COL_BACKGROUND
|
|
G_TYPE_BOOLEAN, // COL_STRIKETHROUGH
|
|
G_TYPE_UINT,
|
|
G_TYPE_UINT,
|
|
G_TYPE_UINT,
|
|
// Reference to the buffer here to avoid maintaining multiple lists.
|
|
G_TYPE_POINTER);
|
|
|
|
if (ui_store.store == NULL)
|
|
{
|
|
g_error("gtk_list_store_new failed");
|
|
}
|
|
|
|
ui_store.filtered = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (ui_store.store), NULL));
|
|
gtk_tree_model_filter_set_visible_func (ui_store.filtered, (GtkTreeModelFilterVisibleFunc) ui_tree_filter_messages,
|
|
&ui_store, NULL);
|
|
|
|
gtk_tree_view_set_model (GTK_TREE_VIEW(list), GTK_TREE_MODEL(ui_store.filtered));
|
|
|
|
gtk_tree_view_columns_autosize (GTK_TREE_VIEW(list));
|
|
}
|
|
|
|
static void ui_tree_view_add_to_list(GtkWidget *list, const gchar *lte_time, const uint32_t message_number,
|
|
const uint32_t message_id, const gchar *signal_name, const uint32_t origin_task_id,
|
|
const char *origin_task_name, const uint32_t destination_task_id,
|
|
const char *destination_task_name, uint32_t instance_id, const char *instance_name, gpointer buffer)
|
|
{
|
|
static int counter = 0;
|
|
|
|
GtkTreeIter iter;
|
|
gboolean enabled;
|
|
int message_index;
|
|
|
|
g_info("ui_tree_view_add_to_list: %d %d %d %d %d", message_number, message_id, origin_task_id, destination_task_id, instance_id);
|
|
|
|
enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance_id);
|
|
message_index = ui_filters_search_id (&ui_filters.messages, message_id);
|
|
|
|
g_info("ui_tree_view_add_to_list: %d %d", enabled, message_index);
|
|
|
|
gtk_list_store_append (ui_store.store, &iter);
|
|
gtk_list_store_set (ui_store.store, &iter,
|
|
/* Columns */
|
|
COL_MSG_NUM,
|
|
message_number, COL_LTE_TIME, lte_time, COL_MESSAGE, signal_name, COL_FROM_TASK, origin_task_name,
|
|
COL_TO_TASK, destination_task_name, COL_INSTANCE, instance_name, COL_MESSAGE_ID, message_id,
|
|
COL_FROM_TASK_ID, origin_task_id, COL_TO_TASK_ID, destination_task_id, COL_INSTANCE_ID, instance_id,
|
|
COL_BUFFER, buffer, COL_FOREGROUND, ui_filters.messages.items[message_index].foreground, COL_BACKGROUND,
|
|
ui_filters.messages.items[message_index].background, COL_STRIKETHROUGH, !enabled,
|
|
// COL_STYLE, (counter % 2) == 0 ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
|
|
// COL_WEIGHT, ((counter + 2) % 4) < 2 ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
|
|
// COL_UNDERLINE, ((counter + 4) % 8) < 4 ?PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE,
|
|
COL_STYLE, PANGO_STYLE_NORMAL,
|
|
COL_WEIGHT, PANGO_WEIGHT_NORMAL,
|
|
COL_UNDERLINE, PANGO_UNDERLINE_NONE,
|
|
/* End of columns */
|
|
-1);
|
|
counter++;
|
|
}
|
|
|
|
void ui_tree_view_destroy_list(GtkWidget *list)
|
|
{
|
|
g_assert(list != NULL);
|
|
|
|
gtk_list_store_clear (ui_store.store);
|
|
ui_store.filtered_last_msg = 0;
|
|
ui_store.filtered_msg_number = 0;
|
|
ui_store.instance_number = 0;
|
|
|
|
/* Reset number of messages */
|
|
ui_main_data.nb_message_received = 0;
|
|
}
|
|
|
|
/* Search for the message with its message number equal to the given value or the previous one */
|
|
static gboolean ui_tree_view_search(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter,
|
|
gpointer search_data)
|
|
{
|
|
uint32_t msg_number;
|
|
uint32_t key_value = atoi (key);
|
|
|
|
gtk_tree_model_get (model, iter, column, &msg_number, -1);
|
|
|
|
g_debug("ui_tree_view_search %d %d", key_value, msg_number);
|
|
|
|
if (key_value == msg_number)
|
|
{
|
|
/* Value found, use this message */
|
|
return 0;
|
|
}
|
|
|
|
{
|
|
GtkTreeIter iter_next = *iter;
|
|
|
|
if (gtk_tree_model_iter_next (model, &iter_next))
|
|
{
|
|
gtk_tree_model_get (model, &iter_next, column, &msg_number, -1);
|
|
|
|
if (key_value < msg_number)
|
|
{
|
|
/* Next value will be greater, use this message */
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Last value, use this message */
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void ui_tree_view_create_menu(GtkWidget **menu)
|
|
{
|
|
GtkWidget *menu_items;
|
|
|
|
*menu = gtk_menu_new ();
|
|
|
|
/* Create the "Message enable" menu-item */
|
|
{
|
|
/* Create a new menu-item */
|
|
menu_items = gtk_check_menu_item_new ();
|
|
ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable = menu_items;
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable),
|
|
&ui_tree_view_menu_enable[MENU_MESSAGE]);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
|
|
/* Create the "Destination task enable" menu-item */
|
|
{
|
|
/* Create a new menu-item */
|
|
menu_items = gtk_check_menu_item_new ();
|
|
ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable = menu_items;
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable),
|
|
&ui_tree_view_menu_enable[MENU_FROM_TASK]);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
|
|
/* Create the "Origin task enable" menu-item */
|
|
{
|
|
/* Create a new menu-item */
|
|
menu_items = gtk_check_menu_item_new ();
|
|
ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable = menu_items;
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable),
|
|
&ui_tree_view_menu_enable[MENU_TO_TASK]);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
|
|
/* Create the "Instance enable" menu-item */
|
|
{
|
|
/* Create a new menu-item */
|
|
menu_items = gtk_check_menu_item_new ();
|
|
ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable = menu_items;
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable),
|
|
&ui_tree_view_menu_enable[MENU_INSTANCE]);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
|
|
/* Create the "Foreground color" menu-item */
|
|
{
|
|
static ui_tree_view_menu_color_t menu_color_foreground =
|
|
{TRUE, &ui_tree_view_menu_enable[MENU_MESSAGE]};
|
|
|
|
/* Create a new menu-item with a name */
|
|
menu_items = gtk_menu_item_new_with_label ("Select message foreground color");
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_color),
|
|
&menu_color_foreground);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
|
|
/* Create the "Background color" menu-item */
|
|
{
|
|
static ui_tree_view_menu_color_t menu_color_background =
|
|
{FALSE, &ui_tree_view_menu_enable[MENU_MESSAGE]};
|
|
|
|
/* Create a new menu-item with a name */
|
|
menu_items = gtk_menu_item_new_with_label ("Select message background color");
|
|
|
|
/* Add it to the menu. */
|
|
gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items);
|
|
g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_color),
|
|
&menu_color_background);
|
|
|
|
/* Show the widget */
|
|
gtk_widget_show (menu_items);
|
|
}
|
|
}
|
|
|
|
int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox)
|
|
{
|
|
GtkWidget *hbox;
|
|
GtkTreeSelection *selection;
|
|
GtkWidget *scrolled_window;
|
|
|
|
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
|
|
|
|
ui_main_data.messages_list = gtk_tree_view_new ();
|
|
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(ui_main_data.messages_list), TRUE);
|
|
gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW(ui_main_data.messages_list), ui_tree_view_search, NULL, NULL);
|
|
gtk_tree_view_set_search_entry (GTK_TREE_VIEW(ui_main_data.messages_list),
|
|
GTK_ENTRY(ui_main_data.signals_go_to_entry));
|
|
|
|
/* Disable multiple selection */
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(ui_main_data.messages_list));
|
|
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
|
|
|
hbox = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
|
|
|
gtk_container_add (GTK_CONTAINER(scrolled_window), ui_main_data.messages_list);
|
|
|
|
ui_tree_view_init_list (ui_main_data.messages_list);
|
|
gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(ui_main_data.messages_list), TRUE);
|
|
|
|
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW(scrolled_window), 680);
|
|
gtk_paned_pack1 (GTK_PANED (hbox), scrolled_window, FALSE, TRUE);
|
|
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.messages_list), "button-press-event", G_CALLBACK (onButtonPressed), NULL);
|
|
// g_signal_connect(G_OBJECT(ui_main_data.signalslist), "button-release-event", G_CALLBACK (onButtonRelease), 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_store.filtered_last_msg = 0;
|
|
ui_store.filtered_msg_number = 0;
|
|
ui_store.instance_number = 0;
|
|
|
|
ui_main_data.selection = selection;
|
|
|
|
ui_tree_view_create_menu (&ui_tree_view_menu);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ui_tree_view_new_signal_ind(const uint32_t message_number, const gchar *lte_time, const uint32_t message_id,
|
|
const char *message_name, const uint32_t origin_task_id, const char *origin_task_name,
|
|
const uint32_t destination_task_id, const char *destination_task_name, uint32_t instance_id,
|
|
gpointer buffer)
|
|
{
|
|
char *instance_name = NULL;
|
|
char instance_name_buffer[10];
|
|
|
|
if (((instance_t) instance_id) < INSTANCE_DEFAULT)
|
|
{
|
|
if (ui_store.instance_number < (instance_id + 1))
|
|
{
|
|
int i;
|
|
|
|
for (i = ui_store.instance_number; i <= instance_id; i++)
|
|
{
|
|
sprintf (instance_name_buffer, "%d", i);
|
|
ui_filters_add (FILTER_INSTANCES, i, instance_name_buffer, ENTRY_ENABLED_TRUE, NULL, NULL);
|
|
}
|
|
ui_store.instance_number = (instance_id + 1);
|
|
ui_destroy_filter_menu (FILTER_INSTANCES);
|
|
}
|
|
|
|
sprintf (instance_name_buffer, "%d", instance_id);
|
|
instance_name = instance_name_buffer;
|
|
}
|
|
else
|
|
{
|
|
switch ((instance_t) instance_id)
|
|
{
|
|
case INSTANCE_DEFAULT:
|
|
instance_name = "DEF";
|
|
break;
|
|
|
|
case INSTANCE_ALL:
|
|
instance_name = "ALL";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ((instance_name != NULL) && (ui_filters_search_id (&ui_filters.instances, instance_id) < 0))
|
|
{
|
|
ui_filters_add (FILTER_INSTANCES, instance_id, instance_name, ENTRY_ENABLED_TRUE, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
ui_tree_view_add_to_list (ui_main_data.messages_list, lte_time, message_number, message_id, message_name,
|
|
origin_task_id, origin_task_name, destination_task_id, destination_task_name, instance_id, instance_name,
|
|
buffer);
|
|
|
|
return RC_OK;
|
|
}
|
|
|
|
void ui_tree_view_select_row(gint row)
|
|
{
|
|
GtkTreePath *path_row;
|
|
|
|
if (row >= 0)
|
|
{
|
|
path_row = gtk_tree_path_new_from_indices (row, -1);
|
|
|
|
if ((ui_main_data.messages_list != NULL) && (path_row != NULL))
|
|
{
|
|
g_info("Select row %d", row);
|
|
|
|
/* Select the message in requested row */
|
|
gtk_tree_view_set_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), 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.messages_list), path_row, NULL, TRUE, 0.5, 0.0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static gboolean updateColors(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
|
{
|
|
uint32_t message_id;
|
|
uint32_t origin_task_id;
|
|
uint32_t destination_task_id;
|
|
uint32_t instance;
|
|
|
|
gboolean enabled = FALSE;
|
|
int message_index;
|
|
|
|
gtk_tree_model_get (model, iter, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID,
|
|
&destination_task_id, COL_INSTANCE_ID, &instance, -1);
|
|
enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance);
|
|
message_index = ui_filters_search_id (&ui_filters.messages, message_id);
|
|
|
|
gtk_list_store_set (GTK_LIST_STORE(model), iter, COL_FOREGROUND,
|
|
ui_filters.messages.items[message_index].foreground, COL_BACKGROUND,
|
|
ui_filters.messages.items[message_index].background, COL_STRIKETHROUGH, !enabled, -1);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void ui_tree_view_refilter()
|
|
{
|
|
ui_store.filtered_last_msg = 0;
|
|
ui_store.filtered_msg_number = 0;
|
|
|
|
/* Update foreground color of messages, this will also update filtered model */
|
|
if (ui_store.store != NULL)
|
|
{
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL(ui_store.store), updateColors, NULL);
|
|
|
|
if (ui_main_data.messages_list != NULL)
|
|
{
|
|
GtkTreePath *path_row;
|
|
|
|
/* Get the currently selected message */
|
|
gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), &path_row, NULL);
|
|
if (path_row != NULL)
|
|
{
|
|
/* Center the message in the middle of the list if possible */
|
|
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(ui_main_data.messages_list), path_row, NULL, TRUE, 0.5,
|
|
0.0);
|
|
g_info("ui_tree_view_refilter: center on message");
|
|
}
|
|
}
|
|
}
|
|
|
|
g_info("ui_tree_view_refilter: last message %d, %d messages displayed", ui_store.filtered_last_msg, ui_store.filtered_msg_number);
|
|
}
|
|
|
|
typedef struct foreach_message_params_s
|
|
{
|
|
message_write_callback_t callback;
|
|
gboolean filter;
|
|
} foreach_message_params_t;
|
|
|
|
static gboolean foreach_message(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
|
{
|
|
foreach_message_params_t *params = (foreach_message_params_t *) data;
|
|
const gchar *signal_name;
|
|
uint32_t message_id;
|
|
uint32_t origin_task_id;
|
|
uint32_t destination_task_id;
|
|
uint32_t instance;
|
|
gpointer buffer = NULL;
|
|
|
|
gtk_tree_model_get (model, iter, COL_MESSAGE, &signal_name, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID,
|
|
&destination_task_id, COL_INSTANCE_ID, &instance, COL_BUFFER, &buffer, -1);
|
|
|
|
if (params->filter == TRUE)
|
|
{
|
|
gboolean enabled = FALSE;
|
|
|
|
enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance);
|
|
if (enabled == FALSE)
|
|
{
|
|
buffer = NULL;
|
|
}
|
|
}
|
|
|
|
if (buffer != NULL)
|
|
{
|
|
params->callback(buffer, signal_name);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void ui_tree_view_foreach_message(message_write_callback_t callback, gboolean filter)
|
|
{
|
|
foreach_message_params_t params = {callback, filter};
|
|
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL(ui_store.store), foreach_message, (void *) ¶ms);
|
|
}
|
|
|
|
guint ui_tree_view_get_filtered_number(void)
|
|
{
|
|
return ui_store.filtered_msg_number;
|
|
}
|