diff --git a/src/apps/webpositive/URLInputGroup.cpp b/src/apps/webpositive/URLInputGroup.cpp index 7fec10caaf..e5d5c9ecb3 100644 --- a/src/apps/webpositive/URLInputGroup.cpp +++ b/src/apps/webpositive/URLInputGroup.cpp @@ -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); + } } diff --git a/src/apps/webpositive/autocompletion/AutoCompleter.cpp b/src/apps/webpositive/autocompletion/AutoCompleter.cpp index 98b659da40..2e5d45e164 100644 --- a/src/apps/webpositive/autocompletion/AutoCompleter.cpp +++ b/src/apps/webpositive/autocompletion/AutoCompleter.cpp @@ -175,10 +175,10 @@ BAutoCompleter::CancelChoice() void -BAutoCompleter::EditViewStateChanged() +BAutoCompleter::EditViewStateChanged(bool updateChoices) { if (fCompletionStyle) - fCompletionStyle->EditViewStateChanged(); + fCompletionStyle->EditViewStateChanged(updateChoices); } diff --git a/src/apps/webpositive/autocompletion/AutoCompleter.h b/src/apps/webpositive/autocompletion/AutoCompleter.h index 8b5cb7be37..16a94559b4 100644 --- a/src/apps/webpositive/autocompletion/AutoCompleter.h +++ b/src/apps/webpositive/autocompletion/AutoCompleter.h @@ -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); diff --git a/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.cpp b/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.cpp index 95ce32c7a0..5760852400 100644 --- a/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.cpp +++ b/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.cpp @@ -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); diff --git a/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.h b/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.h index cf01dbbad1..216a2d7f78 100644 --- a/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.h +++ b/src/apps/webpositive/autocompletion/AutoCompleterDefaultImpl.h @@ -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; }; diff --git a/src/apps/webpositive/autocompletion/TextViewCompleter.cpp b/src/apps/webpositive/autocompletion/TextViewCompleter.cpp index 9f0a90b065..3f83e884d8 100644 --- a/src/apps/webpositive/autocompletion/TextViewCompleter.cpp +++ b/src/apps/webpositive/autocompletion/TextViewCompleter.cpp @@ -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; } diff --git a/src/apps/webpositive/autocompletion/TextViewCompleter.h b/src/apps/webpositive/autocompletion/TextViewCompleter.h index a325603309..1a2955f6d7 100644 --- a/src/apps/webpositive/autocompletion/TextViewCompleter.h +++ b/src/apps/webpositive/autocompletion/TextViewCompleter.h @@ -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