[Xfce4-commits] <mousepad:master> * mousepad/mousepad-view.c: Implement transpose: - Selection on one line: Inverse selected text. - Multiple lines selected: Invert seleted lines. - Cursor is inside a word: Swap chars on each side of the cursor. - Cursor is outside a word: Swap word left and right of the cursor. - Cursor at the start of a line: Swap line with the line above. - Cursor at the end of a line: Swap line with the line below. Will add support for multi- and column-selections later. Thanks to Textmate for this great idea.
Nick Schermer
noreply at xfce.org
Sat May 5 21:30:57 CEST 2012
Updating branch refs/heads/master
to 03cd4c266c5d539c85dbe22f505d1d54c1b011b4 (commit)
from ec4cae752aa01e235b870df476b0c3008cb24f4d (commit)
commit 03cd4c266c5d539c85dbe22f505d1d54c1b011b4
Author: Nick Schermer <nick at xfce.org>
Date: Fri Oct 26 15:02:40 2007 +0000
* mousepad/mousepad-view.c: Implement transpose:
- Selection on one line: Inverse selected text.
- Multiple lines selected: Invert seleted lines.
- Cursor is inside a word: Swap chars on each side of the cursor.
- Cursor is outside a word: Swap word left and right of the cursor.
- Cursor at the start of a line: Swap line with the line above.
- Cursor at the end of a line: Swap line with the line below.
Will add support for multi- and column-selections later. Thanks to
Textmate for this great idea.
(Old svn revision: 26200)
ChangeLog | 12 ++
mousepad/mousepad-view.c | 250 ++++++++++++++++++++++++++++++++++++++-
mousepad/mousepad-view.h | 2 +
mousepad/mousepad-window-ui.xml | 2 +
mousepad/mousepad-window.c | 38 ++++--
5 files changed, 288 insertions(+), 16 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e64012a..2d87175 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,16 @@
2007-10-26 Nick Schermer <nick at xfce.org>
+ * mousepad/mousepad-view.c: Implement transpose:
+ - Selection on one line: Inverse selected text.
+ - Multiple lines selected: Invert seleted lines.
+ - Cursor is inside a word: Swap chars on each side of the cursor.
+ - Cursor is outside a word: Swap word left and right of the cursor.
+ - Cursor at the start of a line: Swap line with the line above.
+ - Cursor at the end of a line: Swap line with the line below.
+ Will add support for multi- and column-selections later. Thanks to
+ Textmate for this great idea.
+
+
+2007-10-26 Nick Schermer <nick at xfce.org>
* MousepadHelp.in, mousepad/mousepad-{dialogs,window}.{c,h}:
Add support for the help file.
* Mousepad.spec.in: Add spec file.
diff --git a/mousepad/mousepad-view.c b/mousepad/mousepad-view.c
index dec3071..2fed762 100644
--- a/mousepad/mousepad-view.c
+++ b/mousepad/mousepad-view.c
@@ -77,6 +77,15 @@ static gchar *mousepad_view_indent_string (GtkTextBuffer
static gint mousepad_view_calculate_layout_width (GtkWidget *widget,
gsize length,
gchar fill_char);
+static void mousepad_view_transpose_range (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter);
+static void mousepad_view_transpose_lines (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter);
+static void mousepad_view_transpose_words (GtkTextBuffer *buffer,
+ GtkTextIter *iter);
+
enum _MousepadViewFlags
@@ -1232,8 +1241,8 @@ mousepad_view_selection_clipboard (MousepadView *view,
_mousepad_return_if_fail (view->marks == NULL || g_slist_length (view->marks) % 2 == 0);
- /* create string with some size so we don't have to realloc a zillon times */
- string = g_string_sized_new (1024);
+ /* create new string */
+ string = g_string_new (NULL);
/* get the buffer */
buffer = mousepad_view_get_buffer (view);
@@ -1495,6 +1504,243 @@ mousepad_view_put_cursor_on_screen (MousepadView *view)
+static void
+mousepad_view_transpose_range (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter)
+{
+ gchar *string, *reversed;
+ gint offset;
+
+ /* store start iter line offset */
+ offset = gtk_text_iter_get_offset (start_iter);
+
+ /* get selected text */
+ string = gtk_text_buffer_get_slice (buffer, start_iter, end_iter, FALSE);
+
+ /* reverse the string */
+ reversed = g_utf8_strreverse (string, -1);
+
+ /* cleanup */
+ g_free (string);
+
+ /* delete the text between the iters */
+ gtk_text_buffer_delete (buffer, start_iter, end_iter);
+
+ /* insert the reversed string */
+ gtk_text_buffer_insert (buffer, end_iter, reversed, -1);
+
+ /* cleanup */
+ g_free (reversed);
+
+ /* restore start iter */
+ gtk_text_buffer_get_iter_at_offset (buffer, start_iter, offset);
+}
+
+
+
+static void
+mousepad_view_transpose_lines (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter)
+{
+ GString *string;
+ gint start_line, end_line;
+ gint i;
+ gchar *slice;
+
+ /* make sure the order is ok */
+ gtk_text_iter_order (start_iter, end_iter);
+
+ /* get the line numbers */
+ start_line = gtk_text_iter_get_line (start_iter);
+ end_line = gtk_text_iter_get_line (end_iter);
+
+ /* new string */
+ string = g_string_new (NULL);
+
+ /* add the lines in reversed order to the string */
+ for (i = start_line; i <= end_line; i++)
+ {
+ /* get start iter */
+ gtk_text_buffer_get_iter_at_line (buffer, start_iter, i);
+
+ /* set end iter */
+ *end_iter = *start_iter;
+
+ /* only prepend when the iters won't be equal */
+ if (!gtk_text_iter_ends_line (end_iter))
+ {
+ /* move the iter to the end of this line */
+ gtk_text_iter_forward_to_line_end (end_iter);
+
+ /* prepend line */
+ slice = gtk_text_buffer_get_slice (buffer, start_iter, end_iter, FALSE);
+ string = g_string_prepend (string, slice);
+ g_free (slice);
+ }
+
+ /* prepend new line */
+ if (i < end_line)
+ string = g_string_prepend_c (string, '\n');
+ }
+
+ /* get start iter again */
+ gtk_text_buffer_get_iter_at_line (buffer, start_iter, start_line);
+
+ /* delete selection */
+ gtk_text_buffer_delete (buffer, start_iter, end_iter);
+
+ /* insert reversed lines */
+ gtk_text_buffer_insert (buffer, end_iter, string->str, string->len);
+
+ /* cleanup */
+ g_string_free (string, TRUE);
+
+ /* restore start iter */
+ gtk_text_buffer_get_iter_at_line (buffer, start_iter, start_line);
+}
+
+
+
+static void
+mousepad_view_transpose_words (GtkTextBuffer *buffer,
+ GtkTextIter *iter)
+{
+ GtkTextIter start_one, end_one, end_two;
+ gchar *word_left, *word_right, *word_space;
+
+ /* move the iter to the start of first word */
+ gtk_text_iter_backward_word_start (iter);
+ start_one = *iter;
+ if (!gtk_text_iter_starts_word (iter))
+ return;
+
+ /* move to end of first word */
+ gtk_text_iter_forward_word_end (iter);
+ end_one = *iter;
+ if (!gtk_text_iter_ends_word (iter))
+ return;
+
+ /* move to end of second word */
+ gtk_text_iter_forward_word_end (iter);
+ end_two = *iter;
+ if (!gtk_text_iter_ends_word (iter))
+ return;
+
+ /* move to start of second word */
+ gtk_text_iter_backward_word_start (iter);
+ if (!gtk_text_iter_starts_word (iter))
+ return;
+
+ /* only do this on the same line */
+ if (gtk_text_iter_get_line (&start_one) != gtk_text_iter_get_line (&end_two))
+ return;
+
+ /* get the three parts */
+ word_left = gtk_text_buffer_get_slice (buffer, &start_one, &end_one, FALSE);
+ word_space = gtk_text_buffer_get_slice (buffer, &end_one, iter, FALSE);
+ word_right = gtk_text_buffer_get_slice (buffer, iter, &end_two, FALSE);
+
+ /* build string */
+ gtk_text_buffer_delete (buffer, &start_one, &end_two);
+ *iter = end_two;
+
+ /* insert right word */
+ gtk_text_buffer_insert (buffer, iter, word_right, -1);
+ g_free (word_right);
+
+ /* insert space */
+ gtk_text_buffer_insert (buffer, iter, word_space, -1);
+ g_free (word_space);
+
+ /* insert left word */
+ gtk_text_buffer_insert (buffer, iter, word_left, -1);
+ g_free (word_left);
+
+ /* return valid iter */
+ gtk_text_iter_backward_word_start (iter);
+
+ /* place cursor */
+ gtk_text_buffer_place_cursor (buffer, iter);
+}
+
+
+
+void
+mousepad_view_transpose (MousepadView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter sel_start, sel_end;
+
+ _mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
+
+ /* get buffer */
+ buffer = mousepad_view_get_buffer (view);
+
+ /* begin user action */
+ gtk_text_buffer_begin_user_action (buffer);
+
+ if (view->flags != 0)
+ {
+
+ }
+ else if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end))
+ {
+ /* if the selection is not on the same line, include the whole lines */
+ if (gtk_text_iter_get_line (&sel_start) == gtk_text_iter_get_line (&sel_end))
+ {
+ /* reverse selection */
+ mousepad_view_transpose_range (buffer, &sel_start, &sel_end);
+ }
+ else
+ {
+ /* reverse lines */
+ mousepad_view_transpose_lines (buffer, &sel_start, &sel_end);
+ }
+
+ /* restore selection */
+ gtk_text_buffer_select_range (buffer, &sel_start, &sel_end);
+ }
+ else
+ {
+ /* get cursor iter */
+ gtk_text_buffer_get_iter_at_mark (buffer, &sel_start, gtk_text_buffer_get_insert (buffer));
+
+ /* set end iter */
+ sel_end = sel_start;
+
+ if (gtk_text_iter_starts_line (&sel_start))
+ {
+ /* swap this line with the line above */
+ if (gtk_text_iter_backward_line (&sel_end))
+ mousepad_view_transpose_lines (buffer, &sel_start, &sel_end);
+ }
+ else if (gtk_text_iter_ends_line (&sel_start))
+ {
+ /* swap this line with the line below */
+ if (gtk_text_iter_forward_line (&sel_end))
+ mousepad_view_transpose_lines (buffer, &sel_start, &sel_end);
+ }
+ else if (gtk_text_iter_inside_word (&sel_start) && !gtk_text_iter_starts_word (&sel_start))
+ {
+ /* reverse the characters before and after the cursor */
+ if (gtk_text_iter_backward_char (&sel_start) && gtk_text_iter_forward_char (&sel_end))
+ mousepad_view_transpose_range (buffer, &sel_start, &sel_end);
+ }
+ else
+ {
+ /* swap the words left and right of the cursor */
+ mousepad_view_transpose_words (buffer, &sel_start);
+ }
+ }
+
+ /* end user action */
+ gtk_text_buffer_end_user_action (buffer);
+}
+
+
+
void
mousepad_view_clipboard_cut (MousepadView *view)
{
diff --git a/mousepad/mousepad-view.h b/mousepad/mousepad-view.h
index f29a671..8a1933f 100644
--- a/mousepad/mousepad-view.h
+++ b/mousepad/mousepad-view.h
@@ -35,6 +35,8 @@ GType mousepad_view_get_type (void) G_GNUC_CONST;
void mousepad_view_put_cursor_on_screen (MousepadView *view);
+void mousepad_view_transpose (MousepadView *view);
+
void mousepad_view_clipboard_cut (MousepadView *view);
void mousepad_view_clipboard_copy (MousepadView *view);
diff --git a/mousepad/mousepad-window-ui.xml b/mousepad/mousepad-window-ui.xml
index efbf935..6c5baaa 100644
--- a/mousepad/mousepad-window-ui.xml
+++ b/mousepad/mousepad-window-ui.xml
@@ -56,6 +56,8 @@
<menuitem action="delete" />
<separator />
<menuitem action="select-all" />
+ <separator />
+ <menuitem action="transpose" />
</menu>
<menu action="search-menu">
diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
index f46cc83..e68914c 100644
--- a/mousepad/mousepad-window.c
+++ b/mousepad/mousepad-window.c
@@ -232,6 +232,8 @@ static void mousepad_window_action_delete (GtkAction
MousepadWindow *window);
static void mousepad_window_action_select_all (GtkAction *action,
MousepadWindow *window);
+static void mousepad_window_action_transpose (GtkAction *action,
+ MousepadWindow *window);
static void mousepad_window_action_find (GtkAction *action,
MousepadWindow *window);
static void mousepad_window_action_find_next (GtkAction *action,
@@ -350,6 +352,7 @@ static const GtkActionEntry action_entries[] =
{ "paste-column", GTK_STOCK_PASTE, N_("Paste _Column"), "<control><shift>V", N_("Paste the clipboard text in a clumn"), G_CALLBACK (mousepad_window_action_paste_column), },
{ "delete", GTK_STOCK_DELETE, NULL, NULL, N_("Delete the selected text"), G_CALLBACK (mousepad_window_action_delete), },
{ "select-all", GTK_STOCK_SELECT_ALL, NULL, NULL, N_("Select the entire document"), G_CALLBACK (mousepad_window_action_select_all), },
+ { "transpose", NULL, N_("_Transpose"), NULL, N_("Reverse the order of something"), G_CALLBACK (mousepad_window_action_transpose), },
{ "search-menu", NULL, N_("_Search"), NULL, NULL, NULL, },
{ "find", GTK_STOCK_FIND, NULL, NULL, N_("Search for text"), G_CALLBACK (mousepad_window_action_find), },
@@ -2914,11 +2917,20 @@ static void
mousepad_window_action_select_all (GtkAction *action,
MousepadWindow *window)
{
- MousepadDocument *document = window->active;
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active));
- _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+ mousepad_view_select_all (window->active->textview);
+}
+
+
+
+static void
+mousepad_window_action_transpose (GtkAction *action,
+ MousepadWindow *window)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active));
- mousepad_view_select_all (document->textview);
+ mousepad_view_transpose (window->active->textview);
}
@@ -3298,20 +3310,18 @@ static void
mousepad_window_action_go_to_line (GtkAction *action,
MousepadWindow *window)
{
- MousepadDocument *document = window->active;
- gint current_line, last_line, line;
+ gint current_line, last_line, line;
- if (G_LIKELY (document))
- {
- /* get the current and last line number */
- mousepad_document_line_numbers (document, ¤t_line, &last_line);
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active));
- /* run the jump to dialog and wait for the response */
- line = mousepad_dialogs_go_to_line (GTK_WINDOW (window), current_line, last_line);
+ /* get the current and last line number */
+ mousepad_document_line_numbers (window->active, ¤t_line, &last_line);
- if (G_LIKELY (line > 0))
- mousepad_document_go_to_line (document, line);
- }
+ /* run the jump to dialog and wait for the response */
+ line = mousepad_dialogs_go_to_line (GTK_WINDOW (window), current_line, last_line);
+
+ if (G_LIKELY (line > 0))
+ mousepad_document_go_to_line (window->active, line);
}
More information about the Xfce4-commits
mailing list