<commit_before>/**
 * @file    gui.c
 * @brief  
 *
 * Copyright (C) 2010 Gummi-Dev Team <<EMAIL>>
 * All Rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "gui.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifndef WIN32
#   include <unistd.h>
#endif

#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

#include "biblio.h"
#include "configfile.h"
#include "editor.h"
#include "environment.h"
#include "importer.h"
#include "updatecheck.h"
#include "utils.h"
#include "template.h"

extern Gummi* gummi;

/* Many of the functions in this file are based on the excellent GTK+
 * tutorials written by <NAME> that can be found on: 
 * http://www.micahcarrick.com/gtk-glade-tutorial-part-3.html */

GummiGui* gui_init(GtkBuilder* builder) {
    L_F_DEBUG;
    GtkWidget *hpaned;
    GtkWidget *errortext;
    gint wx = 0, wy = 0, width = 0, height = 0;

    GummiGui* g = g_new0(GummiGui, 1);

    errortext = GTK_WIDGET(gtk_builder_get_object(builder, "errorfield"));
    g->mainwindow =
        GTK_WIDGET(gtk_builder_get_object(builder, "mainwindow"));
    g->toolbar =
        GTK_HBOX(gtk_builder_get_object(builder, "toolbar"));
    g->statusbar =
        GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar"));
    g->rightpane =
        GTK_VBOX(gtk_builder_get_object(builder, "rightpanebox"));
    g->previewoff = GTK_TOGGLE_TOOL_BUTTON(
            gtk_builder_get_object(builder, "tool_previewoff"));
    g->errorbuff =
        gtk_text_view_get_buffer(GTK_TEXT_VIEW(errortext));
    g->menu_spelling =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_spelling"));
    g->menu_toolbar =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_toolbar"));
    g->menu_statusbar =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_statusbar"));
    g->menu_rightpane =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_rightpane"));
    g->statusid =
        gtk_statusbar_get_context_id(GTK_STATUSBAR(g->statusbar), "Gummi");
    g->recent[0] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent1"));
    g->recent[1] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent2"));
    g->recent[2] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent3"));
    g->recent[3] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent4"));
    g->recent[4] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent5"));

    g->prefsgui = prefsgui_init(g);
    g->searchgui = searchgui_init(builder);
    g->importgui = importgui_init(builder);

    gtk_window_resize(GTK_WINDOW(g->mainwindow),
                      atoi(config_get_value("mainwindow_w")),
                      atoi(config_get_value("mainwindow_h")));

    wx = atoi(config_get_value("mainwindow_x"));
    wy = atoi(config_get_value("mainwindow_y"));
    if (wx && wy)
      gtk_window_move(GTK_WINDOW(g->mainwindow), wx, wy);
    else
      gtk_window_set_position(GTK_WINDOW(g->mainwindow), GTK_WIN_POS_CENTER);

    PangoFontDescription* font_desc = 
        pango_font_description_from_string("Monospace 8");
    gtk_widget_modify_font(errortext, font_desc);
    pango_font_description_free(font_desc);
    gtk_window_get_size(GTK_WINDOW(g->mainwindow), &width, &height);

    hpaned= GTK_WIDGET(gtk_builder_get_object(builder, "hpaned"));
    gtk_paned_set_position(GTK_PANED(hpaned), (width/2)); 

#ifndef USE_GTKSPELL
    gtk_widget_set_sensitive(GTK_WIDGET(g->menu_spelling), FALSE);
#else
    if (config_get_value("spelling"))
        gtk_check_menu_item_set_active(g->menu_spelling, TRUE);
#endif
    if (config_get_value("toolbar")) {
        gtk_check_menu_item_set_active(g->menu_toolbar, TRUE);
        gtk_widget_show(GTK_WIDGET(g->toolbar));
    }

    if (config_get_value("statusbar")) {
        gtk_check_menu_item_set_active(g->menu_statusbar, TRUE);
        gtk_widget_show(GTK_WIDGET(g->statusbar));
    }

    if (config_get_value("rightpane")) {
        gtk_check_menu_item_set_active(g->menu_rightpane, TRUE);
        gtk_widget_show(GTK_WIDGET(g->rightpane));
    } else {
        config_set_value("compile_status", "False");
        gtk_toggle_tool_button_set_active(g->previewoff, TRUE);
    }

    if (!config_get_value("compile_status"))
        gtk_toggle_tool_button_set_active(g->previewoff, TRUE);

    g->recent_list[0] = g_strdup(config_get_value("recent1"));
    g->recent_list[1] = g_strdup(config_get_value("recent2"));
    g->recent_list[2] = g_strdup(config_get_value("recent3"));
    g->recent_list[3] = g_strdup(config_get_value("recent4"));
    g->recent_list[4] = g_strdup(config_get_value("recent5"));

    display_recent_files(g);

    return g;
}

