The mechanism with which the TextViewCompleter detected changes (attaching a

BMessageFilter to the BTextView to pre-process key down events) missed changes
to the BTextView via other means, for example by pasting, or simply when
SetText() is invoked on the BTextView. -> Introduced an alternative method
of making the TextViewCompleter aware of changes, by invoking new method
TextModified(). To bypass the old method, one has to call
SetModificationsReported(true). URLInput::URLTextView now uses the new method
in InsertText() and DeleteText(), which catches any and all changes to the
text. Since the BAutoCompleter framework also controls the editor view contents,
it needs to protect against re-entering some methods when the editor view
reports the changes (fIgnoreEditViewStateChanges). Since we want the
BAutoCompleter to always be aware of the current editor view contents, but not
necessarily also running the choice mechanism (i.e. when you enter
"www.google.com", you don't want the auto-completion kick back in when it is
programmatically changed to "http://www.google.com" later on), the
EditViewStateChange() method gets a boolean now "updateChoices". All
programmatic changes to the URL will then not trigger displaying the choice
pop-up, but the BAutoCompleter is always aware of the current editor view
contents.

All this fixes numerous issues and inconsistencies with entering text in the
URL text view.

git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@500 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
stippi 2010-05-18 16:59:34 +00:00 committed by Alexandre Deckner
parent eb44597cd0
commit 90a69c8e1d
7 changed files with 92 additions and 20 deletions

View File

@ -148,10 +148,14 @@ public:
virtual BSize MinSize();
virtual BSize MaxSize();
void SetUpdateAutoCompleterChoices(bool update);
protected:
virtual void InsertText(const char* inText, int32 inLength,
int32 inOffset,
const text_run_array* inRuns);
virtual void DeleteText(int32 fromOffset, int32 toOffset);
private:
void _AlignTextRect();
@ -159,6 +163,7 @@ private:
URLInputGroup* fURLInputGroup;
TextViewCompleter* fURLAutoCompleter;
BString fPreviousText;
bool fUpdateAutoCompleterChoices;
};
@ -168,10 +173,12 @@ URLInputGroup::URLTextView::URLTextView(URLInputGroup* parent)
fURLInputGroup(parent),
fURLAutoCompleter(new TextViewCompleter(this,
new BrowsingHistoryChoiceModel())),
fPreviousText("")
fPreviousText(""),
fUpdateAutoCompleterChoices(true)
{
MakeResizable(true);
SetStylable(true);
fURLAutoCompleter->SetModificationsReported(true);
}
@ -318,6 +325,13 @@ URLInputGroup::URLTextView::MaxSize()
}
void
URLInputGroup::URLTextView::SetUpdateAutoCompleterChoices(bool update)
{
fUpdateAutoCompleterChoices = update;
}
void
URLInputGroup::URLTextView::InsertText(const char* inText, int32 inLength,
int32 inOffset, const text_run_array* inRuns)
@ -360,6 +374,17 @@ URLInputGroup::URLTextView::InsertText(const char* inText, int32 inLength,
font.SetFace(B_REGULAR_FACE);
SetFontAndColor(baseUrlEnd, TextLength(), &font, B_FONT_ALL, &gray);
}
fURLAutoCompleter->TextModified(fUpdateAutoCompleterChoices);
}
void
URLInputGroup::URLTextView::DeleteText(int32 fromOffset, int32 toOffset)
{
BTextView::DeleteText(fromOffset, toOffset);
fURLAutoCompleter->TextModified(fUpdateAutoCompleterChoices);
}
@ -599,8 +624,11 @@ URLInputGroup::TextView() const
void
URLInputGroup::SetText(const char* text)
{
if (!text || !Text() || strcmp(Text(), text) != 0)
if (!text || !Text() || strcmp(Text(), text) != 0) {
fTextView->SetUpdateAutoCompleterChoices(false);
fTextView->SetText(text);
fTextView->SetUpdateAutoCompleterChoices(true);
}
}

View File

@ -175,10 +175,10 @@ BAutoCompleter::CancelChoice()
void
BAutoCompleter::EditViewStateChanged()
BAutoCompleter::EditViewStateChanged(bool updateChoices)
{
if (fCompletionStyle)
fCompletionStyle->EditViewStateChanged();
fCompletionStyle->EditViewStateChanged(updateChoices);
}

View File

@ -101,7 +101,7 @@ public:
virtual void ApplyChoice(bool hideChoices = true) = 0;
virtual void CancelChoice() = 0;
virtual void EditViewStateChanged() = 0;
virtual void EditViewStateChanged(bool updateChoices) = 0;
void SetEditView(EditView* view);
void SetPatternSelector(PatternSelector* selector);
@ -130,7 +130,8 @@ protected:
PatternSelector* patternSelector);
virtual ~BAutoCompleter();
void EditViewStateChanged();
void EditViewStateChanged(
bool updateChoices = true);
bool Select(int32 index);
bool SelectNext(bool wrap = false);

View File

