From 9eaebcbcddcf7cc749839c90e44ad350f4e43d1a Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 25 May 2008 16:39:04 +0000 Subject: [PATCH] Tweaked cursor movement a bit git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@882 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/gui/value/text.cpp | 49 +++++++++++++++++++++++--------------- src/util/tagged_string.cpp | 9 ++++--- src/util/tagged_string.hpp | 5 ++++ 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index 816b26f3..f34069ab 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -868,22 +868,33 @@ void TextValueEditor::insert(const String& text, const String& action_name) { /// compare two cursor positions, determine how much the text matches before and after size_t match_cursor_position(size_t pos1, const String& text1, size_t pos2, const String& text2) { - size_t penalty = 0; // penalty for case mismatches - size_t before; - for (before = 0 ; before < min(pos1,pos2) ; ++before) { - Char c1 = text1.GetChar(pos1-before-1), c2 = text2.GetChar(pos2-before-1); - if (toLower(c1) != toLower(c2)) break; - else if (c1 != c2) ++penalty; + size_t score = 0; // total score + // Match part before cursor + size_t before1, before2; + for (before1 = before2 = 0 ; before1 < pos1 && before2 < pos2 ; ++before1, ++before2) { + Char c1 = text1.GetChar(pos1-before1-1), c2 = text2.GetChar(pos2-before2-1); + if (c1 == c2) score += 10000; + else if (toLower(c1) == toLower(c2)) score += 9999; + else if (isPunct(c1) && isPunct(c2)) score += 1; + else if (c1 == UNTAG_ATOM_KWPPH) {score += 1; --before2;} + else break; } - if (pos1 == before && pos2 == before) ++before; // bonus points for matching start of string - size_t after; - for (after = 0 ; after < min(text1.size() - pos1, text2.size() - pos2) ; ++after) { - Char c1 = text1.GetChar(pos1+after), c2 = text2.GetChar(pos2+after); - if (toLower(c1) != toLower(c2)) break; - else if (c1 != c2) ++penalty; + // bonus points for matching start of string + if (pos1 == before1 && pos2 == before2) score += 10000; + // Match part after cursor + size_t after1, after2; + for (after1 = after2 = 0 ; pos1 + after1 < text1.size() && pos2 + after2 < text2.size() ; ++after1, ++after2) { + Char c1 = text1.GetChar(pos1+after1), c2 = text2.GetChar(pos2+after2); + if (c1 == c2) score += 10; + else if (toLower(c1) == toLower(c2)) score += 9; + else if (isPunct(c1) && isPunct(c2)) score += 1; + else if (c2 == UNTAG_ATOM_KWPPH) {score += 1; --after1;} + else break; } - if (pos1+after == text1.size() && pos2+after == text2.size()) ++after; // bonus points for matching end of string - return 1000 * before + 2 * after - penalty; // matching 'before' is more important + // bonus points for matching end of string + if (pos1+after1 == text1.size() && pos2+after2 == text2.size()) score += 2; + // final score: matching 'before' is more important + return score; } void TextValueEditor::replaceSelection(const String& replacement, const String& name, bool allow_auto_replace, bool select_on_undo) { @@ -924,17 +935,17 @@ void TextValueEditor::replaceSelection(const String& replacement, const String& size_t best_cursor = expected_cursor; if (real_value.size() < expected_value.size() && expected_cursor < expected_value.size() - && expected_value.GetChar(expected_cursor) == _('\3') // \3 == - && real_value.GetChar(start) == _('\3') // \3 == + && expected_value.GetChar(expected_cursor) == UNTAG_SEP + && real_value.GetChar(start) == UNTAG_SEP && real_value.size() - end_min == start) { // exception for type-over separators best_cursor = start + 1; } else { - // try to find the best match + // try to find the best match to what text we expected to be around the cursor size_t best_match = 0; - for (size_t i = min(start, expected_cursor) ; i <= real_value.size() - end_min ; ++i) { + for (size_t i = min(start, expected_cursor) ; i <= max(real_value.size() - end_min, expected_cursor) ; ++i) { size_t match = match_cursor_position(expected_cursor, expected_value, i, real_value); - if (match > best_match) { + if (match > best_match || (match == best_match && abs((int)expected_cursor - (int)i) < abs((int)expected_cursor - (int)best_cursor))) { best_match = match; best_cursor = i; } diff --git a/src/util/tagged_string.cpp b/src/util/tagged_string.cpp index 4540f3a9..6daa010e 100644 --- a/src/util/tagged_string.cpp +++ b/src/util/tagged_string.cpp @@ -347,12 +347,15 @@ String untag_for_cursor(const String& str) { for (size_t i = 0 ; i < str.size() ; ) { Char c = str.GetChar(i); if (c == _('<')) { - if (is_substr(str, i, _("... becomes a single character. /** This string should only be used for cursor position calculations. */ String untag_for_cursor(const String& str);