ui_notifications.c 22.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * 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.
 */
ghaddab's avatar
ghaddab committed
29 30


31
#include <fcntl.h>
Cedric Roux's avatar
 
Cedric Roux committed
32 33 34 35
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>

36 37
#define G_LOG_DOMAIN ("UI")

38 39
#include <sys/stat.h>

Cedric Roux's avatar
 
Cedric Roux committed
40 41
#include <gtk/gtk.h>

42
#include "logs.h"
43
#include "itti_types.h"
44
#include "rc.h"
Cedric Roux's avatar
 
Cedric Roux committed
45 46 47

#include "ui_interface.h"
#include "ui_main_screen.h"
48
#include "ui_menu_bar.h"
Cedric Roux's avatar
 
Cedric Roux committed
49
#include "ui_notifications.h"
50
#include "ui_notif_dlg.h"
51
#include "ui_callbacks.h"
winckel's avatar
winckel committed
52
#include "ui_filters.h"
53
#include "ui_tree_view.h"
Cedric Roux's avatar
 
Cedric Roux committed
54

55
#include "locate_root.h"
Cedric Roux's avatar
Cedric Roux committed
56
#include "xml_parse.h"
57
#include "socket.h"
Cedric Roux's avatar
 
Cedric Roux committed
58

winckel's avatar
winckel committed
59 60 61
static const itti_message_types_t itti_dump_xml_definition_end =  ITTI_DUMP_XML_DEFINITION_END;
static const itti_message_types_t itti_dump_message_type_end =    ITTI_DUMP_MESSAGE_TYPE_END;

62 63
static FILE *messages_file;
static uint32_t message_number;
64
static gboolean ui_abort;
65

Cedric Roux's avatar
 
Cedric Roux committed
66 67 68
int ui_disable_connect_button(void)
{
    /* Disable Connect button and enable disconnect button */
69 70
    gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.connect), FALSE);
    gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.disconnect), TRUE);
71
    socket_abort_connection = FALSE;
Cedric Roux's avatar
 
Cedric Roux committed
72 73 74 75 76 77 78

    return RC_OK;
}

int ui_enable_connect_button(void)
{
    /* Disable Disconnect button and enable connect button */
79 80
    gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.connect), TRUE);
    gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.disconnect), FALSE);
81
    socket_abort_connection = TRUE;
82
    ui_set_sensitive_save_message_buttons (TRUE);
83
    ui_set_title ("");
Cedric Roux's avatar
 
Cedric Roux committed
84 85 86 87

    return RC_OK;
}

winckel's avatar
winckel committed
88
static void ui_change_cursor(gboolean busy)
winckel's avatar
winckel committed
89 90 91 92 93 94 95 96 97 98
{
    static GdkWindow *window;

    if (busy)
    {
        GdkDisplay *display;
        GdkCursor *cursor;
        // gint x, y;

        cursor = gdk_cursor_new (GDK_WATCH);
99 100
        display = gdk_display_get_default ();
        window = gtk_widget_get_window (GTK_WIDGET(ui_main_data.window));
winckel's avatar
winckel committed
101 102 103
        // window = gdk_display_get_window_at_pointer(display, &x, &y);

        gdk_window_set_cursor (window, cursor);
104
        gdk_display_sync (display);
winckel's avatar
winckel committed
105
        g_object_unref (cursor);
106
        // gtk_widget_set_sensitive (ui_main_data.window, FALSE);
107
        ui_gtk_flush_events ();
winckel's avatar
winckel committed
108 109 110 111
    }
    else
    {
        gdk_window_set_cursor (window, NULL);
112
        // gtk_widget_set_sensitive (ui_main_data.window, TRUE);
113
        ui_gtk_flush_events ();
winckel's avatar
winckel committed
114 115 116
    }
}