void gui_main(GtkBuilder* builder) {
    L_F_DEBUG;
    gtk_builder_connect_signals(builder, NULL);       
    g_signal_connect(g_e_buffer, "changed",
            G_CALLBACK(check_motion_timer), NULL);
    gtk_widget_show_all(gummi->gui->mainwindow);
    gtk_main();
}

gboolean gui_quit(void) {
    L_F_DEBUG;
    gint wx = 0, wy = 0, width = 0, height = 0;
    gchar* wx_str = NULL;
    gchar* wy_str = NULL;
    gchar* width_str = NULL;
    gchar* height_str = NULL;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return TRUE;

    gtk_window_get_size(GTK_WINDOW(gummi->gui->mainwindow), &width, &height);
    gtk_window_get_position(GTK_WINDOW(gummi->gui->mainwindow), &wx, &wy);
    wx_str = g_strdup_printf("%d", wx);
    wy_str = g_strdup_printf("%d", wy);
    width_str = g_strdup_printf("%d", width);
    height_str = g_strdup_printf("%d", height);
    config_set_value("mainwindow_x", wx_str);
    config_set_value("mainwindow_y", wy_str);
    config_set_value("mainwindow_w", width_str);
    config_set_value("mainwindow_h", height_str);

    g_free(wx_str);
    g_free(wy_str);
    g_free(width_str);
    g_free(height_str);

    gtk_main_quit();

    printf("   ___ \n"
            "  {o,o}    Thanks for using Gummi!\n" 
            "  |)__)    I welcome your feedback at:\n"
            "  -\"-\"-    http://gummi.midnightcoding.org\n\n");
    return FALSE;
}

void gui_update_title(void) {
    L_F_DEBUG;
    gchar* basename = NULL;
    gchar* dirname = NULL;
    gchar* title = NULL;
    if (gummi->finfo->filename) {
        basename = g_path_get_basename(gummi->finfo->filename);
        dirname = g_path_get_dirname(gummi->finfo->filename);
        title = g_strdup_printf("%s%s (%s) - %s",
                (gtk_text_buffer_get_modified(g_e_buffer)? "*": ""),
                basename, dirname, PACKAGE_NAME);
        g_free(basename);
        g_free(dirname);
    } else
        title = g_strdup_printf("%sUnsaved Document - %s",
                (gtk_text_buffer_get_modified(g_e_buffer)? "*": ""),
                PACKAGE_NAME);

    gtk_window_set_title(GTK_WINDOW(gummi->gui->mainwindow), title);
    g_free(title);
}

void on_menu_new_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gint ret = check_for_save();
    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;
    iofunctions_load_default_text(gummi->editor);
    gummi_create_environment(gummi, NULL);
}

void on_menu_template_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    gtk_list_store_clear(gummi->templ->list_templates);
    template_setup(gummi->templ);
    gtk_widget_show_all(GTK_WIDGET(gummi->templ->templatewindow));
}

void on_menu_exportpdf_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    gchar* filename = NULL;

    filename = get_save_filename(TYPE_PDF);
    if (filename)
        motion_export_pdffile(gummi->motion, filename);
}

void on_menu_recent_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    const gchar* name = gtk_menu_item_get_label(GTK_MENU_ITEM(widget));
    gchar* ptr;
    gint index = name[0] - '0' -1;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;

    if (utils_path_exists(gummi->gui->recent_list[index])) {
        iofunctions_load_file(gummi->editor, gummi->gui->recent_list[index]); 
        gummi_create_environment(gummi, gummi->gui->recent_list[index]);
    } else {
        ptr = g_strdup_printf(_("Error loading recent file: %s"),
                gummi->gui->recent_list[index]);
        statusbar_set_message(ptr);
        g_free(ptr);
        g_free(gummi->gui->recent_list[index]);
        while (index < 4) {
            gummi->gui->recent_list[index] = gummi->gui->recent_list[index+1];
            ++index;
        }
        gummi->gui->recent_list[4] = 0;
    }
    display_recent_files(gummi->gui);
}

