From 923980628803706669ed7048b618dc6d54630e91 Mon Sep 17 00:00:00 2001 From: Gabriele Barbero Date: Tue, 29 Apr 2025 18:04:42 +0200 Subject: [PATCH] Issue #1056 - Implement shortcuts in text tool... ...for toggle bold/italic/underline. This commit adds support for common formatting shortcuts in the Text Tool: - Ctrl+B: Toggle bold - Ctrl+I: Toggle italic - Ctrl+U: Toggle underline --- app/actions/text-tool-actions.c | 18 ++++++++++++++ app/actions/text-tool-commands.c | 30 +++++++++++++++++++++++ app/actions/text-tool-commands.h | 10 ++++++++ app/tools/gimptexttool-editor.c | 30 +++++++++++++++++++---- app/tools/gimptexttool.c | 41 ++++++++++++++++++++++++++++++++ app/tools/gimptexttool.h | 2 ++ menus/text-tool-menu.ui | 5 ++++ 7 files changed, 132 insertions(+), 4 deletions(-) diff --git a/app/actions/text-tool-actions.c b/app/actions/text-tool-actions.c index 0fcf5e32f1..85631a0dcd 100644 --- a/app/actions/text-tool-actions.c +++ b/app/actions/text-tool-actions.c @@ -61,6 +61,21 @@ static const GimpActionEntry text_tool_actions[] = text_tool_paste_cmd_callback, GIMP_HELP_TEXT_TOOL_PASTE }, + { "text-tool-toggle-bold", GIMP_ICON_FORMAT_TEXT_BOLD, + NC_("text-tool-action", "_Bold"), NULL, { "B", NULL }, NULL, + text_tool_toggle_bold_cmd_callback, + NULL }, + + { "text-tool-toggle-italic", GIMP_ICON_FORMAT_TEXT_ITALIC, + NC_("text-tool-action", "_Italic"), NULL, { "I", NULL }, NULL, + text_tool_toggle_italic_cmd_callback, + NULL }, + + { "text-tool-toggle-underline", GIMP_ICON_FORMAT_TEXT_UNDERLINE, + NC_("text-tool-action", "_Underline"), NULL, { "U", NULL }, NULL, + text_tool_toggle_underline_cmd_callback, + NULL }, + { "text-tool-delete", GIMP_ICON_EDIT_DELETE, NC_("text-tool-action", "_Delete"), NULL, { NULL }, NULL, text_tool_delete_cmd_callback, @@ -192,6 +207,9 @@ text_tool_actions_update (GimpActionGroup *group, SET_SENSITIVE ("text-tool-cut", text_sel); SET_SENSITIVE ("text-tool-copy", text_sel); SET_SENSITIVE ("text-tool-paste", clip); + SET_SENSITIVE ("text-tool-toggle-bold", text_sel); + SET_SENSITIVE ("text-tool-toggle-italic", text_sel); + SET_SENSITIVE ("text-tool-toggle-underline",text_sel); SET_SENSITIVE ("text-tool-delete", text_sel); SET_SENSITIVE ("text-tool-clear", text_layer); SET_SENSITIVE ("text-tool-load", image); diff --git a/app/actions/text-tool-commands.c b/app/actions/text-tool-commands.c index 882aaff7b0..f8a95c0f77 100644 --- a/app/actions/text-tool-commands.c +++ b/app/actions/text-tool-commands.c @@ -84,6 +84,36 @@ text_tool_paste_cmd_callback (GimpAction *action, gimp_text_tool_paste_clipboard (text_tool); } +void +text_tool_toggle_bold_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data) +{ + GimpTextTool *text_tool = GIMP_TEXT_TOOL (data); + + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->bold_tag); +} + +void +text_tool_toggle_italic_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data) +{ + GimpTextTool *text_tool = GIMP_TEXT_TOOL (data); + + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->italic_tag); +} + +void +text_tool_toggle_underline_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data) +{ + GimpTextTool *text_tool = GIMP_TEXT_TOOL (data); + + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->underline_tag); +} + void text_tool_delete_cmd_callback (GimpAction *action, GVariant *value, diff --git a/app/actions/text-tool-commands.h b/app/actions/text-tool-commands.h index d7bef1c8ad..d33faad17d 100644 --- a/app/actions/text-tool-commands.h +++ b/app/actions/text-tool-commands.h @@ -28,6 +28,16 @@ void text_tool_copy_cmd_callback (GimpAction *action, void text_tool_paste_cmd_callback (GimpAction *action, GVariant *value, gpointer data); +void text_tool_toggle_bold_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data); +void text_tool_toggle_italic_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data); +void text_tool_toggle_underline_cmd_callback + (GimpAction *action, + GVariant *value, + gpointer data); void text_tool_delete_cmd_callback (GimpAction *action, GVariant *value, gpointer data); diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c index c8ac4d5ba5..78fd4298bb 100644 --- a/app/tools/gimptexttool-editor.c +++ b/app/tools/gimptexttool-editor.c @@ -448,12 +448,14 @@ gboolean gimp_text_tool_editor_key_press (GimpTextTool *text_tool, GdkEventKey *kevent) { - GimpTool *tool = GIMP_TOOL (text_tool); - GimpDisplayShell *shell = gimp_display_get_shell (tool->display); - GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer); + GimpTool *tool = GIMP_TOOL (text_tool); + GimpDisplayShell *shell = gimp_display_get_shell (tool->display); + GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer); GtkTextIter cursor; GtkTextIter selection; - gboolean retval = TRUE; + gboolean retval = TRUE; + GdkDisplay *display = gdk_display_get_default (); + GdkModifierType primary_mask; if (! gtk_widget_has_focus (shell->canvas)) { @@ -499,6 +501,8 @@ gimp_text_tool_editor_key_press (GimpTextTool *text_tool, gtk_text_buffer_get_iter_at_mark (buffer, &selection, gtk_text_buffer_get_selection_bound (buffer)); + primary_mask = gdk_keymap_get_modifier_mask (gdk_keymap_get_for_display (display), + GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR); switch (kevent->keyval) { case GDK_KEY_Return: @@ -520,6 +524,24 @@ gimp_text_tool_editor_key_press (GimpTextTool *text_tool, GIMP_TOOL (text_tool)->display); break; + case GDK_KEY_b: + case GDK_KEY_B: + if ((kevent->state & gimp_get_all_modifiers_mask()) == primary_mask) + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->bold_tag); + break; + + case GDK_KEY_i: + case GDK_KEY_I: + if ((kevent->state & gimp_get_all_modifiers_mask()) == primary_mask) + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->italic_tag); + break; + + case GDK_KEY_u: + case GDK_KEY_U: + if ((kevent->state & gimp_get_all_modifiers_mask()) == primary_mask) + gimp_text_tool_toggle_tag (text_tool, text_tool->buffer->underline_tag); + break; + default: retval = FALSE; } diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c index 1c91ed4230..73481866ce 100644 --- a/app/tools/gimptexttool.c +++ b/app/tools/gimptexttool.c @@ -2309,6 +2309,47 @@ gimp_text_tool_paste_clipboard (GimpTextTool *text_tool) clipboard, NULL, TRUE); } +void +gimp_text_tool_toggle_tag (GimpTextTool *text_tool, + GtkTextTag *tag) +{ + GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer); + + g_return_if_fail (GIMP_IS_TEXT_TOOL (text_tool)); + + if (gtk_text_buffer_get_has_selection (buffer)) + { + GtkTextIter start; + GtkTextIter end; + GtkTextIter iter; + gboolean is_tag_active = FALSE; + + gtk_text_buffer_get_selection_bounds (buffer, &start, &end); + + iter = start; + while (! gtk_text_iter_equal (&iter, &end)) + { + if (gtk_text_iter_has_tag (&iter, tag)) + { + is_tag_active = TRUE; + break; + } + gtk_text_iter_forward_char (&iter); + } + + gtk_text_buffer_begin_user_action (buffer); + + if (is_tag_active) + gtk_text_buffer_remove_tag (buffer, tag, + &start, &end); + else + gtk_text_buffer_apply_tag (buffer, tag, + &start, &end); + + gtk_text_buffer_end_user_action (buffer); + } +} + void gimp_text_tool_create_vectors (GimpTextTool *text_tool) { diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h index a46f7fb9d1..3613f8ee12 100644 --- a/app/tools/gimptexttool.h +++ b/app/tools/gimptexttool.h @@ -114,6 +114,8 @@ void gimp_text_tool_delete_selection (GimpTextTool *text_tool); void gimp_text_tool_cut_clipboard (GimpTextTool *text_tool); void gimp_text_tool_copy_clipboard (GimpTextTool *text_tool); void gimp_text_tool_paste_clipboard (GimpTextTool *text_tool); +void gimp_text_tool_toggle_tag (GimpTextTool *text_tool, + GtkTextTag *tag); void gimp_text_tool_create_vectors (GimpTextTool *text_tool); gboolean gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool, diff --git a/menus/text-tool-menu.ui b/menus/text-tool-menu.ui index 1881c5ac9c..3b1fc93fe7 100644 --- a/menus/text-tool-menu.ui +++ b/menus/text-tool-menu.ui @@ -9,6 +9,11 @@ text-tool.text-tool-copy text-tool.text-tool-paste text-tool.text-tool-delete +
+ text-tool.text-tool-toggle-bold + text-tool.text-tool-toggle-italic + text-tool.text-tool-toggle-underline +
text-tool.text-tool-load text-tool.text-tool-clear