[gimp] app: split the text editor code out to a separate file
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: split the text editor code out to a separate file
- Date: Wed, 17 Feb 2010 20:25:58 +0000 (UTC)
commit 8f27ec48c6a0e1e7f6a25b1893561a6b64776348
Author: Michael Natterer <mitch gimp org>
Date: Wed Feb 17 21:23:15 2010 +0100
app: split the text editor code out to a separate file
app/tools/Makefile.am | 2 +
app/tools/gimptexttool-editor.c | 833 +++++++++++++++++++++++++++++++++++++++
app/tools/gimptexttool-editor.h | 38 ++
app/tools/gimptexttool.c | 781 +------------------------------------
app/tools/gimptexttool.h | 5 +
5 files changed, 889 insertions(+), 770 deletions(-)
---
diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am
index b35855d..57a1f55 100644
--- a/app/tools/Makefile.am
+++ b/app/tools/Makefile.am
@@ -170,6 +170,8 @@ libapptools_a_sources = \
gimptextoptions.h \
gimptexttool.c \
gimptexttool.h \
+ gimptexttool-editor.c \
+ gimptexttool-editor.h \
gimpthresholdtool.c \
gimpthresholdtool.h \
gimptool.c \
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
new file mode 100644
index 0000000..dbdefdf
--- /dev/null
+++ b/app/tools/gimptexttool-editor.c
@@ -0,0 +1,833 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpTextTool
+ * Copyright (C) 2002-2004 Sven Neumann <sven gimp org>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "text/gimptext.h"
+#include "text/gimptextlayout.h"
+
+#include "widgets/gimpdialogfactory.h"
+#include "widgets/gimptexteditor.h"
+#include "widgets/gimptextproxy.h"
+
+#include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
+
+#include "gimprectangletool.h"
+#include "gimptextoptions.h"
+#include "gimptexttool.h"
+#include "gimptexttool-editor.h"
+
+#include "gimp-intl.h"
+
+
+/* local function prototypes */
+
+static void gimp_text_tool_ensure_proxy (GimpTextTool *text_tool);
+static void gimp_text_tool_move_cursor (GimpTextTool *text_tool,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection);
+static void gimp_text_tool_insert_at_cursor (GimpTextTool *text_tool,
+ const gchar *str);
+static void gimp_text_tool_delete_from_cursor (GimpTextTool *text_tool,
+ GtkDeleteType type,
+ gint count);
+static void gimp_text_tool_backspace (GimpTextTool *text_tool);
+static void gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool);
+static void gimp_text_tool_select_all (GimpTextTool *text_tool,
+ gboolean select);
+static void gimp_text_tool_options_notify (GimpTextOptions *options,
+ GParamSpec *pspec,
+ GimpTextTool *text_tool);
+static void gimp_text_tool_editor_dialog (GimpTextTool *text_tool);
+static void gimp_text_tool_enter_text (GimpTextTool *text_tool,
+ const gchar *str);
+static void gimp_text_tool_reset_im_context (GimpTextTool *text_tool);
+static void gimp_text_tool_commit_cb (GtkIMContext *context,
+ const gchar *str,
+ GimpTextTool *text_tool);
+static void gimp_text_tool_preedit_changed_cb (GtkIMContext *context,
+ GimpTextTool *text_tool);
+
+
+/* public functions */
+
+void
+gimp_text_tool_editor_init (GimpTextTool *text_tool)
+{
+ text_tool->im_context = gtk_im_multicontext_new ();
+
+ text_tool->preedit_string = NULL;
+ text_tool->overwrite_mode = FALSE;
+
+ text_tool->x_pos = -1;
+
+ g_signal_connect (text_tool->im_context, "commit",
+ G_CALLBACK (gimp_text_tool_commit_cb),
+ text_tool);
+ g_signal_connect (text_tool->im_context, "preedit-changed",
+ G_CALLBACK (gimp_text_tool_preedit_changed_cb),
+ text_tool);
+
+}
+
+void
+gimp_text_tool_editor_finalize (GimpTextTool *text_tool)
+{
+ if (text_tool->im_context)
+ {
+ g_object_unref (text_tool->im_context);
+ text_tool->im_context = NULL;
+ }
+}
+
+void
+gimp_text_tool_editor_start (GimpTextTool *text_tool)
+{
+ GimpTool *tool = GIMP_TOOL (text_tool);
+ GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+
+ gtk_im_context_set_client_window (text_tool->im_context,
+ gtk_widget_get_window (shell->canvas));
+
+ gtk_im_context_focus_in (text_tool->im_context);
+
+ if (text_tool->text)
+ gtk_text_buffer_set_text (text_tool->text_buffer,
+ text_tool->text->text, -1);
+ else
+ gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
+
+ gimp_text_tool_update_layout (text_tool);
+
+ if (options->use_editor)
+ gimp_text_tool_editor_dialog (text_tool);
+
+ g_signal_connect (options, "notify::use-editor",
+ G_CALLBACK (gimp_text_tool_options_notify),
+ text_tool);
+}
+
+void
+gimp_text_tool_editor_halt (GimpTextTool *text_tool)
+{
+ GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+
+ g_signal_handlers_disconnect_by_func (options,
+ gimp_text_tool_options_notify,
+ text_tool);
+
+ if (text_tool->editor)
+ gtk_widget_destroy (text_tool->editor);
+
+ if (text_tool->proxy_text_view)
+ {
+ gtk_widget_destroy (text_tool->offscreen_window);
+ text_tool->offscreen_window = NULL;
+ text_tool->proxy_text_view = NULL;
+ }
+
+ gtk_im_context_focus_out (text_tool->im_context);
+
+ gtk_im_context_set_client_window (text_tool->im_context, NULL);
+}
+
+gboolean
+gimp_text_tool_editor_key_press (GimpTextTool *text_tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+ GtkTextIter cursor;
+ GtkTextIter selection;
+ gint x_pos = -1;
+ gboolean retval = TRUE;
+
+ if (gtk_im_context_filter_keypress (text_tool->im_context, kevent))
+ {
+ text_tool->needs_im_reset = TRUE;
+ text_tool->x_pos = -1;
+
+ return TRUE;
+ }
+
+ gimp_text_tool_ensure_proxy (text_tool);
+
+ if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view),
+ kevent))
+ {
+ g_printerr ("binding handled event!\n");
+ return TRUE;
+ }
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_buffer_get_iter_at_mark (buffer, &selection,
+ gtk_text_buffer_get_selection_bound (buffer));
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ switch (kevent->keyval)
+ {
+ case GDK_Return:
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ gimp_text_tool_enter_text (text_tool, "\n");
+ gimp_text_tool_reset_im_context (text_tool);
+ gimp_text_tool_update_layout (text_tool);
+ break;
+
+ case GDK_Tab:
+ case GDK_KP_Tab:
+ case GDK_ISO_Left_Tab:
+ gimp_text_tool_enter_text (text_tool, "\t");
+ gimp_text_tool_reset_im_context (text_tool);
+ gimp_text_tool_update_layout (text_tool);
+ break;
+
+ case GDK_Escape:
+ gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (text_tool));
+ gimp_tool_control (GIMP_TOOL (text_tool), GIMP_TOOL_ACTION_HALT,
+ GIMP_TOOL (text_tool)->display);
+ break;
+
+ default:
+ retval = FALSE;
+ }
+
+ text_tool->x_pos = x_pos;
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+
+ return retval;
+}
+
+static void
+gimp_text_tool_ensure_proxy (GimpTextTool *text_tool)
+{
+ GimpTool *tool = GIMP_TOOL (text_tool);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+
+ if (text_tool->offscreen_window &&
+ gtk_widget_get_screen (text_tool->offscreen_window) !=
+ gtk_widget_get_screen (GTK_WIDGET (shell)))
+ {
+ gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
+ gtk_widget_get_screen (GTK_WIDGET (shell)));
+ gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
+ }
+ else if (! text_tool->offscreen_window)
+ {
+ text_tool->offscreen_window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
+ gtk_widget_get_screen (GTK_WIDGET (shell)));
+ gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
+ gtk_widget_show (text_tool->offscreen_window);
+
+ text_tool->proxy_text_view = gimp_text_proxy_new ();
+ gtk_container_add (GTK_CONTAINER (text_tool->offscreen_window),
+ text_tool->proxy_text_view);
+ gtk_widget_show (text_tool->proxy_text_view);
+
+ g_signal_connect_swapped (text_tool->proxy_text_view, "move-cursor",
+ G_CALLBACK (gimp_text_tool_move_cursor),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "insert-at-cursor",
+ G_CALLBACK (gimp_text_tool_insert_at_cursor),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "delete-from-cursor",
+ G_CALLBACK (gimp_text_tool_delete_from_cursor),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "backspace",
+ G_CALLBACK (gimp_text_tool_backspace),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "cut-clipboard",
+ G_CALLBACK (gimp_text_tool_cut_clipboard),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "copy-clipboard",
+ G_CALLBACK (gimp_text_tool_copy_clipboard),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "paste-clipboard",
+ G_CALLBACK (gimp_text_tool_paste_clipboard),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "toggle-overwrite",
+ G_CALLBACK (gimp_text_tool_toggle_overwrite),
+ text_tool);
+ g_signal_connect_swapped (text_tool->proxy_text_view, "select-all",
+ G_CALLBACK (gimp_text_tool_select_all),
+ text_tool);
+ }
+}
+
+static void
+gimp_text_tool_move_cursor (GimpTextTool *text_tool,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+ GtkTextIter cursor;
+ GtkTextIter selection;
+ GtkTextIter *sel_start;
+ gboolean cancel_selection = FALSE;
+ gint x_pos = -1;
+
+ g_printerr ("%s: %s count = %d, select = %s\n",
+ G_STRFUNC,
+ g_enum_get_value (g_type_class_ref (GTK_TYPE_MOVEMENT_STEP),
+ step)->value_name,
+ count,
+ extend_selection ? "TRUE" : "FALSE");
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_buffer_get_iter_at_mark (buffer, &selection,
+ gtk_text_buffer_get_selection_bound (buffer));
+
+ if (extend_selection)
+ {
+ sel_start = &selection;
+ }
+ else
+ {
+ /* when there is a selection, moving the cursor without
+ * extending it should move the cursor to the end of the
+ * selection that is in moving direction
+ */
+ if (count > 0)
+ gtk_text_iter_order (&selection, &cursor);
+ else
+ gtk_text_iter_order (&cursor, &selection);
+
+ sel_start = &cursor;
+
+ /* if we actually have a selection, just move *to* the beginning/end
+ * of the selection and not *from* there on LOGICAL_POSITIONS
+ * and VISUAL_POSITIONS movement
+ */
+ if (! gtk_text_iter_equal (&cursor, &selection))
+ cancel_selection = TRUE;
+ }
+
+ switch (step)
+ {
+ case GTK_MOVEMENT_LOGICAL_POSITIONS:
+ if (! cancel_selection)
+ gtk_text_iter_forward_visible_cursor_positions (&cursor, count);
+ break;
+
+ case GTK_MOVEMENT_VISUAL_POSITIONS:
+ if (! cancel_selection)
+ {
+ if (count < 0)
+ gtk_text_iter_backward_cursor_position (&cursor);
+ else if (count > 0)
+ gtk_text_iter_forward_cursor_position (&cursor);
+ }
+ break;
+
+ case GTK_MOVEMENT_WORDS:
+ if (count < 0)
+ {
+ gtk_text_iter_backward_visible_word_starts (&cursor, -count);
+ }
+ else if (count > 0)
+ {
+ if (! gtk_text_iter_forward_visible_word_ends (&cursor, count))
+ gtk_text_iter_forward_to_line_end (&cursor);
+ }
+ break;
+
+ case GTK_MOVEMENT_DISPLAY_LINES:
+ {
+ GtkTextIter start;
+ GtkTextIter end;
+ gchar *string;
+ gint cursor_index;
+ PangoLayout *layout;
+ PangoLayoutLine *layout_line;
+ PangoLayoutIter *layout_iter;
+ PangoRectangle logical;
+ gint line;
+ gint trailing;
+ gint i;
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+ string = gtk_text_buffer_get_text (buffer, &start, &cursor, FALSE);
+ cursor_index = strlen (string);
+ g_free (string);
+
+ layout = gimp_text_layout_get_pango_layout (text_tool->layout);
+
+ pango_layout_index_to_line_x (layout, cursor_index, FALSE,
+ &line, &x_pos);
+
+ layout_iter = pango_layout_get_iter (layout);
+ for (i = 0; i < line; i++)
+ pango_layout_iter_next_line (layout_iter);
+
+ pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);
+
+ pango_layout_iter_free (layout_iter);
+
+ /* try to go to the remembered x_pos if it exists *and* we are at
+ * the beginning or at the end of the current line
+ */
+ if (text_tool->x_pos != -1 && (x_pos <= logical.x ||
+ x_pos >= logical.width))
+ x_pos = text_tool->x_pos;
+
+ line += count;
+
+ if (line < 0)
+ {
+ cursor = start;
+ break;
+ }
+ else if (line >= pango_layout_get_line_count (layout))
+ {
+ cursor = end;
+ break;
+ }
+
+ layout_iter = pango_layout_get_iter (layout);
+ for (i = 0; i < line; i++)
+ pango_layout_iter_next_line (layout_iter);
+
+ layout_line = pango_layout_iter_get_line_readonly (layout_iter);
+ pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);
+
+ pango_layout_iter_free (layout_iter);
+
+ pango_layout_line_x_to_index (layout_line, x_pos,
+ &cursor_index, &trailing);
+
+ string = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+
+ string[cursor_index] = '\0';
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &cursor,
+ g_utf8_strlen (string, -1));
+
+ g_free (string);
+
+ while (trailing--)
+ gtk_text_iter_forward_char (&cursor);
+ }
+ break;
+
+ case GTK_MOVEMENT_PAGES: /* well... */
+ case GTK_MOVEMENT_BUFFER_ENDS:
+ if (count < 0)
+ {
+ gtk_text_buffer_get_start_iter (buffer, &cursor);
+ }
+ else if (count > 0)
+ {
+ gtk_text_buffer_get_end_iter (buffer, &cursor);
+ }
+ break;
+
+ case GTK_MOVEMENT_PARAGRAPH_ENDS:
+ if (count < 0)
+ {
+ gtk_text_iter_set_line_offset (&cursor, 0);
+ }
+ else if (count > 0)
+ {
+ if (! gtk_text_iter_ends_line (&cursor))
+ gtk_text_iter_forward_to_line_end (&cursor);
+ }
+ break;
+
+ case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+ if (count < 0)
+ {
+ gtk_text_iter_set_line_offset (&cursor, 0);
+ }
+ else if (count > 0)
+ {
+ if (! gtk_text_iter_ends_line (&cursor))
+ gtk_text_iter_forward_to_line_end (&cursor);
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ text_tool->x_pos = x_pos;
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ gtk_text_buffer_select_range (buffer, &cursor, sel_start);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+}
+
+static void
+gimp_text_tool_insert_at_cursor (GimpTextTool *text_tool,
+ const gchar *str)
+{
+ gtk_text_buffer_insert_interactive_at_cursor (text_tool->text_buffer,
+ str, -1, TRUE);
+}
+
+static gboolean
+is_whitespace (gunichar ch,
+ gpointer user_data)
+{
+ return (ch == ' ' || ch == '\t');
+}
+
+static gboolean
+is_not_whitespace (gunichar ch,
+ gpointer user_data)
+{
+ return ! is_whitespace (ch, user_data);
+}
+
+static gboolean
+find_whitepace_region (const GtkTextIter *center,
+ GtkTextIter *start,
+ GtkTextIter *end)
+{
+ *start = *center;
+ *end = *center;
+
+ if (gtk_text_iter_backward_find_char (start, is_not_whitespace, NULL, NULL))
+ gtk_text_iter_forward_char (start); /* we want the first whitespace... */
+
+ if (is_whitespace (gtk_text_iter_get_char (end), NULL))
+ gtk_text_iter_forward_find_char (end, is_not_whitespace, NULL, NULL);
+
+ return ! gtk_text_iter_equal (start, end);
+}
+
+static void
+gimp_text_tool_delete_from_cursor (GimpTextTool *text_tool,
+ GtkDeleteType type,
+ gint count)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+ GtkTextIter cursor;
+ GtkTextIter end;
+
+ g_printerr ("%s: %s count = %d\n",
+ G_STRFUNC,
+ g_enum_get_value (g_type_class_ref (GTK_TYPE_DELETE_TYPE),
+ type)->value_name,
+ count);
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+ end = cursor;
+
+ switch (type)
+ {
+ case GTK_DELETE_CHARS:
+ if (gtk_text_buffer_get_has_selection (buffer))
+ {
+ gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
+ return;
+ }
+ else
+ {
+ gtk_text_iter_forward_cursor_positions (&end, count);
+ }
+ break;
+
+ case GTK_DELETE_WORD_ENDS:
+ if (count < 0)
+ {
+ if (! gtk_text_iter_starts_word (&cursor))
+ gtk_text_iter_backward_visible_word_starts (&cursor, 1);
+ }
+ else if (count > 0)
+ {
+ if (! gtk_text_iter_ends_word (&end) &&
+ ! gtk_text_iter_forward_visible_word_ends (&end, 1))
+ gtk_text_iter_forward_to_line_end (&end);
+ }
+ break;
+
+ case GTK_DELETE_WORDS:
+ if (! gtk_text_iter_starts_word (&cursor))
+ gtk_text_iter_backward_visible_word_starts (&cursor, 1);
+
+ if (! gtk_text_iter_ends_word (&end) &&
+ ! gtk_text_iter_forward_visible_word_ends (&end, 1))
+ gtk_text_iter_forward_to_line_end (&end);
+ break;
+
+ case GTK_DELETE_DISPLAY_LINES:
+ break;
+
+ case GTK_DELETE_DISPLAY_LINE_ENDS:
+ break;
+
+ case GTK_DELETE_PARAGRAPH_ENDS:
+ if (count < 0)
+ {
+ gtk_text_iter_set_line_offset (&cursor, 0);
+ }
+ else if (count > 0)
+ {
+ if (! gtk_text_iter_ends_line (&end))
+ gtk_text_iter_forward_to_line_end (&end);
+ else
+ gtk_text_iter_forward_cursor_positions (&end, 1);
+ }
+ break;
+
+ case GTK_DELETE_PARAGRAPHS:
+ break;
+
+ case GTK_DELETE_WHITESPACE:
+ find_whitepace_region (&cursor, &cursor, &end);
+ break;
+ }
+
+ if (! gtk_text_iter_equal (&cursor, &end))
+ {
+ gtk_text_buffer_delete_interactive (buffer, &cursor, &end, TRUE);
+ }
+}
+
+static void
+gimp_text_tool_backspace (GimpTextTool *text_tool)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+
+ if (gtk_text_buffer_get_has_selection (buffer))
+ {
+ gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
+ }
+ else
+ {
+ GtkTextIter cursor;
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+
+ gtk_text_buffer_backspace (buffer, &cursor, TRUE, TRUE);
+ }
+}
+
+static void
+gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool)
+{
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ text_tool->overwrite_mode = ! text_tool->overwrite_mode;
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+}
+
+static void
+gimp_text_tool_select_all (GimpTextTool *text_tool,
+ gboolean select)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ if (select)
+ {
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_select_range (buffer, &start, &end);
+ }
+ else
+ {
+ GtkTextIter cursor;
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &cursor);
+ }
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+}
+
+static void
+gimp_text_tool_options_notify (GimpTextOptions *options,
+ GParamSpec *pspec,
+ GimpTextTool *text_tool)
+{
+ const gchar *param_name = g_param_spec_get_name (pspec);
+
+ if (! strcmp (param_name, "use-editor"))
+ {
+ if (options->use_editor)
+ {
+ if (text_tool->text)
+ gimp_text_tool_editor_dialog (text_tool);
+ }
+ else
+ {
+ if (text_tool->editor)
+ gtk_widget_destroy (text_tool->editor);
+ }
+ }
+}
+
+static void
+gimp_text_tool_editor_dialog (GimpTextTool *text_tool)
+{
+ GimpTool *tool = GIMP_TOOL (text_tool);
+ GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+ GimpDialogFactory *dialog_factory;
+ GtkWindow *parent = NULL;
+
+ if (text_tool->editor)
+ {
+ gtk_window_present (GTK_WINDOW (text_tool->editor));
+ return;
+ }
+
+ dialog_factory = gimp_dialog_factory_from_name ("toplevel");
+
+ if (tool->display)
+ {
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+
+ parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (shell)));
+ }
+
+ text_tool->editor = gimp_text_options_editor_new (parent, options,
+ gimp_dialog_factory_get_menu_factory (dialog_factory),
+ _("GIMP Text Editor"),
+ text_tool->text_buffer);
+
+ g_object_add_weak_pointer (G_OBJECT (text_tool->editor),
+ (gpointer) &text_tool->editor);
+
+ gimp_dialog_factory_add_foreign (dialog_factory,
+ "gimp-text-tool-dialog",
+ text_tool->editor);
+
+ gtk_widget_show (text_tool->editor);
+}
+
+gchar *
+gimp_text_tool_editor_get_text (GimpTextTool *text_tool)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+ GtkTextIter start, end;
+ GtkTextIter selstart, selend;
+ gchar *string;
+ gchar *fb;
+ gchar *lb;
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_get_selection_bounds (buffer, &selstart, &selend);
+
+ fb = gtk_text_buffer_get_text (buffer, &start, &selstart, TRUE);
+ lb = gtk_text_buffer_get_text (buffer, &selstart, &end, TRUE);
+
+ if (text_tool->preedit_string)
+ {
+ if (fb == NULL)
+ string = g_strconcat (text_tool->preedit_string, lb, NULL);
+ else
+ string = g_strconcat (fb, text_tool->preedit_string, lb, NULL);
+ }
+ else
+ {
+ string = g_strconcat (fb, lb, NULL);
+ }
+
+ g_free (fb);
+ g_free (lb);
+
+ return string;
+}
+
+static void
+gimp_text_tool_enter_text (GimpTextTool *text_tool,
+ const gchar *str)
+{
+ GtkTextBuffer *buffer = text_tool->text_buffer;
+ gboolean had_selection;
+
+ had_selection = gtk_text_buffer_get_has_selection (buffer);
+
+ gimp_text_tool_delete_selection (text_tool);
+
+ if (! had_selection && text_tool->overwrite_mode && strcmp (str, "\n"))
+ {
+ GtkTextIter cursor;
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
+ gtk_text_buffer_get_insert (buffer));
+
+ if (! gtk_text_iter_ends_line (&cursor))
+ gimp_text_tool_delete_from_cursor (text_tool, GTK_DELETE_CHARS, 1);
+ }
+
+ gtk_text_buffer_insert_at_cursor (buffer, str, -1);
+}
+
+static void
+gimp_text_tool_reset_im_context (GimpTextTool *text_tool)
+{
+ if (text_tool->needs_im_reset)
+ {
+ text_tool->needs_im_reset = FALSE;
+ gtk_im_context_reset (text_tool->im_context);
+ }
+}
+
+static void
+gimp_text_tool_commit_cb (GtkIMContext *context,
+ const gchar *str,
+ GimpTextTool *text_tool)
+{
+ gimp_text_tool_enter_text (text_tool, str);
+}
+
+static void
+gimp_text_tool_preedit_changed_cb (GtkIMContext *context,
+ GimpTextTool *text_tool)
+{
+ if (text_tool->preedit_string)
+ g_free (text_tool->preedit_string);
+
+ gtk_im_context_get_preedit_string (context,
+ &text_tool->preedit_string, NULL,
+ &text_tool->preedit_cursor);
+
+ text_tool->preedit_len = strlen (text_tool->preedit_string);
+
+ gimp_text_tool_update_proxy (text_tool);
+}
diff --git a/app/tools/gimptexttool-editor.h b/app/tools/gimptexttool-editor.h
new file mode 100644
index 0000000..28aaad2
--- /dev/null
+++ b/app/tools/gimptexttool-editor.h
@@ -0,0 +1,38 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpTextTool
+ * Copyright (C) 2002-2004 Sven Neumann <sven gimp org>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_TEXT_TOOL_EDITOR_H__
+#define __GIMP_TEXT_TOOL_EDITOR_H__
+
+
+void gimp_text_tool_editor_init (GimpTextTool *text_tool);
+void gimp_text_tool_editor_finalize (GimpTextTool *text_tool);
+
+void gimp_text_tool_editor_start (GimpTextTool *text_tool);
+void gimp_text_tool_editor_halt (GimpTextTool *text_tool);
+
+gboolean gimp_text_tool_editor_key_press (GimpTextTool *text_tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display);
+
+gchar * gimp_text_tool_editor_get_text (GimpTextTool *text_tool);
+
+
+#endif /* __GIMP_TEXT_TOOL_EDITOR_H__ */
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 8f4ac68..823b5e2 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -22,7 +22,6 @@
#include <gegl.h>
#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
@@ -49,19 +48,16 @@
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpmenufactory.h"
-#include "widgets/gimptexteditor.h"
-#include "widgets/gimptextproxy.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpviewabledialog.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
-#include "gimpeditselectiontool.h"
#include "gimprectangletool.h"
-#include "gimprectangleoptions.h"
#include "gimptextoptions.h"
#include "gimptexttool.h"
+#include "gimptexttool-editor.h"
#include "gimptoolcontrol.h"
#include "gimp-intl.h"
@@ -133,28 +129,10 @@ static gboolean gimp_text_tool_rectangle_change_complete
static void gimp_text_tool_halt (GimpTextTool *text_tool);
-static void gimp_text_tool_ensure_proxy (GimpTextTool *text_tool);
-static void gimp_text_tool_move_cursor (GimpTextTool *text_tool,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection);
-static void gimp_text_tool_insert_at_cursor (GimpTextTool *text_tool,
- const gchar *str);
-static void gimp_text_tool_delete_from_cursor (GimpTextTool *text_tool,
- GtkDeleteType type,
- gint count);
-static void gimp_text_tool_backspace (GimpTextTool *text_tool);
-static void gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool);
-static void gimp_text_tool_select_all (GimpTextTool *text_tool,
- gboolean select);
-
static void gimp_text_tool_connect (GimpTextTool *text_tool,
GimpTextLayer *layer,
GimpText *text);
-static void gimp_text_tool_options_notify (GimpTextOptions *options,
- GParamSpec *pspec,
- GimpTextTool *text_tool);
static void gimp_text_tool_layer_notify (GimpTextLayer *layer,
GParamSpec *pspec,
GimpTextTool *text_tool);
@@ -170,10 +148,6 @@ static void gimp_text_tool_apply (GimpTextTool *text_tool);
static void gimp_text_tool_create_layer (GimpTextTool *text_tool,
GimpText *text);
-static void gimp_text_tool_editor_dialog (GimpTextTool *text_tool);
-static void gimp_text_tool_editor (GimpTextTool *text_tool);
-static gchar * gimp_text_tool_editor_get_text (GimpTextTool *text_tool);
-
static void gimp_text_tool_layer_changed (GimpImage *image,
GimpTextTool *text_tool);
static void gimp_text_tool_set_image (GimpTextTool *text_tool,
@@ -182,11 +156,6 @@ static gboolean gimp_text_tool_set_drawable (GimpTextTool *text_tool,
GimpDrawable *drawable,
gboolean confirm);
-static void gimp_text_tool_update_layout (GimpTextTool *text_tool);
-static void gimp_text_tool_update_proxy (GimpTextTool *text_tool);
-
-static void gimp_text_tool_enter_text (GimpTextTool *text_tool,
- const gchar *str);
static void gimp_text_tool_text_buffer_changed (GtkTextBuffer *text_buffer,
GimpTextTool *text_tool);
static void gimp_text_tool_text_buffer_mark_set (GtkTextBuffer *text_buffer,
@@ -198,14 +167,6 @@ static gint gimp_text_tool_xy_to_offset (GimpTextTool *text_tool,
gdouble x,
gdouble y);
-/* IM context utilities and callbacks */
-static void gimp_text_tool_reset_im_context (GimpTextTool *text_tool);
-static void gimp_text_tool_commit_cb (GtkIMContext *context,
- const gchar *str,
- GimpTextTool *text_tool);
-static void gimp_text_tool_preedit_changed_cb (GtkIMContext *context,
- GimpTextTool *text_tool);
-
G_DEFINE_TYPE_WITH_CODE (GimpTextTool, gimp_text_tool,
GIMP_TYPE_DRAW_TOOL,
@@ -293,16 +254,7 @@ gimp_text_tool_init (GimpTextTool *text_tool)
G_CALLBACK (gimp_text_tool_text_buffer_mark_set),
text_tool);
- text_tool->im_context = gtk_im_multicontext_new ();
-
- text_tool->preedit_string = NULL;
-
- g_signal_connect (text_tool->im_context, "commit",
- G_CALLBACK (gimp_text_tool_commit_cb),
- text_tool);
- g_signal_connect (text_tool->im_context, "preedit-changed",
- G_CALLBACK (gimp_text_tool_preedit_changed_cb),
- text_tool);
+ gimp_text_tool_editor_init (text_tool);
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_wants_double_click (tool->control, TRUE);
@@ -346,10 +298,6 @@ gimp_text_tool_constructor (GType type,
G_CALLBACK (gimp_text_tool_proxy_notify),
text_tool, 0);
- g_signal_connect_object (options, "notify::use-editor",
- G_CALLBACK (gimp_text_tool_options_notify),
- text_tool, 0);
-
g_object_set (options,
"highlight", FALSE,
NULL);
@@ -390,11 +338,7 @@ gimp_text_tool_finalize (GObject *object)
text_tool->text_buffer = NULL;
}
- if (text_tool->im_context)
- {
- g_object_unref (text_tool->im_context);
- text_tool->im_context = NULL;
- }
+ gimp_text_tool_editor_finalize (text_tool);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -517,7 +461,7 @@ gimp_text_tool_button_press (GimpTool *tool,
/* enable keyboard-handling for the text */
if (text_tool->text && text_tool->text != text)
{
- gimp_text_tool_editor (text_tool);
+ gimp_text_tool_editor_start (text_tool);
}
}
@@ -578,7 +522,7 @@ gimp_text_tool_button_press (GimpTool *tool,
text_tool->text_box_fixed = FALSE;
gimp_text_tool_connect (text_tool, NULL, NULL);
- gimp_text_tool_editor (text_tool);
+ gimp_text_tool_editor_start (text_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
@@ -791,71 +735,11 @@ gimp_text_tool_key_press (GimpTool *tool,
GimpDisplay *display)
{
GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
- GtkTextBuffer *buffer = text_tool->text_buffer;
- GtkTextIter cursor;
- GtkTextIter selection;
- gint x_pos = -1;
- gboolean retval = TRUE;
if (display != tool->display)
return FALSE;
- if (gtk_im_context_filter_keypress (text_tool->im_context, kevent))
- {
- text_tool->needs_im_reset = TRUE;
- text_tool->x_pos = -1;
-
- return TRUE;
- }
-
- gimp_text_tool_ensure_proxy (text_tool);
-
- if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view),
- kevent))
- {
- g_printerr ("binding handled event!\n");
- return TRUE;
- }
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_get_iter_at_mark (buffer, &selection,
- gtk_text_buffer_get_selection_bound (buffer));
-
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
-
- switch (kevent->keyval)
- {
- case GDK_Return:
- case GDK_KP_Enter:
- case GDK_ISO_Enter:
- gimp_text_tool_enter_text (text_tool, "\n");
- gimp_text_tool_reset_im_context (text_tool);
- gimp_text_tool_update_layout (text_tool);
- break;
-
- case GDK_Tab:
- case GDK_KP_Tab:
- case GDK_ISO_Left_Tab:
- gimp_text_tool_enter_text (text_tool, "\t");
- gimp_text_tool_reset_im_context (text_tool);
- gimp_text_tool_update_layout (text_tool);
- break;
-
- case GDK_Escape:
- gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool));
- gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
- break;
-
- default:
- retval = FALSE;
- }
-
- text_tool->x_pos = x_pos;
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
-
- return retval;
+ return gimp_text_tool_editor_key_press (text_tool, kevent, display);
}
static void
@@ -1354,469 +1238,7 @@ gimp_text_tool_halt (GimpTextTool *text_tool)
{
gimp_text_tool_set_drawable (text_tool, NULL, FALSE);
- if (text_tool->editor)
- gtk_widget_destroy (text_tool->editor);
-
- if (text_tool->proxy_text_view)
- {
- gtk_widget_destroy (text_tool->offscreen_window);
- text_tool->offscreen_window = NULL;
- text_tool->proxy_text_view = NULL;
- }
-
- gtk_im_context_focus_out (text_tool->im_context);
-
- gtk_im_context_set_client_window (text_tool->im_context, NULL);
-}
-
-static void
-gimp_text_tool_ensure_proxy (GimpTextTool *text_tool)
-{
- GimpTool *tool = GIMP_TOOL (text_tool);
- GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
-
- if (text_tool->offscreen_window &&
- gtk_widget_get_screen (text_tool->offscreen_window) !=
- gtk_widget_get_screen (GTK_WIDGET (shell)))
- {
- gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
- gtk_widget_get_screen (GTK_WIDGET (shell)));
- gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
- }
- else if (! text_tool->offscreen_window)
- {
- text_tool->offscreen_window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_window_set_screen (GTK_WINDOW (text_tool->offscreen_window),
- gtk_widget_get_screen (GTK_WIDGET (shell)));
- gtk_window_move (GTK_WINDOW (text_tool->offscreen_window), -200, -200);
- gtk_widget_show (text_tool->offscreen_window);
-
- text_tool->proxy_text_view = gimp_text_proxy_new ();
- gtk_container_add (GTK_CONTAINER (text_tool->offscreen_window),
- text_tool->proxy_text_view);
- gtk_widget_show (text_tool->proxy_text_view);
-
- g_signal_connect_swapped (text_tool->proxy_text_view, "move-cursor",
- G_CALLBACK (gimp_text_tool_move_cursor),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "insert-at-cursor",
- G_CALLBACK (gimp_text_tool_insert_at_cursor),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "delete-from-cursor",
- G_CALLBACK (gimp_text_tool_delete_from_cursor),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "backspace",
- G_CALLBACK (gimp_text_tool_backspace),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "cut-clipboard",
- G_CALLBACK (gimp_text_tool_cut_clipboard),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "copy-clipboard",
- G_CALLBACK (gimp_text_tool_copy_clipboard),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "paste-clipboard",
- G_CALLBACK (gimp_text_tool_paste_clipboard),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "toggle-overwrite",
- G_CALLBACK (gimp_text_tool_toggle_overwrite),
- text_tool);
- g_signal_connect_swapped (text_tool->proxy_text_view, "select-all",
- G_CALLBACK (gimp_text_tool_select_all),
- text_tool);
- }
-}
-
-static void
-gimp_text_tool_move_cursor (GimpTextTool *text_tool,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
- GtkTextIter cursor;
- GtkTextIter selection;
- GtkTextIter *sel_start;
- gboolean cancel_selection = FALSE;
- gint x_pos = -1;
-
- g_printerr ("%s: %s count = %d, select = %s\n",
- G_STRFUNC,
- g_enum_get_value (g_type_class_ref (GTK_TYPE_MOVEMENT_STEP),
- step)->value_name,
- count,
- extend_selection ? "TRUE" : "FALSE");
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_get_iter_at_mark (buffer, &selection,
- gtk_text_buffer_get_selection_bound (buffer));
-
- if (extend_selection)
- {
- sel_start = &selection;
- }
- else
- {
- /* when there is a selection, moving the cursor without
- * extending it should move the cursor to the end of the
- * selection that is in moving direction
- */
- if (count > 0)
- gtk_text_iter_order (&selection, &cursor);
- else
- gtk_text_iter_order (&cursor, &selection);
-
- sel_start = &cursor;
-
- /* if we actually have a selection, just move *to* the beginning/end
- * of the selection and not *from* there on LOGICAL_POSITIONS
- * and VISUAL_POSITIONS movement
- */
- if (! gtk_text_iter_equal (&cursor, &selection))
- cancel_selection = TRUE;
- }
-
- switch (step)
- {
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- if (! cancel_selection)
- gtk_text_iter_forward_visible_cursor_positions (&cursor, count);
- break;
-
- case GTK_MOVEMENT_VISUAL_POSITIONS:
- if (! cancel_selection)
- {
- if (count < 0)
- gtk_text_iter_backward_cursor_position (&cursor);
- else if (count > 0)
- gtk_text_iter_forward_cursor_position (&cursor);
- }
- break;
-
- case GTK_MOVEMENT_WORDS:
- if (count < 0)
- {
- gtk_text_iter_backward_visible_word_starts (&cursor, -count);
- }
- else if (count > 0)
- {
- if (! gtk_text_iter_forward_visible_word_ends (&cursor, count))
- gtk_text_iter_forward_to_line_end (&cursor);
- }
- break;
-
- case GTK_MOVEMENT_DISPLAY_LINES:
- {
- GtkTextIter start;
- GtkTextIter end;
- gchar *string;
- gint cursor_index;
- PangoLayout *layout;
- PangoLayoutLine *layout_line;
- PangoLayoutIter *layout_iter;
- PangoRectangle logical;
- gint line;
- gint trailing;
- gint i;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
-
- string = gtk_text_buffer_get_text (buffer, &start, &cursor, FALSE);
- cursor_index = strlen (string);
- g_free (string);
-
- layout = gimp_text_layout_get_pango_layout (text_tool->layout);
-
- pango_layout_index_to_line_x (layout, cursor_index, FALSE,
- &line, &x_pos);
-
- layout_iter = pango_layout_get_iter (layout);
- for (i = 0; i < line; i++)
- pango_layout_iter_next_line (layout_iter);
-
- pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);
-
- pango_layout_iter_free (layout_iter);
-
- /* try to go to the remembered x_pos if it exists *and* we are at
- * the beginning or at the end of the current line
- */
- if (text_tool->x_pos != -1 && (x_pos <= logical.x ||
- x_pos >= logical.width))
- x_pos = text_tool->x_pos;
-
- line += count;
-
- if (line < 0)
- {
- cursor = start;
- break;
- }
- else if (line >= pango_layout_get_line_count (layout))
- {
- cursor = end;
- break;
- }
-
- layout_iter = pango_layout_get_iter (layout);
- for (i = 0; i < line; i++)
- pango_layout_iter_next_line (layout_iter);
-
- layout_line = pango_layout_iter_get_line_readonly (layout_iter);
- pango_layout_iter_get_line_extents (layout_iter, NULL, &logical);
-
- pango_layout_iter_free (layout_iter);
-
- pango_layout_line_x_to_index (layout_line, x_pos,
- &cursor_index, &trailing);
-
- string = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-
- string[cursor_index] = '\0';
-
- gtk_text_buffer_get_iter_at_offset (buffer, &cursor,
- g_utf8_strlen (string, -1));
-
- g_free (string);
-
- while (trailing--)
- gtk_text_iter_forward_char (&cursor);
- }
- break;
-
- case GTK_MOVEMENT_PAGES: /* well... */
- case GTK_MOVEMENT_BUFFER_ENDS:
- if (count < 0)
- {
- gtk_text_buffer_get_start_iter (buffer, &cursor);
- }
- else if (count > 0)
- {
- gtk_text_buffer_get_end_iter (buffer, &cursor);
- }
- break;
-
- case GTK_MOVEMENT_PARAGRAPH_ENDS:
- if (count < 0)
- {
- gtk_text_iter_set_line_offset (&cursor, 0);
- }
- else if (count > 0)
- {
- if (! gtk_text_iter_ends_line (&cursor))
- gtk_text_iter_forward_to_line_end (&cursor);
- }
- break;
-
- case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
- if (count < 0)
- {
- gtk_text_iter_set_line_offset (&cursor, 0);
- }
- else if (count > 0)
- {
- if (! gtk_text_iter_ends_line (&cursor))
- gtk_text_iter_forward_to_line_end (&cursor);
- }
- break;
-
- default:
- return;
- }
-
- text_tool->x_pos = x_pos;
-
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
-
- gtk_text_buffer_select_range (buffer, &cursor, sel_start);
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
-}
-
-static void
-gimp_text_tool_insert_at_cursor (GimpTextTool *text_tool,
- const gchar *str)
-{
- gtk_text_buffer_insert_interactive_at_cursor (text_tool->text_buffer,
- str, -1, TRUE);
-}
-
-static gboolean
-is_whitespace (gunichar ch,
- gpointer user_data)
-{
- return (ch == ' ' || ch == '\t');
-}
-
-static gboolean
-is_not_whitespace (gunichar ch,
- gpointer user_data)
-{
- return ! is_whitespace (ch, user_data);
-}
-
-static gboolean
-find_whitepace_region (const GtkTextIter *center,
- GtkTextIter *start,
- GtkTextIter *end)
-{
- *start = *center;
- *end = *center;
-
- if (gtk_text_iter_backward_find_char (start, is_not_whitespace, NULL, NULL))
- gtk_text_iter_forward_char (start); /* we want the first whitespace... */
-
- if (is_whitespace (gtk_text_iter_get_char (end), NULL))
- gtk_text_iter_forward_find_char (end, is_not_whitespace, NULL, NULL);
-
- return ! gtk_text_iter_equal (start, end);
-}
-
-static void
-gimp_text_tool_delete_from_cursor (GimpTextTool *text_tool,
- GtkDeleteType type,
- gint count)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
- GtkTextIter cursor;
- GtkTextIter end;
-
- g_printerr ("%s: %s count = %d\n",
- G_STRFUNC,
- g_enum_get_value (g_type_class_ref (GTK_TYPE_DELETE_TYPE),
- type)->value_name,
- count);
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
- end = cursor;
-
- switch (type)
- {
- case GTK_DELETE_CHARS:
- if (gtk_text_buffer_get_has_selection (buffer))
- {
- gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
- return;
- }
- else
- {
- gtk_text_iter_forward_cursor_positions (&end, count);
- }
- break;
-
- case GTK_DELETE_WORD_ENDS:
- if (count < 0)
- {
- if (! gtk_text_iter_starts_word (&cursor))
- gtk_text_iter_backward_visible_word_starts (&cursor, 1);
- }
- else if (count > 0)
- {
- if (! gtk_text_iter_ends_word (&end) &&
- ! gtk_text_iter_forward_visible_word_ends (&end, 1))
- gtk_text_iter_forward_to_line_end (&end);
- }
- break;
-
- case GTK_DELETE_WORDS:
- if (! gtk_text_iter_starts_word (&cursor))
- gtk_text_iter_backward_visible_word_starts (&cursor, 1);
-
- if (! gtk_text_iter_ends_word (&end) &&
- ! gtk_text_iter_forward_visible_word_ends (&end, 1))
- gtk_text_iter_forward_to_line_end (&end);
- break;
-
- case GTK_DELETE_DISPLAY_LINES:
- break;
-
- case GTK_DELETE_DISPLAY_LINE_ENDS:
- break;
-
- case GTK_DELETE_PARAGRAPH_ENDS:
- if (count < 0)
- {
- gtk_text_iter_set_line_offset (&cursor, 0);
- }
- else if (count > 0)
- {
- if (! gtk_text_iter_ends_line (&end))
- gtk_text_iter_forward_to_line_end (&end);
- else
- gtk_text_iter_forward_cursor_positions (&end, 1);
- }
- break;
-
- case GTK_DELETE_PARAGRAPHS:
- break;
-
- case GTK_DELETE_WHITESPACE:
- find_whitepace_region (&cursor, &cursor, &end);
- break;
- }
-
- if (! gtk_text_iter_equal (&cursor, &end))
- {
- gtk_text_buffer_delete_interactive (buffer, &cursor, &end, TRUE);
- }
-}
-
-static void
-gimp_text_tool_backspace (GimpTextTool *text_tool)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
-
- if (gtk_text_buffer_get_has_selection (buffer))
- {
- gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
- }
- else
- {
- GtkTextIter cursor;
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
-
- gtk_text_buffer_backspace (buffer, &cursor, TRUE, TRUE);
- }
-}
-
-static void
-gimp_text_tool_toggle_overwrite (GimpTextTool *text_tool)
-{
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
-
- text_tool->overwrite_mode = ! text_tool->overwrite_mode;
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
-}
-
-static void
-gimp_text_tool_select_all (GimpTextTool *text_tool,
- gboolean select)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
-
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
-
- if (select)
- {
- GtkTextIter start, end;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
- gtk_text_buffer_select_range (buffer, &start, &end);
- }
- else
- {
- GtkTextIter cursor;
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
- gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &cursor);
- }
-
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+ gimp_text_tool_editor_halt (text_tool);
}
@@ -1883,28 +1305,6 @@ gimp_text_tool_connect (GimpTextTool *text_tool,
}
static void
-gimp_text_tool_options_notify (GimpTextOptions *options,
- GParamSpec *pspec,
- GimpTextTool *text_tool)
-{
- const gchar *param_name = g_param_spec_get_name (pspec);
-
- if (! strcmp (param_name, "use-editor"))
- {
- if (options->use_editor)
- {
- if (text_tool->text)
- gimp_text_tool_editor_dialog (text_tool);
- }
- else
- {
- if (text_tool->editor)
- gtk_widget_destroy (text_tool->editor);
- }
- }
-}
-
-static void
gimp_text_tool_layer_notify (GimpTextLayer *layer,
GParamSpec *pspec,
GimpTextTool *text_tool)
@@ -2231,103 +1631,6 @@ gimp_text_tool_create_layer (GimpTextTool *text_tool,
gimp_text_tool_set_drawable (text_tool, GIMP_DRAWABLE (layer), FALSE);
}
-static void
-gimp_text_tool_editor_dialog (GimpTextTool *text_tool)
-{
- GimpTool *tool = GIMP_TOOL (text_tool);
- GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
- GimpDialogFactory *dialog_factory;
- GtkWindow *parent = NULL;
-
- if (text_tool->editor)
- {
- gtk_window_present (GTK_WINDOW (text_tool->editor));
- return;
- }
-
- dialog_factory = gimp_dialog_factory_from_name ("toplevel");
-
- if (tool->display)
- {
- GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
-
- parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (shell)));
- }
-
- text_tool->editor = gimp_text_options_editor_new (parent, options,
- gimp_dialog_factory_get_menu_factory (dialog_factory),
- _("GIMP Text Editor"),
- text_tool->text_buffer);
-
- g_object_add_weak_pointer (G_OBJECT (text_tool->editor),
- (gpointer) &text_tool->editor);
-
- gimp_dialog_factory_add_foreign (dialog_factory,
- "gimp-text-tool-dialog",
- text_tool->editor);
-
- gtk_widget_show (text_tool->editor);
-}
-
-static void
-gimp_text_tool_editor (GimpTextTool *text_tool)
-{
- GimpTool *tool = GIMP_TOOL (text_tool);
- GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
- GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
-
- gtk_im_context_set_client_window (text_tool->im_context,
- gtk_widget_get_window (shell->canvas));
-
- gtk_im_context_focus_in (text_tool->im_context);
-
- if (text_tool->text)
- gtk_text_buffer_set_text (text_tool->text_buffer,
- text_tool->text->text, -1);
- else
- gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
-
- gimp_text_tool_update_layout (text_tool);
-
- if (options->use_editor)
- gimp_text_tool_editor_dialog (text_tool);
-}
-
-static gchar *
-gimp_text_tool_editor_get_text (GimpTextTool *text_tool)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
- GtkTextIter start, end;
- GtkTextIter selstart, selend;
- gchar *string;
- gchar *fb;
- gchar *lb;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
- gtk_text_buffer_get_selection_bounds (buffer, &selstart, &selend);
-
- fb = gtk_text_buffer_get_text (buffer, &start, &selstart, TRUE);
- lb = gtk_text_buffer_get_text (buffer, &selstart, &end, TRUE);
-
- if (text_tool->preedit_string)
- {
- if (fb == NULL)
- string = g_strconcat (text_tool->preedit_string, lb, NULL);
- else
- string = g_strconcat (fb, text_tool->preedit_string, lb, NULL);
- }
- else
- {
- string = g_strconcat (fb, lb, NULL);
- }
-
- g_free (fb);
- g_free (lb);
-
- return string;
-}
-
-
#define RESPONSE_NEW 1
static void
@@ -2354,7 +1657,7 @@ gimp_text_tool_confirm_response (GtkWidget *widget,
if (text_tool->proxy)
g_object_notify (G_OBJECT (text_tool->proxy), "text");
- gimp_text_tool_editor (text_tool);
+ gimp_text_tool_editor_start (text_tool);
break;
default:
@@ -2533,7 +1836,7 @@ gimp_text_tool_set_drawable (GimpTextTool *text_tool,
return FALSE;
}
-static void
+void
gimp_text_tool_update_proxy (GimpTextTool *text_tool)
{
if (text_tool->text)
@@ -2553,31 +1856,6 @@ gimp_text_tool_update_proxy (GimpTextTool *text_tool)
}
static void
-gimp_text_tool_enter_text (GimpTextTool *text_tool,
- const gchar *str)
-{
- GtkTextBuffer *buffer = text_tool->text_buffer;
- gboolean had_selection;
-
- had_selection = gtk_text_buffer_get_has_selection (buffer);
-
- gimp_text_tool_delete_selection (text_tool);
-
- if (! had_selection && text_tool->overwrite_mode && strcmp (str, "\n"))
- {
- GtkTextIter cursor;
-
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
- gtk_text_buffer_get_insert (buffer));
-
- if (! gtk_text_iter_ends_line (&cursor))
- gimp_text_tool_delete_from_cursor (text_tool, GTK_DELETE_CHARS, 1);
- }
-
- gtk_text_buffer_insert_at_cursor (buffer, str, -1);
-}
-
-static void
gimp_text_tool_text_buffer_changed (GtkTextBuffer *text_buffer,
GimpTextTool *text_tool)
{
@@ -2593,7 +1871,7 @@ gimp_text_tool_text_buffer_mark_set (GtkTextBuffer *text_buffer,
gimp_text_tool_update_layout (text_tool);
}
-static void
+void
gimp_text_tool_update_layout (GimpTextTool *text_tool)
{
GimpImage *image;
@@ -2654,43 +1932,6 @@ gimp_text_tool_xy_to_offset (GimpTextTool *text_tool,
}
-/* IM context utilities and callbacks */
-
-static void
-gimp_text_tool_reset_im_context (GimpTextTool *text_tool)
-{
- if (text_tool->needs_im_reset)
- {
- text_tool->needs_im_reset = FALSE;
- gtk_im_context_reset (text_tool->im_context);
- }
-}
-
-static void
-gimp_text_tool_commit_cb (GtkIMContext *context,
- const gchar *str,
- GimpTextTool *text_tool)
-{
- gimp_text_tool_enter_text (text_tool, str);
-}
-
-static void
-gimp_text_tool_preedit_changed_cb (GtkIMContext *context,
- GimpTextTool *text_tool)
-{
- if (text_tool->preedit_string)
- g_free (text_tool->preedit_string);
-
- gtk_im_context_get_preedit_string (context,
- &text_tool->preedit_string, NULL,
- &text_tool->preedit_cursor);
-
- text_tool->preedit_len = strlen (text_tool->preedit_string);
-
- gimp_text_tool_update_proxy (text_tool);
-}
-
-
/* public functions */
void
@@ -2748,7 +1989,7 @@ gimp_text_tool_set_layer (GimpTextTool *text_tool,
gimp_text_tool_frame_item (text_tool);
- gimp_text_tool_editor (text_tool);
+ gimp_text_tool_editor_start (text_tool);
}
}
}
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index 3780d7e..da56cbf 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -104,4 +104,9 @@ void gimp_text_tool_paste_clipboard (GimpTextTool *text_tool);
void gimp_text_tool_create_vectors (GimpTextTool *text_tool);
void gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool);
+/* only for the text editor */
+void gimp_text_tool_update_layout (GimpTextTool *text_tool);
+void gimp_text_tool_update_proxy (GimpTextTool *text_tool);
+
+
#endif /* __GIMP_TEXT_TOOL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]