<commit_before>/*
 *      This file is part of GPaste.
 *
 *      Copyright 2013 <NAME> <<EMAIL>>
 *
 *      GPaste is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      GPaste is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with GPaste.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "gpaste-settings-ui-panel-private.h"

#include <stdlib.h>

struct _GPasteSettingsUiPanelPrivate
{
    GSList *callback_data;
    guint   current_line;
};

G_DEFINE_TYPE_WITH_PRIVATE (GPasteSettingsUiPanel, g_paste_settings_ui_panel, GTK_TYPE_GRID)

#define CALLBACK_DATA_FULL(cb, rcb, w, d, d2)                                                         \
    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);       \
    _CallbackDataWrapper *_data = (_CallbackDataWrapper *) g_malloc0 (sizeof (_CallbackDataWrapper)); \
    CallbackDataWrapper *data = (CallbackDataWrapper *) _data;                                        \
    priv->callback_data = g_slist_prepend (priv->callback_data, _data);                               \
    _data->widget = GTK_WIDGET (w);                                                                   \
    data->callback = G_CALLBACK (cb);                                                                 \
    data->reset_cb = rcb;                                                                             \
    data->custom_data = user_data;                                                                    \
    data->user_data = (d) ? GTK_WIDGET (d) : NULL;                                                    \
    data->user_data2 = (d2) ? GTK_WIDGET (d2) : NULL

#define CALLBACK_DATA_DEFAULT(w) \
    CALLBACK_DATA_FULL (on_value_changed, on_reset, w, NULL, NULL)

#define CALLBACK_DATA_CONFIRM2(w, d, d2) \
    CALLBACK_DATA_FULL (confirm_action, NULL, w, d, d2)

#define CALLBACK_DATA_CONFIRM(w, d) \
    CALLBACK_DATA_CONFIRM2 (w, d, NULL)

#define G_PASTE_CALLBACK(cb_type)                                  \
    CallbackDataWrapper *data = (CallbackDataWrapper *) user_data; \
    ((cb_type) data->callback)

#define G_PASTE_RESET_CALLBACK()                                   \
    CallbackDataWrapper *data = (CallbackDataWrapper *) user_data; \
    (data->reset_cb)

typedef struct
{
    GCallback           callback;
    GPasteResetCallback reset_cb;
    gpointer            custom_data;
    GtkWidget          *user_data;
    GtkWidget          *user_data2;
} CallbackDataWrapper;

typedef struct
{
    CallbackDataWrapper wrap;
    GtkWidget          *widget;
    GtkWidget          *reset_widget;
    gulong              signal;
    gulong              reset_signal;
} _CallbackDataWrapper;

static void
boolean_wrapper (GObject    *object,
                 GParamSpec *pspec G_GNUC_UNUSED,
                 gpointer    user_data)
{
    G_PASTE_CALLBACK (GPasteBooleanCallback) (gtk_switch_get_active (GTK_SWITCH (object)), data->custom_data);
}

static GtkLabel *
g_paste_settings_ui_panel_add_label (GPasteSettingsUiPanel *self,
                                     const gchar           *label)
{
    GtkWidget *button_label = gtk_widget_new (GTK_TYPE_LABEL,
                                              "label",  label,
                                              "xalign", 0.0,
                                              NULL);

    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);

    gtk_widget_set_hexpand (button_label, TRUE);
    gtk_grid_attach (GTK_GRID (self), button_label, 0, priv->current_line++, 1, 1);

    return GTK_LABEL (button_label);
}

static gboolean
g_paste_settings_ui_panel_on_reset_pressed (GtkWidget *widget G_GNUC_UNUSED,
                                            GdkEvent  *event  G_GNUC_UNUSED,
                                            gpointer   user_data)
{
    G_PASTE_RESET_CALLBACK () (data->custom_data);
    return FALSE;
}

static GtkWidget *
g_paste_settings_ui_panel_make_reset_button (_CallbackDataWrapper *data)
{
    data->reset_widget = gtk_button_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_BUTTON);
    data->reset_signal = g_signal_connect (G_OBJECT (data->reset_widget),
                                           "button-press-event",
                                           G_CALLBACK (g_paste_settings_ui_panel_on_reset_pressed),
                                           data);
    return data->reset_widget;
}

/**
 * g_paste_settings_ui_panel_add_boolean_setting:
 * @self: a #GPasteSettingsUiPanel instance
 * @label: the label to display
 * @value: the deafault value
 * @on_value_changed: (closure user_data) (scope notified): the callback to call when the value changes
 * @on_reset: (closure user_data) (scope notified): the callback to call when the value is reset
 *
 * Add a new boolean settings to the current pane
 *
 * Returns: (transfer none): the #GtkSwitch we just added
 */
