SF.net SVN: geany: [1352] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Thu Mar 1 17:36:51 UTC 2007


Revision: 1352
          http://svn.sourceforge.net/geany/?rev=1352&view=rev
Author:   eht16
Date:     2007-03-01 09:36:51 -0800 (Thu, 01 Mar 2007)

Log Message:
-----------
Added sci_get_selection_mode(), sci_set_selection_mode(), sci_get_pos_at_line_sel_start(), sci_get_pos_at_line_sel_end().
Improved replacing in rectangle selections (closes #1665571).

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/document.c
    trunk/src/sciwrappers.c
    trunk/src/sciwrappers.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-03-01 15:54:12 UTC (rev 1351)
+++ trunk/ChangeLog	2007-03-01 17:36:51 UTC (rev 1352)
@@ -10,8 +10,13 @@
  * src/tools.c, src/utils.c:
    Applied patch from Jeff Pohlmeyer to improve the custom command
    execution code(thanks).
+ * src/sciwrappers.c, src/sciwrappers.h:
+   Added sci_get_selection_mode(), sci_set_selection_mode(),
+   sci_get_pos_at_line_sel_start(), sci_get_pos_at_line_sel_end().
+ * src/document.c:
+   Improved replacing in rectangle selections (closes #1665571).
+   
 
-
 2007-02-28  Nick Treleaven  <nick.treleaven at btinternet.com>
 
  * src/msgwindow.c, src/msgwindow.h, src/search.c:

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2007-03-01 15:54:12 UTC (rev 1351)
+++ trunk/src/document.c	2007-03-01 17:36:51 UTC (rev 1352)
@@ -77,7 +77,7 @@
 /* Returns -1 if no text found or the new range endpoint after replacing. */
 static gint
 document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text,
-	gint flags, gint start, gint end, gboolean escaped_chars);
+	gint flags, gint start, gint end, gboolean escaped_chars, gboolean scroll_to_match);
 
 static void document_undo_clear(gint idx);
 static void document_redo_add(gint idx, guint type, gpointer data);