117 118
static void gtk_filter_add(GtkWidget *file_chooser, const gchar *title, const gchar *pattern)
{
119
    GtkFileFilter *file_filter = gtk_file_filter_new ();
120

121 122 123
    gtk_file_filter_set_name (file_filter, title);
    gtk_file_filter_add_pattern (file_filter, pattern);
    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(file_chooser), file_filter);
124 125
}

126
int ui_messages_read(char *file_name)
Cedric Roux's avatar
 
Cedric Roux committed
127
{
128
    int result = RC_OK;
winckel's avatar
winckel committed
129 130 131 132 133 134
    int source;
    int read_data = 0;
    void *input_data = NULL;
    size_t input_data_length = 0;
    int read_messages = 0;

135
    ui_change_cursor (TRUE);
winckel's avatar
winckel committed
136

137
    source = open (file_name, O_RDONLY);
winckel's avatar
winckel committed
138
    if (source < 0)
Cedric Roux's avatar
 
Cedric Roux committed
139
    {
winckel's avatar
winckel committed
140
        ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", "Failed to open file \"%s\": %s", file_name,
141
                                g_strerror (errno));
winckel's avatar
winckel committed
142 143 144 145 146
        result = RC_FAIL;
    }
    else
    {
        itti_socket_header_t message_header;
147 148 149 150
        struct stat st;
        int size;
        double read_fraction = 0.f;

151
        if (stat (file_name, &st) < 0)
152
        {
winckel's avatar
winckel committed
153
            ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "get file length",
154
                                    "Failed to retrieve length for file \"%s\": %s", file_name, g_strerror (errno));
155 156 157
            result = RC_FAIL;
        }
        size = st.st_size;
Cedric Roux's avatar
 
Cedric Roux committed
158

winckel's avatar
winckel committed
159
        ui_callback_signal_clear_list (NULL, NULL);
160

161
        /* Initialize the progress bar */
162
        ui_abort = FALSE;
163
        ui_progress_bar_set_fraction (0);
164

winckel's avatar
winckel committed
165
        do
166
        {
winckel's avatar
winckel committed
167
            read_data = read (source, &message_header, sizeof(itti_socket_header_t));
168

winckel's avatar
winckel committed
169 170
            if (read_data == -1)
            {
winckel's avatar
winckel committed
171
                ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", "Failed to read from file \"%s\": %s",
172
                                        file_name, g_strerror (errno));
winckel's avatar
winckel committed
173 174 175
                result = RC_FAIL;
                break;
            }
176

177 178
            if (read_data == 0)
            {
179
                break;
180 181 182 183
            }

            if (read_data < sizeof(itti_socket_header_t))
            {
winckel's avatar
winckel committed
184 185 186 187 188
                if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages",
                                            "Failed to read a complete message header from file \"%s\": %s", file_name, g_strerror (errno)) == RC_FAIL)
                {
                    read_data = 0;
                }
189 190
            }
            else
191
            {
192
                read_fraction += (double) read_data / size;
193

winckel's avatar
winckel committed
194
                input_data_length = message_header.message_size - sizeof(itti_socket_header_t);
195

196
                g_debug("%x, %x, %zd", message_header.message_type, message_header.message_size, input_data_length);
197

winckel's avatar
winckel committed
198 199
                /* Checking for non-header part */
                if (input_data_length > 0)
200
                {
winckel's avatar
winckel committed
201
                    input_data = malloc (input_data_length);
202

203 204
                    read_data = read (source, input_data, input_data_length);
                    if (read_data < input_data_length)
205
                    {
winckel's avatar
winckel committed
206 207 208 209 210
                        if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages",
                                                    "Failed to read a complete message from file \"%s\": %s", file_name, g_strerror (errno)) == RC_FAIL)
                        {
                            read_data = 0;
                        }
winckel's avatar
winckel committed
211
                        break;
212
                    }
213

214
                    read_fraction += (double) input_data_length / size;
winckel's avatar
winckel committed
215
                }
216