G_PASTE_VISIBLE GtkSwitch *
g_paste_settings_ui_panel_add_boolean_setting (GPasteSettingsUiPanel *self,
                                               const gchar           *label,
                                               gboolean               value,
                                               GPasteBooleanCallback  on_value_changed,
                                               GPasteResetCallback    on_reset,
                                               gpointer               user_data)
{
    GtkGrid *grid = GTK_GRID (self);
    GtkLabel *button_label = g_paste_settings_ui_panel_add_label (self, label);
    GtkWidget *widget = gtk_switch_new ();
    GtkSwitch *sw = GTK_SWITCH (widget);
    CALLBACK_DATA_DEFAULT (widget);

    gtk_switch_set_active (sw, value);
    _data->signal = g_signal_connect (widget, "notify::active", G_CALLBACK (boolean_wrapper), data);
    gtk_grid_attach_next_to (grid, widget, GTK_WIDGET (button_label), GTK_POS_RIGHT, 1, 1);
    if (on_reset)
        gtk_grid_attach_next_to (grid, g_paste_settings_ui_panel_make_reset_button (_data), widget, GTK_POS_RIGHT, 1, 1);

    return sw;
}

/**
 * g_paste_settings_ui_panel_add_separator:
 * @self: a #GPasteSettingsUiPanel instance
 *
 * Add a new separator to the current pane
 *
 * Returns:
 */
G_PASTE_VISIBLE void
g_paste_settings_ui_panel_add_separator (GPasteSettingsUiPanel *self)
{
    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);

    gtk_grid_attach (GTK_GRID (self), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL), 0, priv->current_line++, 3, 1);
}

