Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
367 changes: 367 additions & 0 deletions src/mate-calc-actions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,367 @@
/*
* mate-calc-actions.c - Centralized actions and accelerators for MATE Calculator
*
* Copyright (C) 2024 MATE Desktop Team
*
* This program 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 2 of the License, or (at your option) any later
* version. See http://www.gnu.org/copyleft/gpl.html the full text of the
* license.
*/

#include <config.h>

#include <glib/gi18n.h>
#include <mpc.h>
#include <mpfr.h>

#include "mate-calc-actions.h"
#include "mate-calc-application.h"
#include "mate-calc-settings.h"
#include "math-window.h"

/*
* Accelerator definitions - centralized for future libmateui integration
*/
typedef struct {
const gchar *action_name;
const gchar *accel;
} AccelEntry;

static const AccelEntry app_accels[] = {
{ "app.quit", "<Control>q" },
{ "app.quit", "<Control>w" },
{ "app.help", "F1" },
{ "win.copy", "<Control>c" },
{ "win.paste", "<Control>v" },
{ "win.undo", "<Control>z" },
{ "win.redo", "<Control><Shift>z" },
{ "win.clear-history", "<Control><Shift>Delete" },
{ "win.toggle-history", "<Control><Shift>h" },
};

/*
* Application action callbacks
*/
static void
action_quit(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = GTK_APPLICATION(user_data);
GtkWindow *window;

/* Close only the active window; app quits when last window closes */
window = gtk_application_get_active_window(app);
if (window)
gtk_widget_destroy(GTK_WIDGET(window));
}

static void
action_preferences(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = GTK_APPLICATION(user_data);
GtkWindow *window;

window = gtk_application_get_active_window(app);
if (MATH_WINDOW(window))
{
math_window_show_preferences(MATH_WINDOW(window));
}
}

static void
action_help(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = GTK_APPLICATION(user_data);
GtkWindow *window;
GError *error = NULL;

window = gtk_application_get_active_window(app);

gtk_show_uri_on_window(window,
"help:mate-calc",
gtk_get_current_event_time(),
&error);

if (error != NULL)
{
GtkWidget *dialog;
const char *message = _("Unable to open help file");

dialog = gtk_message_dialog_new(window,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s", message);
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
"%s", error->message);
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
gtk_window_present(GTK_WINDOW(dialog));

g_error_free(error);
}
}

#define ABOUT_GROUP "About"
#define EMAILIFY(string) (g_strdelimit((string), "%", '@'))

