ui_tree_view.c 10.7 KB
Newer Older
Cedric Roux's avatar
   
Cedric Roux committed
1
2
3
4
5
#include <stdlib.h>
#include <stdint.h>

#include <gtk/gtk.h>

6
#include "rc.h"
Cedric Roux's avatar
   
Cedric Roux committed
7

Cedric Roux's avatar
Cedric Roux committed
8
9
#include "buffers.h"

Cedric Roux's avatar
   
Cedric Roux committed
10
11
12
#include "ui_main_screen.h"
#include "ui_tree_view.h"
#include "ui_callbacks.h"
13
#include "ui_filters.h"
Cedric Roux's avatar
   
Cedric Roux committed
14
15
16

#include "ui_signal_dissect_view.h"

17
18
19
20
typedef struct
{
    GtkListStore *store;
    GtkTreeModelFilter *filtered;
winckel's avatar
winckel committed
21
22
    uint32_t filtered_last_msg;
    uint32_t filtered_msg_number;
winckel's avatar
winckel committed
23
    uint32_t instance_number;
24
25
26
27
28
29
} ui_store_t;

static ui_store_t ui_store;

static gboolean ui_tree_filter_messages(GtkTreeModel *model, GtkTreeIter *iter, ui_store_t *store)
{
winckel's avatar
winckel committed
30
    uint32_t msg_number;
31
32
33
    uint32_t message_id;
    uint32_t origin_task_id;
    uint32_t destination_task_id;
winckel's avatar
winckel committed
34
35
    uint32_t instance;

36
    gboolean enabled = FALSE;
37

38
    gtk_tree_model_get (model, iter, COL_MSG_NUM, &msg_number, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, &origin_task_id,
winckel's avatar
winckel committed
39
                        COL_TO_TASK_ID, &destination_task_id, COL_INSTANCE, &instance, -1);
winckel's avatar
winckel committed
40
    if (msg_number != 0)
41
    {
winckel's avatar
winckel committed
42
        enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance);
43

winckel's avatar
winckel committed
44
        if ((enabled) && (ui_store.filtered_last_msg < msg_number))
45
        {
winckel's avatar
winckel committed
46
            ui_store.filtered_last_msg = msg_number;
47
48
            ui_store.filtered_msg_number++;
        }
winckel's avatar
winckel committed
49
        g_debug("%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, ui_store.filtered_msg_number);
50
    }
51
52
53
54

    return enabled;
}

Cedric Roux's avatar
   
Cedric Roux committed
55
static void
Cedric Roux's avatar
Cedric Roux committed
56
ui_tree_view_init_list(GtkWidget *list)
Cedric Roux's avatar
   
Cedric Roux committed
57
{
58
59
    GtkCellRenderer *renderer_left;
    GtkCellRenderer *renderer_right;
Cedric Roux's avatar
   
Cedric Roux committed
60
61
    GtkTreeViewColumn *column;

62
    renderer_left = gtk_cell_renderer_text_new();
63
    gtk_cell_renderer_set_padding (renderer_left, 5, 0);
64
65

    renderer_right = gtk_cell_renderer_text_new();
66
67
    gtk_cell_renderer_set_alignment (renderer_right, 1, 0.5);
    gtk_cell_renderer_set_padding (renderer_right, 5, 0);
68
69
70

    column = gtk_tree_view_column_new_with_attributes(
        "MN", renderer_right, "text", COL_MSG_NUM, NULL);
71
    gtk_tree_view_column_set_resizable (column, TRUE);
72
73
74
    gtk_tree_view_column_set_alignment (column, 0.5);
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);

Cedric Roux's avatar
   
Cedric Roux committed
75
    column = gtk_tree_view_column_new_with_attributes(
76
        "LTE Time", renderer_right, "text", COL_LTE_TIME, NULL);
77
    gtk_tree_view_column_set_resizable (column, TRUE);
78
    gtk_tree_view_column_set_alignment (column, 0.5);
Cedric Roux's avatar
   
Cedric Roux committed
79
80
81
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);

    column = gtk_tree_view_column_new_with_attributes(
82
        "Signal", renderer_left, "text", COL_MESSAGE, NULL);
83
    gtk_tree_view_column_set_resizable (column, TRUE);
84
    gtk_tree_view_column_set_alignment (column, 0.5);
Cedric Roux's avatar
   
Cedric Roux committed
85
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
86
    g_signal_connect(G_OBJECT(column), "clicked",
87
                     G_CALLBACK(ui_callback_on_tree_column_header_click), (gpointer) COL_MESSAGE);
