Author: nick
Date: 2007-10-26 15:02:40 +0000 (Fri, 26 Oct 2007)
New Revision: 26200

Modified:
   mousepad/branches/nick_0_3/ChangeLog
   mousepad/branches/nick_0_3/mousepad/mousepad-view.c
   mousepad/branches/nick_0_3/mousepad/mousepad-view.h
   mousepad/branches/nick_0_3/mousepad/mousepad-window-ui.xml
   mousepad/branches/nick_0_3/mousepad/mousepad-window.c
Log:
        * 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.

Modified: mousepad/branches/nick_0_3/ChangeLog
===================================================================
--- mousepad/branches/nick_0_3/ChangeLog        2007-10-26 08:43:19 UTC (rev 
26199)
+++ mousepad/branches/nick_0_3/ChangeLog        2007-10-26 15:02:40 UTC (rev 
26200)
@@ -1,4 +1,16 @@
 2007-10-26     Nick Schermer <[EMAIL PROTECTED]>
+       * 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 <[EMAIL PROTECTED]>
        * MousepadHelp.in, mousepad/mousepad-{dialogs,window}.{c,h}:
          Add support for the help file.
        * Mousepad.spec.in: Add spec file.

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-view.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-view.c 2007-10-26 08:43:19 UTC 
(rev 26199)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-view.c 2007-10-26 15:02:40 UTC 
(rev 26200)
@@ -77,8 +77,17 @@
 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
 {
   HAS_SELECTION = 1 << 0, /* if there are marks in the selection list */
@@ -1232,8 +1241,8 @@
 
   _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,7 +1504,244 @@
 
 
 
+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)
 {
   GtkClipboard  *clipboard;

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-view.h
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-view.h 2007-10-26 08:43:19 UTC 
(rev 26199)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-view.h 2007-10-26 15:02:40 UTC 
(rev 26200)
@@ -35,6 +35,8 @@
 
 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);

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-window-ui.xml
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-window-ui.xml  2007-10-26 
08:43:19 UTC (rev 26199)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-window-ui.xml  2007-10-26 
15:02:40 UTC (rev 26200)
@@ -56,6 +56,8 @@
       <menuitem action="delete" />
       <separator />
       <menuitem action="select-all" />
+      <separator />
+      <menuitem action="transpose" />
     </menu>
 
     <menu action="search-menu">

Modified: mousepad/branches/nick_0_3/mousepad/mousepad-window.c
===================================================================
--- mousepad/branches/nick_0_3/mousepad/mousepad-window.c       2007-10-26 
08:43:19 UTC (rev 26199)
+++ mousepad/branches/nick_0_3/mousepad/mousepad-window.c       2007-10-26 
15:02:40 UTC (rev 26200)
@@ -232,6 +232,8 @@
                                                                        
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 @@
     { "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 @@
 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);
+}
 
-  mousepad_view_select_all (document->textview);
+
+
+static void
+mousepad_window_action_transpose (GtkAction      *action,
+                                  MousepadWindow *window)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active));
+
+  mousepad_view_transpose (window->active->textview);
 }
 
 
@@ -3298,20 +3310,18 @@
 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, &current_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, &current_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);
 }
 
 

_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to