static void
action_about(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = GTK_APPLICATION(user_data);
GtkWindow *window;

const char *documenters[] = {
N_("Sun Microsystems"),
N_("MATE Documentation Team"),
NULL
};

const char *license[] = {
N_("MATE Calculator 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 2 of the License, or "
"(at your option) any later version."),
N_("MATE Calculator 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."),
N_("You should have received a copy of the GNU General Public License "
"along with MATE Calculator; if not, write to the Free Software Foundation, Inc., "
"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.")
};

char *license_trans;
GKeyFile *key_file;
GBytes *bytes;
const guint8 *data;
gsize data_len;
GError *error = NULL;
char **authors;
gsize n_authors = 0, i;
gchar *comments = NULL;
const char **p;

window = gtk_application_get_active_window(app);

license_trans = g_strjoin("\n\n", _(license[0]), _(license[1]), _(license[2]), NULL);

bytes = g_resources_lookup_data("/org/mate/calculator/ui/mate-calc.about",
G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
g_assert_no_error(error);

data = g_bytes_get_data(bytes, &data_len);
key_file = g_key_file_new();
g_key_file_load_from_data(key_file, (const char *)data, data_len, 0, &error);
g_assert_no_error(error);

authors = g_key_file_get_string_list(key_file, ABOUT_GROUP, "Authors", &n_authors, NULL);

g_key_file_free(key_file);
g_bytes_unref(bytes);

for (i = 0; i < n_authors; ++i)
authors[i] = EMAILIFY(authors[i]);

for (p = documenters; *p; ++p)
*p = _(*p);

comments = g_strdup_printf(_("Calculator with financial and scientific modes.\nUsing GNU MPFR %s and GNU MPC %s"),
mpfr_get_version(), mpc_get_version());

gtk_show_about_dialog(window,
"program-name", _("MATE Calculator"),
"version", VERSION,
"title", _("About MATE Calculator"),
"copyright", _("Copyright \xc2\xa9 1986–2010 The GCalctool authors\n"
"Copyright \xc2\xa9 2011-2021 MATE developers"),
"license", license_trans,
"comments", comments,
"authors", authors,
"documenters", documenters,
"translator_credits", _("translator-credits"),
"wrap-license", TRUE,
"website", PACKAGE_URL,
"icon-name", "accessories-calculator",
"logo-icon-name", "accessories-calculator",
NULL);

g_free(comments);
g_strfreev(authors);
g_free(license_trans);
}

/*
* Window action callbacks
*/
static void
action_copy(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
MathEquation *equation = math_window_get_equation(window);
math_equation_copy(equation);
}

static void
action_paste(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
MathEquation *equation = math_window_get_equation(window);
math_equation_paste(equation);
}

static void
action_undo(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
MathEquation *equation = math_window_get_equation(window);
math_equation_undo(equation);
}

static void
action_redo(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
MathEquation *equation = math_window_get_equation(window);
math_equation_redo(equation);
}

static void
action_clear_history(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
math_window_clear_history(window);
}

static void
action_toggle_history(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
gboolean visible = math_window_get_show_history(window);
math_window_set_show_history(window, !visible);
}

static void
action_mode(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
MathWindow *window = MATH_WINDOW(user_data);
MathButtons *buttons = math_window_get_buttons(window);
const gchar *mode_str = g_variant_get_string(parameter, NULL);
ButtonMode mode = BASIC;

if (g_strcmp0(mode_str, "basic") == 0)
mode = BASIC;
else if (g_strcmp0(mode_str, "advanced") == 0)
mode = ADVANCED;
else if (g_strcmp0(mode_str, "financial") == 0)
mode = FINANCIAL;
else if (g_strcmp0(mode_str, "programming") == 0)
mode = PROGRAMMING;

math_buttons_set_mode(buttons, mode);
g_simple_action_set_state(action, parameter);
}

/*
* Application action entries
*/
static const GActionEntry app_action_entries[] = {
{ "quit", action_quit, NULL, NULL, NULL },
{ "preferences", action_preferences, NULL, NULL, NULL },
{ "help", action_help, NULL, NULL, NULL },
{ "about", action_about, NULL, NULL, NULL },
};

/*
* Window action entries
*/
static const GActionEntry win_action_entries[] = {
{ "copy", action_copy, NULL, NULL, NULL },
{ "paste", action_paste, NULL, NULL, NULL },
{ "undo", action_undo, NULL, NULL, NULL },
{ "redo", action_redo, NULL, NULL, NULL },
{ "clear-history", action_clear_history, NULL, NULL, NULL },
{ "toggle-history", action_toggle_history, NULL, NULL, NULL },
{ "mode", action_mode, "s", "'basic'", NULL },
};

void
mate_calc_actions_setup(GtkApplication *app)
{
gsize i;

g_return_if_fail(GTK_IS_APPLICATION(app));

/* Add application actions */
g_action_map_add_action_entries(G_ACTION_MAP(app),
app_action_entries,
G_N_ELEMENTS(app_action_entries),
app);

/* Setup accelerators */
for (i = 0; i < G_N_ELEMENTS(app_accels); i++)
{
const gchar *accels[] = { app_accels[i].accel, NULL };
gtk_application_set_accels_for_action(app,
app_accels[i].action_name,
accels);
}
}

void
mate_calc_actions_setup_window(GtkWindow *window,
GtkApplication *app)
{
g_return_if_fail(GTK_IS_WINDOW(window));
g_return_if_fail(GTK_IS_APPLICATION(app));

/* Add window actions */
g_action_map_add_action_entries(G_ACTION_MAP(window),
win_action_entries,
G_N_ELEMENTS(win_action_entries),
window);
}

const gchar *const *
mate_calc_actions_get_accel_entries(gsize *n_entries)
{
static const gchar *entries[] = {
"app.quit", "<Control>q",
"app.quit", "<Control>w",
"app.help", "F1",
"win.copy", "<Control>c",
"win.paste", "<Control>v",
"win.undo", "<Control>z",
"win.redo", "<Control><Shift>z",
"win.clear-history", "<Control><Shift>Delete",
"win.toggle-history", "<Control><Shift>h",
NULL
};

if (n_entries)
*n_entries = G_N_ELEMENTS(entries) - 1;

return entries;
}
Loading
Loading