Cedric Roux's avatar
   
Cedric Roux committed
88

Cedric Roux's avatar
Cedric Roux committed
89
    column = gtk_tree_view_column_new_with_attributes(
90
91
        "From", renderer_left, "text", COL_FROM_TASK, NULL);
    gtk_tree_view_column_set_alignment (column, 0.5);
92
    gtk_tree_view_column_set_resizable (column, TRUE);
Cedric Roux's avatar
Cedric Roux committed
93
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
94
    g_signal_connect(G_OBJECT(column), "clicked",
winckel's avatar
winckel committed
95
                     G_CALLBACK(ui_callback_on_tree_column_header_click), (gpointer) COL_FROM_TASK);
Cedric Roux's avatar
Cedric Roux committed
96
97

    column = gtk_tree_view_column_new_with_attributes(
98
99
        "To", renderer_left, "text", COL_TO_TASK, NULL);
    gtk_tree_view_column_set_alignment (column, 0.5);
100
    gtk_tree_view_column_set_resizable (column, TRUE);
Cedric Roux's avatar
Cedric Roux committed
101
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
102
    g_signal_connect(G_OBJECT(column), "clicked",
winckel's avatar
winckel committed
103
                     G_CALLBACK(ui_callback_on_tree_column_header_click), (gpointer) COL_TO_TASK);
Cedric Roux's avatar
Cedric Roux committed
104

winckel's avatar
winckel committed
105
    column = gtk_tree_view_column_new_with_attributes(
106
107
        "Ins", renderer_right, "text", COL_INSTANCE, NULL);
    gtk_tree_view_column_set_alignment (column, 0.5);
winckel's avatar
winckel committed
108
    gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
winckel's avatar
winckel committed
109
110
    g_signal_connect(G_OBJECT(column), "clicked",
                     G_CALLBACK(ui_callback_on_tree_column_header_click), (gpointer) COL_INSTANCE);
winckel's avatar
winckel committed
111

112
    ui_store.store = gtk_list_store_new(NUM_COLS,
winckel's avatar
winckel committed
113
                                       G_TYPE_UINT,   // COL_MSG_NUM
114
                                       G_TYPE_STRING, // COL_LTE_TIME
winckel's avatar
winckel committed
115
116
117
118
119
120
121
122
123
                                       G_TYPE_STRING, // COL_SIGNAL
                                       G_TYPE_STRING, // COL_FROM_TASK
                                       G_TYPE_STRING, // COL_TO_TASK
                                       G_TYPE_UINT,   // COL_INSTANCE
                                       /* HACK: add id of message fields to speed-up filtering
                                        */
                                       G_TYPE_UINT, // COL_SIGNAL_ID
                                       G_TYPE_UINT, // COL_FROM_TASK_ID
                                       G_TYPE_UINT, // COL_TO_TASK_ID
124
125
126
127
128
                                       /* HACK: add a reference to the buffer here
                                        * to avoid maintining multiple lists.
                                        * The reference is not displayed
                                        */
                                       G_TYPE_POINTER);
Cedric Roux's avatar
   
Cedric Roux committed
129

winckel's avatar
winckel committed
130
131
132
133
134
    if(ui_store.store == NULL)
    {
        g_error("gtk_list_store_new failed");
    }

135
136
137
138
    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);
Cedric Roux's avatar
   
Cedric Roux committed
139

140
    gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(ui_store.filtered));
Cedric Roux's avatar
Cedric Roux committed
141

142
    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(list));
Cedric Roux's avatar
   
Cedric Roux committed
143
144
}

145
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,
146
147
                                     const uint32_t origin_task_id, const char *origin_task,
                                     const uint32_t destination_task_id, const char *destination_task, uint32_t instance, gpointer buffer)
Cedric Roux's avatar
   
Cedric Roux committed
148
149
150
{
    GtkTreeIter iter;

151
152
    gtk_list_store_append(ui_store.store, &iter);
    gtk_list_store_set(ui_store.store, &iter,
Cedric Roux's avatar
Cedric Roux committed
153
                       /* Columns */
winckel's avatar
winckel committed
154
                       COL_MSG_NUM      , message_number,
155
                       COL_LTE_TIME     , lte_time,
156
                       COL_MESSAGE      , signal_name,
winckel's avatar
winckel committed
157
                       COL_FROM_TASK    , origin_task,
158
                       COL_TO_TASK      , destination_task,
winckel's avatar
winckel committed
159
                       COL_INSTANCE     , instance,
160
161
162
                       COL_MESSAGE_ID   , message_id,
                       COL_FROM_TASK_ID , origin_task_id,
                       COL_TO_TASK_ID   , destination_task_id,
winckel's avatar
winckel committed
163
                       COL_BUFFER       , buffer,
Cedric Roux's avatar
Cedric Roux committed
164
165
                       /* End of columns */
                       -1);
Cedric Roux's avatar
   
Cedric Roux committed
166
167
168
169
170
171
}