winckel's avatar
winckel committed
217 218
                switch (message_header.message_type)
                {
winckel's avatar
winckel committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
                    case ITTI_DUMP_XML_DEFINITION:
                        ui_gtk_flush_events ();
                        if (memcmp (&(((char *) input_data)[input_data_length - sizeof (itti_message_types_t)]),
                            &itti_dump_xml_definition_end, sizeof (itti_message_types_t)) == 0)
                        {
                            result = xml_parse_buffer (input_data, input_data_length - sizeof (itti_message_types_t));
                            if (result != RC_OK)
                            {
                                ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages",
                                                        "Error in parsing XML definitions in file \"%s\": %s", file_name,
                                                        rc_strings[-result]);
                                read_data = 0;
                            }
                            ui_gtk_flush_events ();
                            g_message("Parsed XML definition from file \"%s\"", file_name);
                        }
                        else
                        {
                            ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages",
                                                    "Error in parsing XML definitions in file \"%s\", end mark is missing", file_name);
                        }
                        /* Data input buffer is kept in case user when to save the log file later */
                        break;

winckel's avatar
winckel committed
243
                    case ITTI_DUMP_MESSAGE_TYPE:
244
                    {
winckel's avatar
winckel committed
245 246 247
                        itti_signal_header_t *itti_signal_header = input_data;
                        buffer_t *buffer;

winckel's avatar
winckel committed
248 249
                        if (memcmp (&(((char *) input_data)[input_data_length - sizeof (itti_message_types_t)]),
                            &itti_dump_message_type_end, sizeof (itti_message_types_t)) == 0)
250
                        {
winckel's avatar
winckel committed
251 252 253 254 255 256 257
                            /* Create the new buffer */
                            if (buffer_new_from_data (&buffer, input_data + sizeof(itti_signal_header_t),
                                                      input_data_length - sizeof(itti_signal_header_t) - sizeof(itti_message_types_t), 0) != RC_OK)
                            {
                                g_error("Failed to create new buffer");
                                g_assert_not_reached ();
                            }
258

259
                            sscanf (itti_signal_header->message_number_char, MESSAGE_NUMBER_CHAR_FORMAT, &buffer->message_number);
260

winckel's avatar
winckel committed
261
                            ui_signal_add_to_list (buffer, ((read_messages % 1000) == 0) ? (gpointer) 1 : NULL);
262

winckel's avatar
winckel committed
263 264 265 266 267 268 269 270 271
                            if ((read_messages % 100) == 0)
                            {
                                ui_progress_bar_set_fraction (read_fraction);
                                ui_gtk_flush_events ();
                            }

                            read_messages++;
                        }
                        else
272
                        {
winckel's avatar
winckel committed
273 274 275 276 277 278
                            if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages",
                                                        "Failed to read a message from file \"%s\", end mark is missing", file_name) == RC_FAIL)
                            {
                                read_data = 0;
                            }
                            break;
279
                        }
winckel's avatar
winckel committed
280

281
                        free (input_data);
winckel's avatar
winckel committed
282
                        break;
283 284
                    }

winckel's avatar
winckel committed
285 286 287 288 289
                    case ITTI_STATISTIC_MESSAGE_TYPE:
                    default:
                        if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages",
                                                    "Unknown (or not implemented) record type: %d in file \"%s\"",
                                                    message_header.message_type, file_name) == RC_FAIL)
290 291 292
                        {
                            read_data = 0;
                        }
293 294

                        free (input_data);
winckel's avatar
winckel committed
295
                        break;
296
                }
297
            }
298
        } while ((ui_abort == FALSE) && (read_data > 0));
299

winckel's avatar
winckel committed
300 301
        if (read_messages > 0)
        {
302 303
            char *basename;

winckel's avatar
winckel committed
304 305
            /* Enable buttons to move in the list of signals */
            ui_set_sensitive_move_buttons (TRUE);
306

winckel's avatar
winckel committed
307 308 309
            if (ui_main_data.follow_last)
            {
                /* Advance to the last signal */
310
                ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1);
winckel's avatar
winckel committed
311 312
            }