static void
range_wrapper (GtkSpinButton *spinbutton,
               gpointer       user_data)
{<commit_msg>libgpaste-settings-ui: cosmetic tweak<commit_after>/*
 *      This file is part of GPaste.
 *
 *      Copyright 2013 <NAME> <<EMAIL>>
 *
 *      GPaste is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      GPaste is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with GPaste.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "gpaste-settings-ui-panel-private.h"

#include <stdlib.h>

struct _GPasteSettingsUiPanelPrivate
{
    GSList *callback_data;
    guint   current_line;
};

G_DEFINE_TYPE_WITH_PRIVATE (GPasteSettingsUiPanel, g_paste_settings_ui_panel, GTK_TYPE_GRID)

#define CALLBACK_DATA_FULL(cb, rcb, w, d, d2)                                                         \
    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);       \
    _CallbackDataWrapper *_data = (_CallbackDataWrapper *) g_malloc0 (sizeof (_CallbackDataWrapper)); \
    CallbackDataWrapper *data = (CallbackDataWrapper *) _data;                                        \
    priv->callback_data = g_slist_prepend (priv->callback_data, _data);                               \
    _data->widget = GTK_WIDGET (w);                                                                   \
    data->callback = G_CALLBACK (cb);                                                                 \
    data->reset_cb = rcb;                                                                             \
    data->custom_data = user_data;                                                                    \
    data->user_data = (d) ? GTK_WIDGET (d) : NULL;                                                    \
    data->user_data2 = (d2) ? GTK_WIDGET (d2) : NULL

#define CALLBACK_DATA_DEFAULT(w) \
    CALLBACK_DATA_FULL (on_value_changed, on_reset, w, NULL, NULL)

#define CALLBACK_DATA_CONFIRM2(w, d, d2) \
    CALLBACK_DATA_FULL (confirm_action, NULL, w, d, d2)

#define CALLBACK_DATA_CONFIRM(w, d) \
    CALLBACK_DATA_CONFIRM2 (w, d, NULL)

#define G_PASTE_CALLBACK(cb_type)                                  \
    CallbackDataWrapper *data = (CallbackDataWrapper *) user_data; \
    ((cb_type) data->callback)

#define G_PASTE_RESET_CALLBACK()                                   \
    CallbackDataWrapper *data = (CallbackDataWrapper *) user_data; \
    (data->reset_cb)

typedef struct
{
    GCallback           callback;
    GPasteResetCallback reset_cb;
    gpointer            custom_data;
    GtkWidget          *user_data;
    GtkWidget          *user_data2;
} CallbackDataWrapper;

typedef struct
{
    CallbackDataWrapper wrap;
    GtkWidget          *widget;
    GtkWidget          *reset_widget;
    gulong              signal;
    gulong              reset_signal;
} _CallbackDataWrapper;

static void
boolean_wrapper (GObject    *object,
                 GParamSpec *pspec G_GNUC_UNUSED,
                 gpointer    user_data)
{
    G_PASTE_CALLBACK (GPasteBooleanCallback) (gtk_switch_get_active (GTK_SWITCH (object)), data->custom_data);
}

static GtkLabel *
g_paste_settings_ui_panel_add_label (GPasteSettingsUiPanel *self,
                                     const gchar           *label)
{
    GtkWidget *button_label = gtk_widget_new (GTK_TYPE_LABEL,
                                              "label",  label,
                                              "xalign", 0.0,
                                              NULL);

    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);

    gtk_widget_set_hexpand (button_label, TRUE);
    gtk_grid_attach (GTK_GRID (self), button_label, 0, priv->current_line++, 1, 1);

    return GTK_LABEL (button_label);
}

static gboolean
g_paste_settings_ui_panel_on_reset_pressed (GtkWidget *widget G_GNUC_UNUSED,
                                            GdkEvent  *event  G_GNUC_UNUSED,
                                            gpointer   user_data)
{
    G_PASTE_RESET_CALLBACK () (data->custom_data);
    return FALSE;
}

static GtkWidget *
g_paste_settings_ui_panel_make_reset_button (_CallbackDataWrapper *data)
{
    data->reset_widget = gtk_button_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_BUTTON);
    data->reset_signal = g_signal_connect (G_OBJECT (data->reset_widget),
                                           "button-press-event",
                                           G_CALLBACK (g_paste_settings_ui_panel_on_reset_pressed),
                                           data);
    if (!((CallbackDataWrapper *) data)->reset_cb)
        gtk_widget_set_sensitive (data->reset_widget, FALSE);
    return data->reset_widget;
}

/**
 * g_paste_settings_ui_panel_add_boolean_setting:
 * @self: a #GPasteSettingsUiPanel instance
 * @label: the label to display
 * @value: the deafault value
 * @on_value_changed: (closure user_data) (scope notified): the callback to call when the value changes
 * @on_reset: (closure user_data) (scope notified): the callback to call when the value is reset
 *
 * Add a new boolean settings to the current pane
 *
 * Returns: (transfer none): the #GtkSwitch we just added
 */
G_PASTE_VISIBLE GtkSwitch *
g_paste_settings_ui_panel_add_boolean_setting (GPasteSettingsUiPanel *self,
                                               const gchar           *label,
                                               gboolean               value,
                                               GPasteBooleanCallback  on_value_changed,
                                               GPasteResetCallback    on_reset,
                                               gpointer               user_data)
{
    GtkGrid *grid = GTK_GRID (self);
    GtkLabel *button_label = g_paste_settings_ui_panel_add_label (self, label);
    GtkWidget *widget = gtk_switch_new ();
    GtkSwitch *sw = GTK_SWITCH (widget);
    CALLBACK_DATA_DEFAULT (widget);

    gtk_switch_set_active (sw, value);
    _data->signal = g_signal_connect (widget, "notify::active", G_CALLBACK (boolean_wrapper), data);
    gtk_grid_attach_next_to (grid, widget, GTK_WIDGET (button_label), GTK_POS_RIGHT, 1, 1);
    gtk_grid_attach_next_to (grid, g_paste_settings_ui_panel_make_reset_button (_data), widget, GTK_POS_RIGHT, 1, 1);

    return sw;
}

/**
 * g_paste_settings_ui_panel_add_separator:
 * @self: a #GPasteSettingsUiPanel instance
 *
 * Add a new separator to the current pane
 *
 * Returns:
 */
G_PASTE_VISIBLE void
g_paste_settings_ui_panel_add_separator (GPasteSettingsUiPanel *self)
{
    GPasteSettingsUiPanelPrivate *priv = g_paste_settings_ui_panel_get_instance_private (self);

    gtk_grid_attach (GTK_GRID (self), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL), 0, priv->current_line++, 3, 1);
}

static void
range_wrapper (GtkSpinButton *spinbutton,
               gpointer       user_data)
{
{'fraction_non_alphanumeric': 0.07573329617501567, 'fraction_numerical': 0.0037622796627882673, 'mean_word_length': 2.0566439522998294, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 84, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '522158', 'n_tokens_mistral': 4179, 'n_tokens_neox': 4016, 'n_words': 960}