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@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.