313
            basename = g_path_get_basename (file_name);
314
            ui_set_title ("\"%s\"", basename);
315
        }
316 317 318 319
        else
        {
            result = RC_FAIL;
        }
320

321
        ui_progress_bar_terminate ();
322

323
        g_message("Read %d messages (%d to display) from file \"%s\"\n", read_messages, ui_tree_view_get_filtered_number(), file_name);
winckel's avatar
winckel committed
324 325 326 327

        close (source);
    }

328
    ui_change_cursor (FALSE);
winckel's avatar
winckel committed
329

winckel's avatar
winckel committed
330 331 332
    return result;
}

333
static void ui_message_write_callback(const gpointer buffer, const gchar *signal_name)
winckel's avatar
winckel committed
334
{
335 336 337 338 339 340
    buffer_t *signal_buffer = (buffer_t *) buffer;
    itti_socket_header_t message_header;
    itti_signal_header_t itti_signal_header;
    uint32_t message_size;

    message_size = signal_buffer->size_bytes;
winckel's avatar
winckel committed
341

winckel's avatar
winckel committed
342
    message_header.message_size = sizeof(itti_socket_header_t) + sizeof(itti_signal_header) + message_size + sizeof(itti_message_types_t);
343 344
    message_header.message_type = ITTI_DUMP_MESSAGE_TYPE;

345 346
    sprintf(itti_signal_header.message_number_char, MESSAGE_NUMBER_CHAR_FORMAT, message_number);
    itti_signal_header.message_number_char[sizeof(itti_signal_header.message_number_char) - 1] = '\n';
347 348 349 350 351
    message_number++;

    fwrite (&message_header, sizeof(message_header), 1, messages_file);
    fwrite (&itti_signal_header, sizeof(itti_signal_header), 1, messages_file);
    fwrite (signal_buffer->data, message_size, 1, messages_file);
winckel's avatar
winckel committed
352
    fwrite (&itti_dump_message_type_end, sizeof(itti_message_types_t), 1, messages_file);
353 354
}

355
static int ui_messages_file_write(char *file_name, gboolean filtered)
356 357 358 359 360 361
{
    if (file_name == NULL)
    {
        g_warning("No name for log file");
        return RC_FAIL;
    }
winckel's avatar
winckel committed
362

363 364 365
    messages_file = fopen (file_name, "w");
    if (messages_file == NULL)
    {
winckel's avatar
winckel committed
366
        ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Failed to open file \"%s\": %s", file_name, g_strerror (errno));
367 368
        return RC_FAIL;
    }
winckel's avatar
winckel committed
369

370
    /* Write XML definitions */
winckel's avatar
winckel committed
371
    {
372 373
        itti_socket_header_t message_header;

winckel's avatar
winckel committed
374
        message_header.message_size = sizeof(itti_socket_header_t) + xml_raw_data_size + sizeof(itti_message_types_t);
375 376 377 378
        message_header.message_type = ITTI_DUMP_XML_DEFINITION;

        fwrite (&message_header, sizeof(message_header), 1, messages_file);
        fwrite (xml_raw_data, xml_raw_data_size, 1, messages_file);
winckel's avatar
winckel committed
379
        fwrite (&itti_dump_xml_definition_end, sizeof(itti_message_types_t), 1, messages_file);
Cedric Roux's avatar
 
Cedric Roux committed
380
    }
381 382

    /* Write messages */
winckel's avatar
winckel committed
383
    {
384
        message_number = 1;
385
        ui_tree_view_foreach_message (ui_message_write_callback, filtered);
386 387 388 389 390 391 392 393 394 395 396
    }

    fclose (messages_file);

    return RC_OK;
}