@ -15,6 +15,7 @@
// #pragma mark - BDefaultPatternSelector
void
BDefaultPatternSelector::SelectPatternBounds(const BString& text,
int32 caretPos, int32* start, int32* length)
@ -38,7 +39,8 @@ BDefaultCompletionStyle::BDefaultCompletionStyle(
CompletionStyle(editView, choiceModel, choiceView, patternSelector),
fSelectedIndex(-1),
fPatternStartPos(0),
fPatternLength(0)
fPatternLength(0),
fIgnoreEditViewStateChanges(false)
{
}
@ -114,15 +116,19 @@ BDefaultCompletionStyle::ApplyChoice(bool hideChoices)
const BString& choiceStr = fChoiceModel->ChoiceAt(fSelectedIndex)->Text();
completedText.Insert(choiceStr, fPatternStartPos);
fIgnoreEditViewStateChanges = true;
fFullEnteredText = completedText;
fPatternLength = choiceStr.Length();
fEditView->SetEditViewState(completedText,
fPatternStartPos+choiceStr.Length());
fPatternStartPos + choiceStr.Length());
if (hideChoices) {
fChoiceView->HideChoices();
Select(-1);
}
fIgnoreEditViewStateChanges = false;
}
@ -132,25 +138,36 @@ BDefaultCompletionStyle::CancelChoice()
if (!fChoiceView || !fEditView)
return;
if (fChoiceView->ChoicesAreShown()) {
fEditView->SetEditViewState(fFullEnteredText,
fPatternStartPos+fPatternLength);
fIgnoreEditViewStateChanges = true;
fEditView->SetEditViewState(fFullEnteredText,
fPatternStartPos + fPatternLength);
fChoiceView->HideChoices();
Select(-1);
fIgnoreEditViewStateChanges = false;
}
}
void
BDefaultCompletionStyle::EditViewStateChanged()
BDefaultCompletionStyle::EditViewStateChanged(bool updateChoices)
{
if (!fChoiceModel || !fChoiceView || !fEditView)
if (fIgnoreEditViewStateChanges || !fChoiceModel || !fChoiceView
|| !fEditView) {
return;
}
BString text;
int32 caretPos;
fEditView->GetEditViewState(text, &caretPos);
if (fFullEnteredText == text)
return;
fFullEnteredText = text;
if (!updateChoices)
return;
fPatternSelector->SelectPatternBounds(text, caretPos, &fPatternStartPos,
&fPatternLength);
BString pattern(text.String() + fPatternStartPos, fPatternLength);

View File

@ -39,13 +39,14 @@ public:
virtual void ApplyChoice(bool hideChoices = true);
virtual void CancelChoice();
virtual void EditViewStateChanged();
virtual void EditViewStateChanged(bool updateChoices);
private:
BString fFullEnteredText;
int32 fSelectedIndex;
int32 fPatternStartPos;
int32 fPatternLength;
bool fIgnoreEditViewStateChanges;
};

View File

@ -63,13 +63,17 @@ TextViewCompleter::TextViewWrapper::GetAdjustmentFrame()
}
// #pragma mark -
TextViewCompleter::TextViewCompleter(BTextView* textView, ChoiceModel* model,
PatternSelector* patternSelector)
:
BAutoCompleter(new TextViewWrapper(textView), model,
new BDefaultChoiceView(), patternSelector),
BMessageFilter(B_KEY_DOWN),
fTextView(textView)
fTextView(textView),
fModificationsReported(false)
{
fTextView->AddFilter(this);
}
@ -81,6 +85,20 @@ TextViewCompleter::~TextViewCompleter()
}
void
TextViewCompleter::SetModificationsReported(bool reported)
{
fModificationsReported = reported;
}
void
TextViewCompleter::TextModified(bool updateChoices)
{
EditViewStateChanged(updateChoices);
}
filter_result
TextViewCompleter::Filter(BMessage* message, BHandler** target)
{
@ -120,11 +138,13 @@ TextViewCompleter::Filter(BMessage* message, BHandler** target)
return B_DISPATCH_MESSAGE;
}
default:
// dispatch message to textview manually...
Looper()->DispatchMessage(message, *target);
// ...and propagate the new state to the auto-completer:
EditViewStateChanged();
return B_SKIP_MESSAGE;
if (!fModificationsReported) {
// dispatch message to textview manually...
Looper()->DispatchMessage(message, *target);
// ...and propagate the new state to the auto-completer:
EditViewStateChanged();
return B_SKIP_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}

View File

@ -22,6 +22,9 @@ public:
PatternSelector* patternSelector = NULL);
virtual ~TextViewCompleter();
void SetModificationsReported(bool reported);
void TextModified(bool updateChoices);
private:
virtual filter_result Filter(BMessage* message, BHandler** target);
@ -36,8 +39,10 @@ private:
private:
BTextView* fTextView;
};
private:
BTextView* fTextView;
bool fModificationsReported;
};
#endif // TEXT_CONTROL_COMPLETER_H