* The type ahead mechanism did not work correctly in list view mode: instead

of taking the contents of the columns, it would always use the file name
  instead.
* That uncovered another bug, though: WidgetText::Text() tried to cast everything
  to StringAttributeText, but GenericAttributeText is actually used for most
  columns.
* Therefore, GenericAttributeText is now a subclass from StringAttributeText.
* Extended the type ahead to take other columns into account, and made it also
  find strings in the middle (like a filter) as a second choice.
* Whitespace cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28180 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-10-16 20:18:20 +00:00
parent 1e2bc11e99
commit 49ad25b392
7 changed files with 225 additions and 115 deletions
+73
View File
@@ -80,6 +80,8 @@ static const float kStubToStringSlotX = 5;
namespace BPrivate {
const float kExactMatchScore = INFINITY;
const rgb_color kBlack = {0, 0, 0, 255};
const rgb_color kWhite = {255, 255, 255, 255};
@@ -1583,6 +1585,77 @@ BootedInSafeMode()
}
float
ComputeTypeAheadScore(const char *text, const char *match, size_t matchLength,
bool wordMode)
{
float first = -1;
float second = -1;
float third = -1;
// highest score: exact match
float score = 0;
size_t pos = 0;
for (; pos < matchLength; pos++) {
if (text[pos] == '\0') {
score = 0;
break;
}
if (tolower(text[pos]) != tolower(match[pos]))
break;
score++;
}
if (pos == matchLength) {
// we don't need to look any further
return kExactMatchScore;
}
first = score;
// there was no exact match
// second best: all characters at word beginnings
if (wordMode) {
score = 0;
for (int32 j = 0, k = 0; match[j]; j++) {
while (text[k]
&& tolower(text[k]) != tolower(match[j])) {
k++;
}
if (text[k] == '\0') {
score = 0;
break;
}
bool wordStart = k == 0 || isspace(text[k - 1]);
if (wordStart)
score++;
if (j > 0) {
bool wordEnd = !text[k + 1] || isspace(text[k + 1]);
if (wordEnd)
score += 0.3;
if (match[j - 1] == text[k - 1])
score += 0.7;
}
score += 1.f / (k + 1);
k++;
}
second = score;
}
// acceptable last: exact match inside the string
score = 0;
const char* found = strstr(text + 1, match);
if (found != NULL)
score = 1.f / (found - text);
third = score;
return max_c(first, max_c(second, third));
}
void
_ThrowOnError(status_t error, const char *DEBUG_ONLY(file), int32 DEBUG_ONLY(line))
{