void on_menu_open_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar *filename = NULL;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;
    filename = get_open_filename(TYPE_LATEX);
    if (filename != NULL) {
        iofunctions_load_file(gummi->editor, filename); 
        gummi_create_environment(gummi, filename);
        add_to_recent_list(filename);
    }
}

void on_menu_save_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar* filename = NULL;
    gboolean new = FALSE;

    if (!gummi->finfo->filename) {
        if ((filename = get_save_filename(TYPE_LATEX))) {
            if (strcmp(filename + strlen(filename) -4, ".tex")) {
                filename = g_strdup_printf("%s.tex", filename);
                new = TRUE;
            }
            fileinfo_set_filename(gummi->finfo, filename);
            iofunctions_write_file(gummi->editor, filename); 
            add_to_recent_list(filename);
            if (new) g_free(filename);
        }
    } else
        iofunctions_write_file(gummi->editor, gummi->finfo->filename); 
    gui_update_title();
}

void on_menu_saveas_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar* filename = NULL;
    gboolean new = FALSE;
    if ((filename = get_save_filename(TYPE_LATEX_SAVEAS))) {
        if (strcmp(filename + strlen(filename) -4, ".tex")) {
            filename = g_strdup_printf("%s.tex", filename);
            new = TRUE;
        }
        iofunctions_write_file(gummi->editor, filename); 
        gummi_create_environment(gummi, filename);
        add_to_recent_list(filename);
        if (new) g_free(filename);
    }
}

void on_menu_cut_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    GtkClipboard     *clipboard;

    clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);<commit_msg>Prompt for overwriting file when save/saveas<commit_after>/**
 * @file    gui.c
 * @brief  
 *
 * Copyright (C) 2010 Gummi-Dev Team <<EMAIL>>
 * All Rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "gui.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifndef WIN32
#   include <unistd.h>
#endif

#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

#include "biblio.h"
#include "configfile.h"
#include "editor.h"
#include "environment.h"
#include "importer.h"
#include "updatecheck.h"
#include "utils.h"
#include "template.h"

extern Gummi* gummi;

/* Many of the functions in this file are based on the excellent GTK+
 * tutorials written by <NAME> that can be found on: 
 * http://www.micahcarrick.com/gtk-glade-tutorial-part-3.html */

GummiGui* gui_init(GtkBuilder* builder) {
    L_F_DEBUG;
    GtkWidget *hpaned;
    GtkWidget *errortext;
    gint wx = 0, wy = 0, width = 0, height = 0;

    GummiGui* g = g_new0(GummiGui, 1);

    errortext = GTK_WIDGET(gtk_builder_get_object(builder, "errorfield"));
    g->mainwindow =
        GTK_WIDGET(gtk_builder_get_object(builder, "mainwindow"));
    g->toolbar =
        GTK_HBOX(gtk_builder_get_object(builder, "toolbar"));
    g->statusbar =
        GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar"));
    g->rightpane =
        GTK_VBOX(gtk_builder_get_object(builder, "rightpanebox"));
    g->previewoff = GTK_TOGGLE_TOOL_BUTTON(
            gtk_builder_get_object(builder, "tool_previewoff"));
    g->errorbuff =
        gtk_text_view_get_buffer(GTK_TEXT_VIEW(errortext));
    g->menu_spelling =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_spelling"));
    g->menu_toolbar =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_toolbar"));
    g->menu_statusbar =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_statusbar"));
    g->menu_rightpane =
        GTK_CHECK_MENU_ITEM(gtk_builder_get_object(builder, "menu_rightpane"));
    g->statusid =
        gtk_statusbar_get_context_id(GTK_STATUSBAR(g->statusbar), "Gummi");
    g->recent[0] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent1"));
    g->recent[1] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent2"));
    g->recent[2] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent3"));
    g->recent[3] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent4"));
    g->recent[4] =
        GTK_MENU_ITEM(gtk_builder_get_object(builder, "menu_recent5"));

    g->prefsgui = prefsgui_init(g);
    g->searchgui = searchgui_init(builder);
    g->importgui = importgui_init(builder);

    gtk_window_resize(GTK_WINDOW(g->mainwindow),
                      atoi(config_get_value("mainwindow_w")),
                      atoi(config_get_value("mainwindow_h")));

    wx = atoi(config_get_value("mainwindow_x"));
    wy = atoi(config_get_value("mainwindow_y"));
    if (wx && wy)
      gtk_window_move(GTK_WINDOW(g->mainwindow), wx, wy);
    else
      gtk_window_set_position(GTK_WINDOW(g->mainwindow), GTK_WIN_POS_CENTER);

    PangoFontDescription* font_desc = 
        pango_font_description_from_string("Monospace 8");
    gtk_widget_modify_font(errortext, font_desc);
    pango_font_description_free(font_desc);
    gtk_window_get_size(GTK_WINDOW(g->mainwindow), &width, &height);

    hpaned= GTK_WIDGET(gtk_builder_get_object(builder, "hpaned"));
    gtk_paned_set_position(GTK_PANED(hpaned), (width/2)); 

#ifndef USE_GTKSPELL
    gtk_widget_set_sensitive(GTK_WIDGET(g->menu_spelling), FALSE);
#else
    if (config_get_value("spelling"))
        gtk_check_menu_item_set_active(g->menu_spelling, TRUE);
#endif
    if (config_get_value("toolbar")) {
        gtk_check_menu_item_set_active(g->menu_toolbar, TRUE);
        gtk_widget_show(GTK_WIDGET(g->toolbar));
    }

    if (config_get_value("statusbar")) {
        gtk_check_menu_item_set_active(g->menu_statusbar, TRUE);
        gtk_widget_show(GTK_WIDGET(g->statusbar));
    }

    if (config_get_value("rightpane")) {
        gtk_check_menu_item_set_active(g->menu_rightpane, TRUE);
        gtk_widget_show(GTK_WIDGET(g->rightpane));
    } else {
        config_set_value("compile_status", "False");
        gtk_toggle_tool_button_set_active(g->previewoff, TRUE);
    }

    if (!config_get_value("compile_status"))
        gtk_toggle_tool_button_set_active(g->previewoff, TRUE);

    g->recent_list[0] = g_strdup(config_get_value("recent1"));
    g->recent_list[1] = g_strdup(config_get_value("recent2"));
    g->recent_list[2] = g_strdup(config_get_value("recent3"));
    g->recent_list[3] = g_strdup(config_get_value("recent4"));
    g->recent_list[4] = g_strdup(config_get_value("recent5"));

    display_recent_files(g);

    return g;
}