int ui_messages_open_file_chooser(void)
{
    int result = RC_OK;

397
    GtkWidget *filechooser;
398
    gboolean response_accept;
399
    char *filename;
400

401 402 403 404 405
    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);
    gtk_filter_add (filechooser, "Log files", "*.log");
    gtk_filter_add (filechooser, "All files", "*");
406

407
    /* Process the response */
408
    response_accept = gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT;
409

410
    if (response_accept)
411 412 413 414
    {
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
    }
    gtk_widget_destroy (filechooser);
415
    if (response_accept)
416
    {
417 418
        ui_set_sensitive_save_message_buttons (FALSE);

419 420
        result = ui_messages_read (filename);
        if (result == RC_OK)
421
        {
422 423
            /* Update messages file name for future use */
            if (ui_main_data.messages_file_name != NULL)
424
            {
425
                g_free (ui_main_data.messages_file_name);
426
            }
427
            ui_main_data.messages_file_name = filename;
428 429

            ui_set_sensitive_save_message_buttons (TRUE);
430 431 432 433
        }
        else
        {
            g_free (filename);
434
        }
435 436 437 438
    }
    return result;
}

439
int ui_messages_save_file_chooser(gboolean filtered)
440 441
{
    int result = RC_OK;
442
    GtkWidget *filechooser;
443

444 445
    /* Check if there is something to save */
    if (xml_raw_data_size > 0)
446
    {
447 448 449 450 451 452 453
        static const char *title[] =
        {
             "Save file (all messages)",
             "Save file (filtered messages)",
        };

        filechooser = gtk_file_chooser_dialog_new (title[filtered], GTK_WINDOW (ui_main_data.window),
454 455 456 457
                                                   GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
                                                   GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
        gtk_filter_add (filechooser, "Log files", "*.log");
        gtk_filter_add (filechooser, "All files", "*");
458

459
        gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filechooser), TRUE);
460

461 462 463 464 465
        if (ui_main_data.messages_file_name != NULL)
        {
            gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser), ui_main_data.messages_file_name);
        }
        else
466
        {
467 468
            gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filechooser), "messages.log");
        }
469

470 471 472 473
        /* Process the response */
        if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT)
        {
            char *filename;
474

475
            filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
476
            result = ui_messages_file_write (filename, filtered);
477
            if (result == RC_OK)
478
            {
479 480 481 482 483 484
                /* Update filters file name for future use */
                if (ui_main_data.messages_file_name != NULL)
                {
                    g_free (ui_main_data.messages_file_name);
                }
                ui_main_data.messages_file_name = filename;
485 486 487
            }
            else
            {
488
                g_free (filename);
489
            }
490
        }
491
        gtk_widget_destroy (filechooser);
winckel's avatar
winckel committed
492
    }
Cedric Roux's avatar
 
Cedric Roux committed
493

494
    return result;
Cedric Roux's avatar
 
Cedric Roux committed
495 496
}

497 498 499
int ui_filters_open_file_chooser(void)
{
    int result = RC_OK;
500
    GtkWidget *filechooser;
501
    gboolean response_accept;
502
    char *filename;
503

504 505 506 507 508
    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);
    gtk_filter_add (filechooser, "Filters files", "*.xml");
    gtk_filter_add (filechooser, "All files", "*");
509

510
    /* Process the response */
511
    response_accept = gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT;
512

513
    if (response_accept)
514 515 516 517
    {
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
    }
    gtk_widget_destroy (filechooser);
518
    if (response_accept)
519 520 521
    {
        result = ui_filters_read (filename);
        if (result == RC_OK)
522
        {
523 524
            /* Update filters file name for future use */
            if (ui_main_data.filters_file_name != NULL)
525
            {
526
                g_free (ui_main_data.filters_file_name);
527
            }
528 529 530 531 532
            ui_main_data.filters_file_name = filename;
        }
        else
        {
            g_free (filename);
533
        }
winckel's avatar
winckel committed
534
    }
