* Renamed TextControlCompleter to TextViewCompleter, since it actually only
works with the BTextView. * Factored out the URL text handling into a new class URLInputGroup, which is used instead of a plain BTextControl, but currently works much the same way. It's a BGroupView though and allows easy addition of other controls and items into the URL text field. * Moved baseURL() method into it's own file, since it's used from multiple places now. git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@402 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
committed by
Alexandre Deckner
parent
406b936322
commit
312655fb6f
@@ -34,13 +34,14 @@
|
|||||||
#include "BrowserWindow.h"
|
#include "BrowserWindow.h"
|
||||||
|
|
||||||
#include "AuthenticationPanel.h"
|
#include "AuthenticationPanel.h"
|
||||||
|
#include "BaseURL.h"
|
||||||
#include "BrowserApp.h"
|
#include "BrowserApp.h"
|
||||||
#include "BrowsingHistory.h"
|
#include "BrowsingHistory.h"
|
||||||
#include "IconButton.h"
|
#include "IconButton.h"
|
||||||
#include "NavMenu.h"
|
#include "NavMenu.h"
|
||||||
#include "SettingsKeys.h"
|
#include "SettingsKeys.h"
|
||||||
#include "SettingsMessage.h"
|
#include "SettingsMessage.h"
|
||||||
#include "TextControlCompleter.h"
|
#include "URLInputGroup.h"
|
||||||
#include "WebPage.h"
|
#include "WebPage.h"
|
||||||
#include "WebTabView.h"
|
#include "WebTabView.h"
|
||||||
#include "WebView.h"
|
#include "WebView.h"
|
||||||
@@ -107,112 +108,6 @@ layoutItemFor(BView* view)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class URLChoice : public BAutoCompleter::Choice {
|
|
||||||
public:
|
|
||||||
URLChoice(const BString& choiceText, const BString& displayText,
|
|
||||||
int32 matchPos, int32 matchLen, int32 priority)
|
|
||||||
:
|
|
||||||
BAutoCompleter::Choice(choiceText, displayText, matchPos, matchLen),
|
|
||||||
fPriority(priority)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const URLChoice& other) const
|
|
||||||
{
|
|
||||||
if (fPriority > other.fPriority)
|
|
||||||
return true;
|
|
||||||
return DisplayText() < other.DisplayText();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const URLChoice& other) const
|
|
||||||
{
|
|
||||||
return fPriority == other.fPriority
|
|
||||||
&& DisplayText() < other.DisplayText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int32 fPriority;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static BString
|
|
||||||
baseURL(const BString string)
|
|
||||||
{
|
|
||||||
int32 baseURLStart = string.FindFirst("://") + 3;
|
|
||||||
int32 baseURLEnd = string.FindFirst("/", baseURLStart + 1);
|
|
||||||
BString result;
|
|
||||||
result.SetTo(string.String() + baseURLStart, baseURLEnd - baseURLStart);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class BrowsingHistoryChoiceModel : public BAutoCompleter::ChoiceModel {
|
|
||||||
virtual void FetchChoicesFor(const BString& pattern)
|
|
||||||
{
|
|
||||||
int32 count = CountChoices();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
delete reinterpret_cast<BAutoCompleter::Choice*>(
|
|
||||||
fChoices.ItemAtFast(i));
|
|
||||||
}
|
|
||||||
fChoices.MakeEmpty();
|
|
||||||
|
|
||||||
// Search through BrowsingHistory for any matches.
|
|
||||||
BrowsingHistory* history = BrowsingHistory::DefaultInstance();
|
|
||||||
if (!history->Lock())
|
|
||||||
return;
|
|
||||||
|
|
||||||
BString lastBaseURL;
|
|
||||||
int32 priority = INT_MAX;
|
|
||||||
|
|
||||||
count = history->CountItems();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
BrowsingHistoryItem item = history->HistoryItemAt(i);
|
|
||||||
const BString& choiceText = item.URL();
|
|
||||||
int32 matchPos = choiceText.IFindFirst(pattern);
|
|
||||||
if (matchPos < 0)
|
|
||||||
continue;
|
|
||||||
if (lastBaseURL.Length() > 0
|
|
||||||
&& choiceText.FindFirst(lastBaseURL) >= 0) {
|
|
||||||
priority--;
|
|
||||||
} else
|
|
||||||
priority = INT_MAX;
|
|
||||||
lastBaseURL = baseURL(choiceText);
|
|
||||||
fChoices.AddItem(new URLChoice(choiceText,
|
|
||||||
choiceText, matchPos, pattern.Length(), priority));
|
|
||||||
}
|
|
||||||
|
|
||||||
history->Unlock();
|
|
||||||
|
|
||||||
fChoices.SortItems(_CompareChoices);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountChoices() const
|
|
||||||
{
|
|
||||||
return fChoices.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const BAutoCompleter::Choice* ChoiceAt(int32 index) const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<BAutoCompleter::Choice*>(
|
|
||||||
fChoices.ItemAt(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _CompareChoices(const void* a, const void* b)
|
|
||||||
{
|
|
||||||
const URLChoice* aChoice = *reinterpret_cast<const URLChoice* const *>(a);
|
|
||||||
const URLChoice* bChoice = *reinterpret_cast<const URLChoice* const *>(b);
|
|
||||||
if (*aChoice < *bChoice)
|
|
||||||
return -1;
|
|
||||||
else if (*aChoice == *bChoice)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BList fChoices;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class BookmarkMenu : public BNavMenu {
|
class BookmarkMenu : public BNavMenu {
|
||||||
public:
|
public:
|
||||||
BookmarkMenu(const char* title, BHandler* target, const entry_ref* navDir)
|
BookmarkMenu(const char* title, BHandler* target, const entry_ref* navDir)
|
||||||
@@ -349,8 +244,7 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
|
|||||||
fStopButton->TrimIcon();
|
fStopButton->TrimIcon();
|
||||||
|
|
||||||
// URL
|
// URL
|
||||||
fURLTextControl = new BTextControl("url", "", "", NULL);
|
fURLInputGroup = new URLInputGroup();
|
||||||
fURLTextControl->SetDivider(50.0);
|
|
||||||
|
|
||||||
// Go
|
// Go
|
||||||
fGoButton = new BButton("", "Go", new BMessage(GOTO_URL));
|
fGoButton = new BButton("", "Go", new BMessage(GOTO_URL));
|
||||||
@@ -396,7 +290,7 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
|
|||||||
.Add(fBackButton, 0, 0)
|
.Add(fBackButton, 0, 0)
|
||||||
.Add(fForwardButton, 1, 0)
|
.Add(fForwardButton, 1, 0)
|
||||||
.Add(fStopButton, 2, 0)
|
.Add(fStopButton, 2, 0)
|
||||||
.Add(fURLTextControl, 3, 0)
|
.Add(fURLInputGroup, 3, 0)
|
||||||
.Add(fGoButton, 4, 0)
|
.Add(fGoButton, 4, 0)
|
||||||
.SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing)
|
.SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing)
|
||||||
)
|
)
|
||||||
@@ -423,10 +317,7 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
|
|||||||
.Add(statusGroup)
|
.Add(statusGroup)
|
||||||
);
|
);
|
||||||
|
|
||||||
fURLTextControl->MakeFocus(true);
|
fURLInputGroup->MakeFocus(true);
|
||||||
|
|
||||||
fURLAutoCompleter = new TextControlCompleter(fURLTextControl,
|
|
||||||
new BrowsingHistoryChoiceModel());
|
|
||||||
|
|
||||||
fMenuGroup = layoutItemFor(mainMenu);
|
fMenuGroup = layoutItemFor(mainMenu);
|
||||||
fTabGroup = layoutItemFor(fTabManager->TabGroup());
|
fTabGroup = layoutItemFor(fTabManager->TabGroup());
|
||||||
@@ -471,7 +362,6 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
|
|||||||
BrowserWindow::~BrowserWindow()
|
BrowserWindow::~BrowserWindow()
|
||||||
{
|
{
|
||||||
fAppSettings->RemoveListener(BMessenger(this));
|
fAppSettings->RemoveListener(BMessenger(this));
|
||||||
delete fURLAutoCompleter;
|
|
||||||
delete fTabManager;
|
delete fTabManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +374,7 @@ BrowserWindow::DispatchMessage(BMessage* message, BHandler* target)
|
|||||||
if ((message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN)
|
if ((message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN)
|
||||||
&& message->FindString("bytes", &bytes) == B_OK
|
&& message->FindString("bytes", &bytes) == B_OK
|
||||||
&& message->FindInt32("modifiers", &modifiers) == B_OK) {
|
&& message->FindInt32("modifiers", &modifiers) == B_OK) {
|
||||||
if (fURLTextControl && target == fURLTextControl->TextView()) {
|
if (target == fURLInputGroup->TextView()) {
|
||||||
// Handle B_RETURN in the URL text control. This is the easiest
|
// Handle B_RETURN in the URL text control. This is the easiest
|
||||||
// way to react *only* when the user presses the return key in the
|
// way to react *only* when the user presses the return key in the
|
||||||
// address bar, as opposed to trying to load whatever is in there when
|
// address bar, as opposed to trying to load whatever is in there when
|
||||||
@@ -512,12 +402,10 @@ BrowserWindow::MessageReceived(BMessage* message)
|
|||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case OPEN_LOCATION:
|
case OPEN_LOCATION:
|
||||||
if (fURLTextControl) {
|
if (fURLInputGroup->TextView()->IsFocus())
|
||||||
if (fURLTextControl->TextView()->IsFocus())
|
fURLInputGroup->TextView()->SelectAll();
|
||||||
fURLTextControl->TextView()->SelectAll();
|
else
|
||||||
else
|
fURLInputGroup->MakeFocus(true);
|
||||||
fURLTextControl->MakeFocus(true);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case RELOAD:
|
case RELOAD:
|
||||||
CurrentWebView()->Reload();
|
CurrentWebView()->Reload();
|
||||||
@@ -526,7 +414,7 @@ BrowserWindow::MessageReceived(BMessage* message)
|
|||||||
{
|
{
|
||||||
BString url;
|
BString url;
|
||||||
if (message->FindString("url", &url) != B_OK)
|
if (message->FindString("url", &url) != B_OK)
|
||||||
url = fURLTextControl->Text();
|
url = fURLInputGroup->Text();
|
||||||
fTabManager->SetTabIcon(CurrentWebView(), NULL);
|
fTabManager->SetTabIcon(CurrentWebView(), NULL);
|
||||||
CurrentWebView()->LoadURL(url.String());
|
CurrentWebView()->LoadURL(url.String());
|
||||||
break;
|
break;
|
||||||
@@ -889,10 +777,8 @@ BrowserWindow::CreateNewTab(const BString& url, bool select, BWebView* webView)
|
|||||||
fTabManager->SelectTab(fTabManager->CountTabs() - 1);
|
fTabManager->SelectTab(fTabManager->CountTabs() - 1);
|
||||||
SetCurrentWebView(webView);
|
SetCurrentWebView(webView);
|
||||||
webView->WebPage()->ResendNotifications();
|
webView->WebPage()->ResendNotifications();
|
||||||
if (fURLTextControl) {
|
fURLInputGroup->SetText(url.String());
|
||||||
fURLTextControl->SetText(url.String());
|
fURLInputGroup->MakeFocus(true);
|
||||||
fURLTextControl->MakeFocus(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_UpdateTabGroupVisibility();
|
_UpdateTabGroupVisibility();
|
||||||
@@ -967,8 +853,7 @@ BrowserWindow::LoadCommitted(const BString& url, BWebView* view)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// This hook is invoked when the load is commited.
|
// This hook is invoked when the load is commited.
|
||||||
if (fURLTextControl)
|
fURLInputGroup->SetText(url.String());
|
||||||
fURLTextControl->SetText(url.String());
|
|
||||||
|
|
||||||
BString status("Loading: ");
|
BString status("Loading: ");
|
||||||
status << url;
|
status << url;
|
||||||
@@ -1170,7 +1055,7 @@ BrowserWindow::AuthenticationChallenge(BString message, BString& inOutUser,
|
|||||||
if (view != CurrentWebView()) {
|
if (view != CurrentWebView()) {
|
||||||
int32 tabIndex = fTabManager->TabForView(view);
|
int32 tabIndex = fTabManager->TabForView(view);
|
||||||
if (tabIndex < 0) {
|
if (tabIndex < 0) {
|
||||||
// page seems to be gone already?
|
// Page seems to be gone already?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fTabManager->SelectTab(tabIndex);
|
fTabManager->SelectTab(tabIndex);
|
||||||
@@ -1245,7 +1130,7 @@ BrowserWindow::_TabChanged(int32 index)
|
|||||||
else
|
else
|
||||||
webView->MakeFocus(true);
|
webView->MakeFocus(true);
|
||||||
|
|
||||||
fURLTextControl->SetText(webView->MainFrameURL());
|
fURLInputGroup->SetText(webView->MainFrameURL());
|
||||||
// Trigger update of the interface to the new page, by requesting
|
// Trigger update of the interface to the new page, by requesting
|
||||||
// to resend all notifications.
|
// to resend all notifications.
|
||||||
webView->WebPage()->ResendNotifications();
|
webView->WebPage()->ResendNotifications();
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class BWebView;
|
|||||||
class IconButton;
|
class IconButton;
|
||||||
class SettingsMessage;
|
class SettingsMessage;
|
||||||
class TabManager;
|
class TabManager;
|
||||||
class TextControlCompleter;
|
class URLInputGroup;
|
||||||
|
|
||||||
enum ToolbarPolicy {
|
enum ToolbarPolicy {
|
||||||
HaveToolbar,
|
HaveToolbar,
|
||||||
@@ -150,8 +150,7 @@ private:
|
|||||||
IconButton* fForwardButton;
|
IconButton* fForwardButton;
|
||||||
IconButton* fStopButton;
|
IconButton* fStopButton;
|
||||||
BButton* fGoButton;
|
BButton* fGoButton;
|
||||||
BTextControl* fURLTextControl;
|
URLInputGroup* fURLInputGroup;
|
||||||
TextControlCompleter* fURLAutoCompleter;
|
|
||||||
BStringView* fStatusText;
|
BStringView* fStatusText;
|
||||||
BStatusBar* fLoadingProgressBar;
|
BStatusBar* fLoadingProgressBar;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,384 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Stephan Aßmus <[email protected]>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "URLInputGroup.h"
|
||||||
|
|
||||||
|
#include <ControlLook.h>
|
||||||
|
#include <GroupLayout.h>
|
||||||
|
#include <GroupLayoutBuilder.h>
|
||||||
|
#include <LayoutUtils.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "BaseURL.h"
|
||||||
|
#include "BrowsingHistory.h"
|
||||||
|
#include "IconButton.h"
|
||||||
|
#include "TextViewCompleter.h"
|
||||||
|
|
||||||
|
|
||||||
|
class URLChoice : public BAutoCompleter::Choice {
|
||||||
|
public:
|
||||||
|
URLChoice(const BString& choiceText, const BString& displayText,
|
||||||
|
int32 matchPos, int32 matchLen, int32 priority)
|
||||||
|
:
|
||||||
|
BAutoCompleter::Choice(choiceText, displayText, matchPos, matchLen),
|
||||||
|
fPriority(priority)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const URLChoice& other) const
|
||||||
|
{
|
||||||
|
if (fPriority > other.fPriority)
|
||||||
|
return true;
|
||||||
|
return DisplayText() < other.DisplayText();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const URLChoice& other) const
|
||||||
|
{
|
||||||
|
return fPriority == other.fPriority
|
||||||
|
&& DisplayText() < other.DisplayText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fPriority;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BrowsingHistoryChoiceModel : public BAutoCompleter::ChoiceModel {
|
||||||
|
virtual void FetchChoicesFor(const BString& pattern)
|
||||||
|
{
|
||||||
|
int32 count = CountChoices();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
delete reinterpret_cast<BAutoCompleter::Choice*>(
|
||||||
|
fChoices.ItemAtFast(i));
|
||||||
|
}
|
||||||
|
fChoices.MakeEmpty();
|
||||||
|
|
||||||
|
// Search through BrowsingHistory for any matches.
|
||||||
|
BrowsingHistory* history = BrowsingHistory::DefaultInstance();
|
||||||
|
if (!history->Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BString lastBaseURL;
|
||||||
|
int32 priority = INT_MAX;
|
||||||
|
|
||||||
|
count = history->CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
BrowsingHistoryItem item = history->HistoryItemAt(i);
|
||||||
|
const BString& choiceText = item.URL();
|
||||||
|
int32 matchPos = choiceText.IFindFirst(pattern);
|
||||||
|
if (matchPos < 0)
|
||||||
|
continue;
|
||||||
|
if (lastBaseURL.Length() > 0
|
||||||
|
&& choiceText.FindFirst(lastBaseURL) >= 0) {
|
||||||
|
priority--;
|
||||||
|
} else
|
||||||
|
priority = INT_MAX;
|
||||||
|
lastBaseURL = baseURL(choiceText);
|
||||||
|
fChoices.AddItem(new URLChoice(choiceText,
|
||||||
|
choiceText, matchPos, pattern.Length(), priority));
|
||||||
|
}
|
||||||
|
|
||||||
|
history->Unlock();
|
||||||
|
|
||||||
|
fChoices.SortItems(_CompareChoices);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountChoices() const
|
||||||
|
{
|
||||||
|
return fChoices.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const BAutoCompleter::Choice* ChoiceAt(int32 index) const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<BAutoCompleter::Choice*>(
|
||||||
|
fChoices.ItemAt(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _CompareChoices(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
const URLChoice* aChoice
|
||||||
|
= *reinterpret_cast<const URLChoice* const *>(a);
|
||||||
|
const URLChoice* bChoice
|
||||||
|
= *reinterpret_cast<const URLChoice* const *>(b);
|
||||||
|
if (*aChoice < *bChoice)
|
||||||
|
return -1;
|
||||||
|
else if (*aChoice == *bChoice)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BList fChoices;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - URLTextView
|
||||||
|
|
||||||
|
|
||||||
|
static const float kHorizontalTextRectInset = 3.0;
|
||||||
|
|
||||||
|
|
||||||
|
class URLInputGroup::URLTextView : public BTextView {
|
||||||
|
public:
|
||||||
|
URLTextView(URLInputGroup* parent);
|
||||||
|
virtual ~URLTextView();
|
||||||
|
|
||||||
|
virtual void FrameResized(float width, float height);
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||||
|
virtual void MakeFocus(bool focused = true);
|
||||||
|
|
||||||
|
virtual BSize MinSize();
|
||||||
|
virtual BSize MaxSize();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void InsertText(const char* inText, int32 inLength,
|
||||||
|
int32 inOffset,
|
||||||
|
const text_run_array* inRuns);
|
||||||
|
private:
|
||||||
|
void _AlignTextRect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
URLInputGroup* fURLInputGroup;
|
||||||
|
TextViewCompleter* fURLAutoCompleter;
|
||||||
|
BString fPreviousText;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
URLInputGroup::URLTextView::URLTextView(URLInputGroup* parent)
|
||||||
|
:
|
||||||
|
BTextView("url"),
|
||||||
|
fURLInputGroup(parent),
|
||||||
|
fURLAutoCompleter(new TextViewCompleter(this,
|
||||||
|
new BrowsingHistoryChoiceModel())),
|
||||||
|
fPreviousText("")
|
||||||
|
{
|
||||||
|
MakeResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
URLInputGroup::URLTextView::~URLTextView()
|
||||||
|
{
|
||||||
|
delete fURLAutoCompleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::FrameResized(float width, float height)
|
||||||
|
{
|
||||||
|
BTextView::FrameResized(width, height);
|
||||||
|
_AlignTextRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
if (!IsFocus()) {
|
||||||
|
MakeFocus(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only pass through to base class if we already have focus.
|
||||||
|
BTextView::MouseDown(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::KeyDown(const char* bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
switch (bytes[0]) {
|
||||||
|
case B_TAB:
|
||||||
|
BView::KeyDown(bytes, numBytes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_ESCAPE:
|
||||||
|
// Revert to text as it was when we received keyboard focus.
|
||||||
|
SetText(fPreviousText.String());
|
||||||
|
SelectAll();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BTextView::KeyDown(bytes, numBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::MakeFocus(bool focus)
|
||||||
|
{
|
||||||
|
if (focus == IsFocus())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BTextView::MakeFocus(focus);
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
fPreviousText = Text();
|
||||||
|
SelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
fURLInputGroup->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
URLInputGroup::URLTextView::MinSize()
|
||||||
|
{
|
||||||
|
BSize min;
|
||||||
|
min.height = ceilf(LineHeight(0) + kHorizontalTextRectInset);
|
||||||
|
// we always add at least one pixel vertical inset top/bottom for
|
||||||
|
// the text rect.
|
||||||
|
min.width = min.height * 3;
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitMinSize(), min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
URLInputGroup::URLTextView::MaxSize()
|
||||||
|
{
|
||||||
|
BSize max(MinSize());
|
||||||
|
max.width = B_SIZE_UNLIMITED;
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::InsertText(const char* inText, int32 inLength,
|
||||||
|
int32 inOffset, const text_run_array* inRuns)
|
||||||
|
{
|
||||||
|
char* buffer = NULL;
|
||||||
|
|
||||||
|
if (strpbrk(inText, "\r\n") && inLength <= 1024) {
|
||||||
|
buffer = (char*)malloc(inLength);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
strcpy(buffer, inText);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < inLength; i++) {
|
||||||
|
if (buffer[i] == '\r' || buffer[i] == '\n')
|
||||||
|
buffer[i] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BTextView::InsertText(buffer ? buffer : inText, inLength, inOffset,
|
||||||
|
inRuns);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::URLTextView::_AlignTextRect()
|
||||||
|
{
|
||||||
|
// Layout the text rect to be in the middle, normally this means there
|
||||||
|
// is one pixel spacing on each side.
|
||||||
|
BRect textRect(Bounds());
|
||||||
|
textRect.left = 0.0;
|
||||||
|
float vInset = max_c(1,
|
||||||
|
floorf((textRect.Height() - LineHeight(0)) / 2.0 + 0.5));
|
||||||
|
float hInset = kHorizontalTextRectInset;
|
||||||
|
|
||||||
|
if (be_control_look)
|
||||||
|
hInset = be_control_look->DefaultLabelSpacing();
|
||||||
|
|
||||||
|
textRect.InsetBy(hInset, vInset);
|
||||||
|
SetTextRect(textRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - URLInputGroup
|
||||||
|
|
||||||
|
|
||||||
|
URLInputGroup::URLInputGroup()
|
||||||
|
:
|
||||||
|
BGroupView(B_HORIZONTAL),
|
||||||
|
fWindowActive(false)
|
||||||
|
{
|
||||||
|
GroupLayout()->SetInsets(2, 2, 2, 2);
|
||||||
|
|
||||||
|
fTextView = new URLTextView(this);
|
||||||
|
AddChild(fTextView);
|
||||||
|
|
||||||
|
SetFlags(Flags() | B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE);
|
||||||
|
SetLowColor(ViewColor());
|
||||||
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
|
|
||||||
|
SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
|
||||||
|
B_ALIGN_VERTICAL_CENTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
URLInputGroup::~URLInputGroup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BGroupView::AttachedToWindow();
|
||||||
|
fWindowActive = Window()->IsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::WindowActivated(bool active)
|
||||||
|
{
|
||||||
|
BGroupView::WindowActivated(active);
|
||||||
|
if (fWindowActive != active) {
|
||||||
|
fWindowActive = active;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
rgb_color base(LowColor());
|
||||||
|
uint32 flags = 0;
|
||||||
|
if (fWindowActive && fTextView->IsFocus())
|
||||||
|
flags |= BControlLook::B_FOCUSED;
|
||||||
|
be_control_look->DrawTextControlBorder(this, bounds, updateRect, base,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::MakeFocus(bool focus)
|
||||||
|
{
|
||||||
|
// Forward this to the text view, we never accept focus ourselves.
|
||||||
|
fTextView->MakeFocus(focus);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextView*
|
||||||
|
URLInputGroup::TextView() const
|
||||||
|
{
|
||||||
|
return fTextView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLInputGroup::SetText(const char* text)
|
||||||
|
{
|
||||||
|
fTextView->SetText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
URLInputGroup::Text() const
|
||||||
|
{
|
||||||
|
return fTextView->Text();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef URL_INPUT_GROUP_H
|
||||||
|
#define URL_INPUT_GROUP_H
|
||||||
|
|
||||||
|
#include <GroupView.h>
|
||||||
|
|
||||||
|
class BTextView;
|
||||||
|
|
||||||
|
|
||||||
|
class URLInputGroup : public BGroupView {
|
||||||
|
public:
|
||||||
|
URLInputGroup();
|
||||||
|
virtual ~URLInputGroup();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void WindowActivated(bool active);
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
virtual void MakeFocus(bool focus = true);
|
||||||
|
|
||||||
|
BTextView* TextView() const;
|
||||||
|
void SetText(const char* text);
|
||||||
|
const char* Text() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class URLTextView;
|
||||||
|
|
||||||
|
URLTextView* fTextView;
|
||||||
|
bool fWindowActive;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // URL_INPUT_GROUP_H
|
||||||
|
|
||||||
+27
-28
@@ -6,7 +6,7 @@
|
|||||||
* Oliver Tappe <beam@hirschkaefer.de>
|
* Oliver Tappe <beam@hirschkaefer.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TextControlCompleter.h"
|
#include "TextViewCompleter.h"
|
||||||
|
|
||||||
#include <Looper.h>
|
#include <Looper.h>
|
||||||
#include <TextControl.h>
|
#include <TextControl.h>
|
||||||
@@ -15,75 +15,74 @@
|
|||||||
#include "AutoCompleterDefaultImpl.h"
|
#include "AutoCompleterDefaultImpl.h"
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - TextControlWrapper
|
// #pragma mark - TextViewWrapper
|
||||||
|
|
||||||
|
|
||||||
TextControlCompleter::TextControlWrapper::TextControlWrapper(
|
TextViewCompleter::TextViewWrapper::TextViewWrapper(BTextView* textView)
|
||||||
BTextControl* textControl)
|
|
||||||
:
|
:
|
||||||
fTextControl(textControl)
|
fTextView(textView)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextControlCompleter::TextControlWrapper::GetEditViewState(BString& text,
|
TextViewCompleter::TextViewWrapper::GetEditViewState(BString& text,
|
||||||
int32* caretPos)
|
int32* caretPos)
|
||||||
{
|
{
|
||||||
if (fTextControl && fTextControl->LockLooper()) {
|
if (fTextView && fTextView->LockLooper()) {
|
||||||
text = fTextControl->Text();
|
text = fTextView->Text();
|
||||||
if (caretPos) {
|
if (caretPos) {
|
||||||
int32 end;
|
int32 end;
|
||||||
fTextControl->TextView()->GetSelection(caretPos, &end);
|
fTextView->GetSelection(caretPos, &end);
|
||||||
}
|
}
|
||||||
fTextControl->UnlockLooper();
|
fTextView->UnlockLooper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextControlCompleter::TextControlWrapper::SetEditViewState(const BString& text,
|
TextViewCompleter::TextViewWrapper::SetEditViewState(const BString& text,
|
||||||
int32 caretPos, int32 selectionLength)
|
int32 caretPos, int32 selectionLength)
|
||||||
{
|
{
|
||||||
if (fTextControl && fTextControl->LockLooper()) {
|
if (fTextView && fTextView->LockLooper()) {
|
||||||
fTextControl->TextView()->SetText(text.String(), text.Length());
|
fTextView->SetText(text.String(), text.Length());
|
||||||
fTextControl->TextView()->Select(caretPos, caretPos + selectionLength);
|
fTextView->Select(caretPos, caretPos + selectionLength);
|
||||||
fTextControl->TextView()->ScrollToSelection();
|
fTextView->ScrollToSelection();
|
||||||
fTextControl->UnlockLooper();
|
fTextView->UnlockLooper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BRect
|
BRect
|
||||||
TextControlCompleter::TextControlWrapper::GetAdjustmentFrame()
|
TextViewCompleter::TextViewWrapper::GetAdjustmentFrame()
|
||||||
{
|
{
|
||||||
BRect frame = fTextControl->TextView()->Bounds();
|
BRect frame = fTextView->Bounds();
|
||||||
frame = fTextControl->TextView()->ConvertToScreen(frame);
|
frame = fTextView->ConvertToScreen(frame);
|
||||||
frame.InsetBy(0, -3);
|
frame.InsetBy(0, -3);
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextControlCompleter::TextControlCompleter(BTextControl* textControl,
|
TextViewCompleter::TextViewCompleter(BTextView* textView, ChoiceModel* model,
|
||||||
ChoiceModel* model, PatternSelector* patternSelector)
|
PatternSelector* patternSelector)
|
||||||
:
|
:
|
||||||
BAutoCompleter(new TextControlWrapper(textControl), model,
|
BAutoCompleter(new TextViewWrapper(textView), model,
|
||||||
new BDefaultChoiceView(), patternSelector),
|
new BDefaultChoiceView(), patternSelector),
|
||||||
BMessageFilter(B_KEY_DOWN),
|
BMessageFilter(B_KEY_DOWN),
|
||||||
fTextControl(textControl)
|
fTextView(textView)
|
||||||
{
|
{
|
||||||
fTextControl->TextView()->AddFilter(this);
|
fTextView->AddFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextControlCompleter::~TextControlCompleter()
|
TextViewCompleter::~TextViewCompleter()
|
||||||
{
|
{
|
||||||
fTextControl->TextView()->RemoveFilter(this);
|
fTextView->RemoveFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
filter_result
|
filter_result
|
||||||
TextControlCompleter::Filter(BMessage* message, BHandler** target)
|
TextViewCompleter::Filter(BMessage* message, BHandler** target)
|
||||||
{
|
{
|
||||||
const char* bytes;
|
const char* bytes;
|
||||||
int32 modifiers;
|
int32 modifiers;
|
||||||
@@ -91,7 +90,7 @@ TextControlCompleter::Filter(BMessage* message, BHandler** target)
|
|||||||
|| message->FindInt32("modifiers", &modifiers) != B_OK) {
|
|| message->FindInt32("modifiers", &modifiers) != B_OK) {
|
||||||
return B_DISPATCH_MESSAGE;
|
return B_DISPATCH_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bytes[0]) {
|
switch (bytes[0]) {
|
||||||
case B_UP_ARROW:
|
case B_UP_ARROW:
|
||||||
SelectPrevious();
|
SelectPrevious();
|
||||||
+10
-10
@@ -13,31 +13,31 @@
|
|||||||
#include "AutoCompleter.h"
|
#include "AutoCompleter.h"
|
||||||
|
|
||||||
|
|
||||||
class BTextControl;
|
class BTextView;
|
||||||
|
|
||||||
class TextControlCompleter : protected BAutoCompleter, public BMessageFilter {
|
class TextViewCompleter : protected BAutoCompleter, public BMessageFilter {
|
||||||
public:
|
public:
|
||||||
TextControlCompleter(BTextControl* textControl,
|
TextViewCompleter(BTextView* textView,
|
||||||
ChoiceModel* choiceModel = NULL,
|
ChoiceModel* choiceModel = NULL,
|
||||||
PatternSelector* patternSelector = NULL);
|
PatternSelector* patternSelector = NULL);
|
||||||
virtual ~TextControlCompleter();
|
virtual ~TextViewCompleter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual filter_result Filter(BMessage* message, BHandler** target);
|
virtual filter_result Filter(BMessage* message, BHandler** target);
|
||||||
|
|
||||||
class TextControlWrapper : public EditView {
|
class TextViewWrapper : public EditView {
|
||||||
public:
|
public:
|
||||||
TextControlWrapper(BTextControl* textControl);
|
TextViewWrapper(BTextView* textView);
|
||||||
virtual BRect GetAdjustmentFrame();
|
virtual BRect GetAdjustmentFrame();
|
||||||
virtual void GetEditViewState(BString& text,
|
virtual void GetEditViewState(BString& text,
|
||||||
int32* caretPos);
|
int32* caretPos);
|
||||||
virtual void SetEditViewState(const BString& text,
|
virtual void SetEditViewState(const BString& text,
|
||||||
int32 caretPos, int32 selectionLength = 0);
|
int32 caretPos, int32 selectionLength = 0);
|
||||||
private:
|
private:
|
||||||
BTextControl* fTextControl;
|
BTextView* fTextView;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
BTextControl* fTextControl;
|
BTextView* fTextView;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXT_CONTROL_COMPLETER_H
|
#endif // TEXT_CONTROL_COMPLETER_H
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BaseURL.h"
|
||||||
|
|
||||||
|
|
||||||
|
BString
|
||||||
|
baseURL(const BString string)
|
||||||
|
{
|
||||||
|
int32 baseURLStart = string.FindFirst("://") + 3;
|
||||||
|
int32 baseURLEnd = string.FindFirst("/", baseURLStart + 1);
|
||||||
|
BString result;
|
||||||
|
result.SetTo(string.String() + baseURLStart, baseURLEnd - baseURLStart);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef BASE_URL_H
|
||||||
|
#define BASE_URL_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
BString baseURL(const BString string);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BASE_URL_H
|
||||||
Reference in New Issue
Block a user