void gui_main(GtkBuilder* builder) {
    L_F_DEBUG;
    gtk_builder_connect_signals(builder, NULL);       
    g_signal_connect(g_e_buffer, "changed",
            G_CALLBACK(check_motion_timer), NULL);
    gtk_widget_show_all(gummi->gui->mainwindow);
    gtk_main();
}

gboolean gui_quit(void) {
    L_F_DEBUG;
    gint wx = 0, wy = 0, width = 0, height = 0;
    gchar* wx_str = NULL;
    gchar* wy_str = NULL;
    gchar* width_str = NULL;
    gchar* height_str = NULL;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return TRUE;

    gtk_window_get_size(GTK_WINDOW(gummi->gui->mainwindow), &width, &height);
    gtk_window_get_position(GTK_WINDOW(gummi->gui->mainwindow), &wx, &wy);
    wx_str = g_strdup_printf("%d", wx);
    wy_str = g_strdup_printf("%d", wy);
    width_str = g_strdup_printf("%d", width);
    height_str = g_strdup_printf("%d", height);
    config_set_value("mainwindow_x", wx_str);
    config_set_value("mainwindow_y", wy_str);
    config_set_value("mainwindow_w", width_str);
    config_set_value("mainwindow_h", height_str);

    g_free(wx_str);
    g_free(wy_str);
    g_free(width_str);
    g_free(height_str);

    gtk_main_quit();

    printf("   ___ \n"
            "  {o,o}    Thanks for using Gummi!\n" 
            "  |)__)    I welcome your feedback at:\n"
            "  -\"-\"-    http://gummi.midnightcoding.org\n\n");
    return FALSE;
}

void gui_update_title(void) {
    L_F_DEBUG;
    gchar* basename = NULL;
    gchar* dirname = NULL;
    gchar* title = NULL;
    if (gummi->finfo->filename) {
        basename = g_path_get_basename(gummi->finfo->filename);
        dirname = g_path_get_dirname(gummi->finfo->filename);
        title = g_strdup_printf("%s%s (%s) - %s",
                (gtk_text_buffer_get_modified(g_e_buffer)? "*": ""),
                basename, dirname, PACKAGE_NAME);
        g_free(basename);
        g_free(dirname);
    } else
        title = g_strdup_printf("%sUnsaved Document - %s",
                (gtk_text_buffer_get_modified(g_e_buffer)? "*": ""),
                PACKAGE_NAME);

    gtk_window_set_title(GTK_WINDOW(gummi->gui->mainwindow), title);
    g_free(title);
}