@@ -1249,7 +1249,7 @@
 /* Returns -1 if no text found or the new range endpoint after replacing. */
 static gint
 document_replace_range(gint idx, const gchar *find_text, const gchar *replace_text,
-	gint flags, gint start, gint end, gboolean escaped_chars)
+	gint flags, gint start, gint end, gboolean escaped_chars, gboolean scroll_to_match)
 {
 	gint search_pos;
 	gint count = 0;
@@ -1264,11 +1264,12 @@
 	ttf.chrg.cpMin = start;
 	ttf.chrg.cpMax = end;
 	ttf.lpstrText = (gchar*)find_text;
-
+	
 	while (TRUE)
 	{
 		search_pos = sci_find_text(doc_list[idx].sci, flags, &ttf);
-		if (search_pos == -1) break;
+		if (search_pos == -1)
+			break;
 		find_len = ttf.chrgText.cpMax - ttf.chrgText.cpMin;
 
 		if (search_pos + find_len > end)
@@ -1291,9 +1292,10 @@
 	show_replace_summary(idx, count, find_text, replace_text, escaped_chars);
 
 	if (match_found)
-	{
-		// scroll last match in view.
-		sci_goto_pos(doc_list[idx].sci, ttf.chrg.cpMin, TRUE);
+	{	// scroll last match in view, will destroy the existing selection
+		if (scroll_to_match)
+			sci_goto_pos(doc_list[idx].sci, ttf.chrg.cpMin, TRUE);
+		
 		return end;
 	}
 	else
@@ -1304,32 +1306,96 @@
 void document_replace_sel(gint idx, const gchar *find_text, const gchar *replace_text, gint flags,
 						  gboolean escaped_chars)
 {
-	gint selection_end, selection_start;
+	gint selection_end, selection_start, selection_mode, selected_lines, last_line;
+	gint max_column = 0;
+	gboolean replaced = FALSE;
 
 	g_return_if_fail(find_text != NULL && replace_text != NULL);
 	if (idx == -1 || ! *find_text) return;
 
 	selection_start = sci_get_selection_start(doc_list[idx].sci);
 	selection_end = sci_get_selection_end(doc_list[idx].sci);
+	// do we have a selection?
 	if ((selection_end - selection_start) == 0)
 	{
 		utils_beep();
 		return;
 	}
 
-	selection_end = document_replace_range(idx, find_text, replace_text, flags,
-		selection_start, selection_end, escaped_chars);
-	if (selection_end == -1)
+	selection_mode = sci_get_selection_mode(doc_list[idx].sci);
+	selected_lines = sci_get_lines_selected(doc_list[idx].sci);
+	// handle rectangle, multi line selections (it doesn't matter on a single line)
+	if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1)
 	{
-		// no replacements
-		utils_beep();
+		gint first_line, line, line_start, line_end, tmp;
+		
+		sci_start_undo_action(doc_list[idx].sci);
+		
+		first_line = sci_get_line_from_position(doc_list[idx].sci, selection_start);
+		// Find the last line with chars selected (not EOL char)
+		last_line = sci_get_line_from_position(doc_list[idx].sci, selection_end - 1);
+		last_line = MAX(first_line, last_line);
+		for (line = first_line; line < (first_line + selected_lines); line++)
+		{
+			line_start = sci_get_pos_at_line_sel_start(doc_list[idx].sci, line);
+			line_end = sci_get_pos_at_line_sel_end(doc_list[idx].sci, line);
+			
+			// skip line if there is no selection
+			if (line_start != INVALID_POSITION)
+			{
+				// don't let document_replace_range() scroll to match to keep our selection
+				tmp = document_replace_range(idx, find_text, replace_text, flags,
+												line_start, line_end, escaped_chars, FALSE);
+				if (tmp != -1)
+				{
+					replaced = TRUE;				
+					// this gets the greatest column within the selection after replacing
+					max_column = MAX(max_column,
+						tmp - sci_get_position_from_line(doc_list[idx].sci, line));
+				}
+			}
+		}
+		sci_end_undo_action(doc_list[idx].sci);
 	}
 	else
 	{
-		// update the selection for the new endpoint
-		sci_set_selection_start(doc_list[idx].sci, selection_start);
-		sci_set_selection_end(doc_list[idx].sci, selection_end);
+		selection_end = document_replace_range(idx, find_text, replace_text, flags,
+											selection_start, selection_end, escaped_chars, TRUE);
+		if (selection_end != -1)
+			replaced = TRUE;
 	}
+	
+	if (replaced)
+	{	// update the selection for the new endpoint
+		
+		if (selection_mode == SC_SEL_RECTANGLE && selected_lines > 1)
+		{
+			// now we can scroll to the selection and destroy it because we rebuild it later
+			//sci_goto_pos(doc_list[idx].sci, selection_start, FALSE);
+			
+			// Note: the selection will be wrapped to last_line + 1 if max_column is greater than
+			// the highest column on the last line. The wrapped selection is completely different
+			// from the original one, so skip the selection at all
+			/// TODO is there a better way to handle the wrapped selection?
+			if ((sci_get_line_length(doc_list[idx].sci, last_line) - 1) >= max_column)
+			{
+				// for keeping and adjusting the selection in multi line rectangle selection we
+				// need the last line of the original selection and the greatest column number after
+				// replacing and set the selection end to the last line at the greatest column
+				sci_set_selection_start(doc_list[idx].sci, selection_start);
+				sci_set_selection_end(doc_list[idx].sci,
+					sci_get_position_from_line(doc_list[idx].sci, last_line) + max_column);
+				sci_set_selection_mode(doc_list[idx].sci, selection_mode);
+			}
+		}
+		else 
+		{
+			sci_set_selection_start(doc_list[idx].sci, selection_start);
+			sci_set_selection_end(doc_list[idx].sci, selection_end);
+		}
+	}	
+	else // no replacements
+		utils_beep();
 }
 
 
@@ -1342,7 +1408,8 @@
 	if (idx == -1 || ! *find_text) return FALSE;
 
 	len = sci_get_length(doc_list[idx].sci);
-	if (document_replace_range(idx, find_text, replace_text, flags, 0, len, escaped_chars) == -1)
+	if (document_replace_range(
+			idx, find_text, replace_text, flags, 0, len, escaped_chars, TRUE) == -1)
 	{
 		utils_beep();
 		return FALSE;

Modified: trunk/src/sciwrappers.c
===================================================================
--- trunk/src/sciwrappers.c	2007-03-01 15:54:12 UTC (rev 1351)
+++ trunk/src/sciwrappers.c	2007-03-01 17:36:51 UTC (rev 1352)
@@ -911,3 +911,24 @@
 {
 	SSM(sci, SCI_SETUSETABS, set, 0);
 }
+
+gint sci_get_pos_at_line_sel_start(ScintillaObject *sci, gint line)
+{
+	return SSM(sci, SCI_GETLINESELSTARTPOSITION, line, 0);
+}
+
+gint sci_get_pos_at_line_sel_end(ScintillaObject *sci, gint line)
+{
+	return SSM(sci, SCI_GETLINESELENDPOSITION, line, 0);
+}
+
+gint sci_get_selection_mode(ScintillaObject *sci)
+{
+	return SSM(sci, SCI_GETSELECTIONMODE, 0, 0);
+}
+
+void sci_set_selection_mode(ScintillaObject *sci, gint mode)
+{
+	SSM(sci, SCI_SETSELECTIONMODE, mode, 0);
+}
+

Modified: trunk/src/sciwrappers.h
===================================================================
--- trunk/src/sciwrappers.h	2007-03-01 15:54:12 UTC (rev 1351)
+++ trunk/src/sciwrappers.h	2007-03-01 17:36:51 UTC (rev 1352)
@@ -80,6 +80,12 @@
 gint				sci_get_selection_start		(ScintillaObject* sci);
 gint				sci_get_selection_end		(ScintillaObject* sci);
 void 				sci_replace_sel				(ScintillaObject* sci, gchar* text);
+gint				sci_get_selection_mode		(ScintillaObject* sci);
+void				sci_set_selection_mode		(ScintillaObject* sci, gint mode);
+gint				sci_get_pos_at_line_sel_start(ScintillaObject*sci, gint line);
+gint				sci_get_pos_at_line_sel_end	(ScintillaObject* sci, gint line);
+void 				sci_set_selection_start		(ScintillaObject* sci, gint position);
+void				sci_set_selection_end		(ScintillaObject* sci, gint position);
 
 gint				sci_get_length				(ScintillaObject* sci);
 void				sci_get_text				(ScintillaObject* sci,gint len,gchar* text);
@@ -87,15 +93,13 @@
 gint				sci_get_selected_text_length(ScintillaObject* sci);
 gchar *				sci_get_line				(ScintillaObject* sci, gint line_num);
 gint 				sci_get_line_length			(ScintillaObject* sci, gint line);
-gint				sci_get_line_count			( ScintillaObject* sci );
+gint				sci_get_line_count			(ScintillaObject* sci);
 void 				sci_get_xy_from_position	(ScintillaObject* sci,gint pos, gint* x, gint* y);
 gint				sci_get_position_from_xy	(ScintillaObject* sci, gint x, gint y, gboolean nearby);
 
 void 				sci_set_undo_collection		(ScintillaObject* sci, gboolean set);
 gboolean			sci_get_undo_collection		(ScintillaObject* sci);
 
-void 				sci_set_selection_start		(ScintillaObject* sci, gint position);
-void				sci_set_selection_end		(ScintillaObject* sci, gint position);
 gint				sci_get_line_end_position	(ScintillaObject* sci, gint line);
 
 void 				sci_toggle_fold				(ScintillaObject* sci, gint line);
@@ -147,6 +151,7 @@
 void				sci_target_start			(ScintillaObject * sci, gint start);
 void				sci_target_end				(ScintillaObject * sci, gint end);
 gint				sci_target_replace			(ScintillaObject * sci, const gchar *text, gboolean regex);
+
 void				sci_set_keywords			(ScintillaObject * sci, gint k, gchar *text);
 gint				sci_get_lexer				(ScintillaObject * sci);
 void				sci_set_readonly			(ScintillaObject * sci, gboolean readonly);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list