535

winckel's avatar
winckel committed
536
    return result;
537 538 539 540 541
}

int ui_filters_save_file_chooser(void)
{
    int result = RC_OK;
542
    GtkWidget *filechooser;
543

544 545 546 547 548
    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_filter_add (filechooser, "Filters files", "*.xml");
    gtk_filter_add (filechooser, "All files", "*");
549

550
    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filechooser), TRUE);
551

552 553 554 555 556 557 558 559
    if (ui_main_data.filters_file_name != NULL)
    {
        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser), ui_main_data.filters_file_name);
    }
    else
    {
        gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filechooser), "filters.xml");
    }
560

561 562 563 564
    /* Process the response */
    if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT)
    {
        char *filename;
565

566 567 568
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
        result = ui_filters_file_write (filename);
        if (result == RC_OK)
569
        {
570 571 572 573 574 575
            /* Update filters file name for future use */
            if (ui_main_data.filters_file_name != NULL)
            {
                g_free (ui_main_data.filters_file_name);
            }
            ui_main_data.filters_file_name = filename;
576 577 578
        }
        else
        {
579
            g_free (filename);
580
        }
581
    }
582
    gtk_widget_destroy (filechooser);
583

winckel's avatar
winckel committed
584
    return result;
585 586
}

587 588 589 590 591 592
void ui_progressbar_window_destroy (void)
{
    ui_abort = TRUE;
    ui_progress_bar_terminate();
}

Cedric Roux's avatar
 
Cedric Roux committed
593 594
int ui_progress_bar_set_fraction(double fraction)
{
595
    if (ui_abort == FALSE)
596
    {
597 598 599 600
        /* If not exist instantiate */
        if (!ui_main_data.progressbar && !ui_main_data.progressbar_window)
        {
            ui_main_data.progressbar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
601 602
            /* Keep progress bar window on top of main window */
            gtk_window_set_transient_for (GTK_WINDOW(ui_main_data.progressbar_window), GTK_WINDOW(ui_main_data.window));
603

604 605
            /* Set the window at center of main window */
            gtk_window_set_position (GTK_WINDOW(ui_main_data.progressbar_window), GTK_WIN_POS_CENTER_ON_PARENT);
606
            gtk_window_set_title (GTK_WINDOW(ui_main_data.progressbar_window), "Processing");
607

608
            gtk_container_set_border_width (GTK_CONTAINER (ui_main_data.progressbar_window), 10);
609

610
            ui_main_data.progressbar = gtk_progress_bar_new ();
611

612
            gtk_container_add (GTK_CONTAINER (ui_main_data.progressbar_window), ui_main_data.progressbar);
613

614 615
            /* Assign the destroy event */
            g_signal_connect(ui_main_data.progressbar_window, "destroy", ui_progressbar_window_destroy, NULL);
616

617
            gtk_widget_show_all (ui_main_data.progressbar_window);
618

winckel's avatar
winckel committed
619
            gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.stop_loading), TRUE);
620 621 622 623 624 625
        }

        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(ui_main_data.progressbar), fraction);

//       ui_gtk_flush_events();
    }
Cedric Roux's avatar
 
Cedric Roux committed
626 627 628 629 630 631

    return RC_OK;
}

int ui_progress_bar_terminate(void)
{
632 633 634
    if (ui_main_data.progressbar)
    {
        gtk_widget_destroy (ui_main_data.progressbar);
635
        ui_main_data.progressbar = NULL;
636
    }
637 638 639
    if (ui_main_data.progressbar_window)
    {
        gtk_widget_destroy (ui_main_data.progressbar_window);
640
        ui_main_data.progressbar_window = NULL;
641
    }
winckel's avatar
winckel committed
642
    gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.stop_loading), FALSE);
643

Cedric Roux's avatar
 
Cedric Roux committed
644 645
    return RC_OK;
}