void on_menu_new_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gint ret = check_for_save();
    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;
    iofunctions_load_default_text(gummi->editor);
    gummi_create_environment(gummi, NULL);
}

void on_menu_template_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    gtk_list_store_clear(gummi->templ->list_templates);
    template_setup(gummi->templ);
    gtk_widget_show_all(GTK_WIDGET(gummi->templ->templatewindow));
}

void on_menu_exportpdf_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    gchar* filename = NULL;

    filename = get_save_filename(TYPE_PDF);
    if (filename)
        motion_export_pdffile(gummi->motion, filename);
}

void on_menu_recent_activate(GtkWidget *widget, void * user) {
    L_F_DEBUG;
    const gchar* name = gtk_menu_item_get_label(GTK_MENU_ITEM(widget));
    gchar* ptr;
    gint index = name[0] - '0' -1;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;

    if (utils_path_exists(gummi->gui->recent_list[index])) {
        iofunctions_load_file(gummi->editor, gummi->gui->recent_list[index]); 
        gummi_create_environment(gummi, gummi->gui->recent_list[index]);
    } else {
        ptr = g_strdup_printf(_("Error loading recent file: %s"),
                gummi->gui->recent_list[index]);
        statusbar_set_message(ptr);
        g_free(ptr);
        g_free(gummi->gui->recent_list[index]);
        while (index < 4) {
            gummi->gui->recent_list[index] = gummi->gui->recent_list[index+1];
            ++index;
        }
        gummi->gui->recent_list[4] = 0;
    }
    display_recent_files(gummi->gui);
}

void on_menu_open_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar *filename = NULL;
    gint ret = check_for_save();

    if (GTK_RESPONSE_YES == ret)
        on_menu_save_activate(NULL, NULL);  
    else if (GTK_RESPONSE_CANCEL == ret || GTK_RESPONSE_DELETE_EVENT == ret)
        return;
    filename = get_open_filename(TYPE_LATEX);
    if (filename != NULL) {
        iofunctions_load_file(gummi->editor, filename); 
        gummi_create_environment(gummi, filename);
        add_to_recent_list(filename);
    }
}

void on_menu_save_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar* filename = NULL;
    gboolean new = FALSE;
    gint ret = 0;

    if (!gummi->finfo->filename) {
        if ((filename = get_save_filename(TYPE_LATEX))) {
            if (strcmp(filename + strlen(filename) -4, ".tex")) {
                filename = g_strdup_printf("%s.tex", filename);
                new = TRUE;
            }
            if (utils_path_exists(filename)) {
                ret = utils_yes_no_dialog(
                        _("The file already exists. Overwrite?"));
                if (GTK_RESPONSE_YES != ret) {
                    if (new) g_free(filename);
                    return;
                }
            }
            fileinfo_set_filename(gummi->finfo, filename);
            iofunctions_write_file(gummi->editor, filename); 
            add_to_recent_list(filename);
            if (new) g_free(filename);
        }
    } else
        iofunctions_write_file(gummi->editor, gummi->finfo->filename); 
    gui_update_title();
}

void on_menu_saveas_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    gchar* filename = NULL;
    gboolean new = FALSE;
    gint ret = 0;

    if ((filename = get_save_filename(TYPE_LATEX_SAVEAS))) {
        if (strcmp(filename + strlen(filename) -4, ".tex")) {
            filename = g_strdup_printf("%s.tex", filename);
            new = TRUE;
        }
        if (utils_path_exists(filename)) {
            ret = utils_yes_no_dialog(
                    _("The file already exists. Overwrite?"));
            if (GTK_RESPONSE_YES != ret) {
                if (new) g_free(filename);
                return;
            }
        }
        iofunctions_write_file(gummi->editor, filename); 
        gummi_create_environment(gummi, filename);
        add_to_recent_list(filename);
        if (new) g_free(filename);
    }
}

void on_menu_cut_activate(GtkWidget *widget, void* user) {
    L_F_DEBUG;
    GtkClipboard     *clipboard;

    clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
{'fraction_non_alphanumeric': 0.12136119694259229, 'fraction_numerical': 0.0039843877053179376, 'mean_word_length': 3.4350883519653803, 'pattern_counts': {'":': 4, '<': 23, '<?xml version=': 0, '>': 195, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '849352', 'n_tokens_mistral': 9053, 'n_tokens_neox': 8644, 'n_words': 1538}