From 50c66f38576be9af6e806361871107f51405de1a Mon Sep 17 00:00:00 2001 From: stippi Date: Fri, 30 Apr 2010 14:05:35 +0000 Subject: [PATCH] * Store the favicon in the PageUserData of any BWebView instance. * Refactored setting the page icon so it always goes through the new BrowserWindow::_SetPageIcon(). * Don't replace the PageUserData in _TabChanged() if it already exists (which would forget the favicon). * Write the favicon to the Bookmark file. At the moment, it writes the 32x32 icon as upscaled version of the 16x16 icon. Color reduction makes the icons look not so nice, since Haiku does not yet support PNG icons... git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@464 94f232f2-1747-11df-bad5-a5bfde151594 --- src/apps/webpositive/BrowserWindow.cpp | 112 +++++++++++++++++++++++-- src/apps/webpositive/BrowserWindow.h | 3 + 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 552b2ee885..9699ca2bd7 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -139,17 +139,43 @@ class PageUserData : public BWebView::UserData { public: PageUserData(BView* focusedView) : - fFocusedView(focusedView) + fFocusedView(focusedView), + fPageIcon(NULL) { } + ~PageUserData() + { + delete fPageIcon; + } + + void SetFocusedView(BView* focusedView) + { + fFocusedView = focusedView; + } + BView* FocusedView() const { return fFocusedView; } + void SetPageIcon(const BBitmap* icon) + { + delete fPageIcon; + if (icon) + fPageIcon = new BBitmap(icon); + else + fPageIcon = NULL; + } + + const BBitmap* PageIcon() const + { + return fPageIcon; + } + private: - BView* fFocusedView; + BView* fFocusedView; + BBitmap* fPageIcon; }; @@ -456,7 +482,7 @@ BrowserWindow::MessageReceived(BMessage* message) BString url; if (message->FindString("url", &url) != B_OK) url = fURLInputGroup->Text(); - fTabManager->SetTabIcon(CurrentWebView(), NULL); + _SetPageIcon(CurrentWebView(), NULL); CurrentWebView()->LoadURL(url.String()); break; } @@ -1019,7 +1045,7 @@ BrowserWindow::TitleChanged(const BString& title, BWebView* view) void BrowserWindow::IconReceived(const BBitmap* icon, BWebView* view) { - fTabManager->SetTabIcon(view, icon); + _SetPageIcon(view, icon); } @@ -1128,14 +1154,24 @@ BrowserWindow::_TabChanged(int32 index) if (webView == CurrentWebView()) return; - if (CurrentWebView() != NULL) - CurrentWebView()->SetUserData(new PageUserData(CurrentFocus())); + if (CurrentWebView() != NULL) { + // Remember the currently focused view before switching tabs, + // so that we can revert the focus when switching back to this tab + // later. + PageUserData* userData = static_cast( + webView->GetUserData()); + if (userData) + userData->SetFocusedView(CurrentFocus()); + else + CurrentWebView()->SetUserData(new PageUserData(CurrentFocus())); + } SetCurrentWebView(webView); if (webView != NULL) { _UpdateTitle(webView->MainFrameTitle()); + // Restore the previous focus or focus the web view. PageUserData* userData = static_cast( webView->GetUserData()); if (userData != NULL && userData->FocusedView() != NULL) @@ -1247,8 +1283,53 @@ BrowserWindow::_CreateBookmark() } BNodeInfo nodeInfo(&bookmarkFile); - if (status == B_OK) + if (status == B_OK) { status = nodeInfo.SetType("application/x-vnd.Be-bookmark"); + if (status == B_OK) { + PageUserData* userData = static_cast( + webView->GetUserData()); + if (userData != NULL && userData->PageIcon() != NULL) { + BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, + B_CMAP8); + status_t ret = miniIcon.ImportBits(userData->PageIcon()); + if (ret == B_OK) + ret = nodeInfo.SetIcon(&miniIcon, B_MINI_ICON); + if (ret != B_OK) { + fprintf(stderr, "Failed to store mini icon for bookmark: " + "%s\n", strerror(ret)); + } + BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, + B_CMAP8); + // TODO: Store 32x32 favicon which is often provided by sites. + const uint8* src = (const uint8*)miniIcon.Bits(); + uint32 srcBPR = miniIcon.BytesPerRow(); + uint8* dst = (uint8*)largeIcon.Bits(); + uint32 dstBPR = largeIcon.BytesPerRow(); + for (uint32 y = 0; y < 16; y++) { + const uint8* s = src; + uint8* d = dst; + for (uint32 x = 0; x < 16; x++) { + *d++ = *s; + *d++ = *s++; + } + dst += dstBPR; + s = src; + for (uint32 x = 0; x < 16; x++) { + *d++ = *s; + *d++ = *s++; + } + dst += dstBPR; + src += srcBPR; + } + if (ret == B_OK) + ret = nodeInfo.SetIcon(&largeIcon, B_LARGE_ICON); + if (ret != B_OK) { + fprintf(stderr, "Failed to store large icon for bookmark: " + "%s\n", strerror(ret)); + } + } + } + } if (status != B_OK) { BString message("There was an error creating the bookmark " @@ -1348,6 +1429,23 @@ BrowserWindow::_AddBookmarkURLsRecursively(BDirectory& directory, } +void +BrowserWindow::_SetPageIcon(BWebView* view, const BBitmap* icon) +{ + PageUserData* userData = static_cast(view->GetUserData()); + if (userData == NULL) { + userData = new(std::nothrow) PageUserData(NULL); + if (userData == NULL) + return; + view->SetUserData(userData); + } + // The PageUserData makes a copy of the icon, which we pass on to + // the TabManager for display in the respective tab. + userData->SetPageIcon(icon); + fTabManager->SetTabIcon(view, userData->PageIcon()); +} + + static void addItemToMenuOrSubmenu(BMenu* menu, BMenuItem* newItem) { diff --git a/src/apps/webpositive/BrowserWindow.h b/src/apps/webpositive/BrowserWindow.h index 31886fa045..9f3937257b 100644 --- a/src/apps/webpositive/BrowserWindow.h +++ b/src/apps/webpositive/BrowserWindow.h @@ -150,6 +150,9 @@ private: BMessage* message, uint32& addedCount) const; + void _SetPageIcon(BWebView* view, + const BBitmap* icon); + void _UpdateHistoryMenu(); void _UpdateClipboardItems();