void ui_tree_view_destroy_list(GtkWidget *list)
{
    g_assert(list != NULL);

172
    gtk_list_store_clear(ui_store.store);
173
174
    ui_store.filtered_last_msg = 0;
    ui_store.filtered_msg_number = 0;
winckel's avatar
winckel committed
175
    ui_store.instance_number = 0;
176
177
178

    /* Reset number of messages */
    ui_main_data.nb_message_received = 0;
winckel's avatar
winckel committed
179
    ui_main_data.path_last = NULL;
Cedric Roux's avatar
   
Cedric Roux committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
}

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.signalslist = gtk_tree_view_new();
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(ui_main_data.signalslist), TRUE);

    /* Disable multiple selection */
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ui_main_data.signalslist));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);

200
    hbox = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
Cedric Roux's avatar
   
Cedric Roux committed
201

202
    gtk_container_add(GTK_CONTAINER(scrolled_window), ui_main_data.signalslist);
Cedric Roux's avatar
   
Cedric Roux committed
203

Cedric Roux's avatar
Cedric Roux committed
204
    ui_tree_view_init_list(ui_main_data.signalslist);
205
    gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(ui_main_data.signalslist), TRUE);
Cedric Roux's avatar
   
Cedric Roux committed
206

207
208
    gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scrolled_window), 600);
    gtk_paned_pack1 (GTK_PANED (hbox), scrolled_window, FALSE, TRUE);
Cedric Roux's avatar
Cedric Roux committed
209
    ui_main_data.text_view = ui_signal_dissect_new(hbox);
Cedric Roux's avatar
   
Cedric Roux committed
210
211
212
213

    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);

    /* Connect callback on row selection */
Cedric Roux's avatar
Cedric Roux committed
214
215
    gtk_tree_selection_set_select_function(selection, ui_callback_on_select_signal,
                                           ui_main_data.text_view, NULL);
Cedric Roux's avatar
   
Cedric Roux committed
216

winckel's avatar
winckel committed
217
218
219
220
    ui_store.filtered_last_msg = 0;
    ui_store.filtered_msg_number = 0;
    ui_store.instance_number = 0;

221
222
    ui_main_data.selection = selection;

Cedric Roux's avatar
   
Cedric Roux committed
223
224
225
    return 0;
}

226
int ui_tree_view_new_signal_ind(const uint32_t message_number, const gchar *lte_time,
227
228
229
230
                                const uint32_t message_id, const char *message_name,
                                const uint32_t origin_task_id, const char *origin_task,
                                const uint32_t destination_task_id, const char *destination_task,
                                uint32_t instance, gpointer buffer)
Cedric Roux's avatar
   
Cedric Roux committed
231
{
winckel's avatar
winckel committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    if(ui_store.instance_number < (instance + 1))
    {
        int i;
        char name[10];

        for (i = ui_store.instance_number; i <= instance; i++)
        {
            sprintf (name, "%d", i);
            ui_filters_add (FILTER_INSTANCES, i, name, ENTRY_ENABLED_TRUE);
        }
        ui_store.instance_number = (instance + 1);
        ui_destroy_filter_menu(FILTER_INSTANCES);
    }

246
    ui_tree_view_add_to_list(ui_main_data.signalslist, lte_time, message_number, message_id, message_name,
247
                             origin_task_id, origin_task, destination_task_id, destination_task, instance, (buffer_t *)buffer);
Cedric Roux's avatar
   
Cedric Roux committed
248
249
250

    return RC_OK;
}
251

252
void ui_tree_view_select_row(gint row, GtkTreePath **path)
253
{
254
    GtkTreePath *path_row;
255

256
    path_row = gtk_tree_path_new_from_indices(row, -1);
257
258
259
260
261
262
263
264
265
    /* 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;
    }
266
}
267
268
269

void ui_tree_view_refilter(void)
{
270
271
272
273
274
275
276
277
    ui_store.filtered_last_msg = 0;
    ui_store.filtered_msg_number = 0;
    gtk_tree_model_filter_refilter (ui_store.filtered);
}

guint ui_tree_view_get_filtered_number(void)
{
    return ui_store.filtered_msg_number;
278
}