summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 03:30:22 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 03:30:22 +0000
commit59560e0ba999d5edc33453d4a0fbf44831025817 (patch)
treef365944f6f0eca593a28747a7fed4caf169578fb /chrome/browser
parent4d2868972ff25746d39ecea58e88480ae0463145 (diff)
downloadchromium_src-59560e0ba999d5edc33453d4a0fbf44831025817.zip
chromium_src-59560e0ba999d5edc33453d4a0fbf44831025817.tar.gz
chromium_src-59560e0ba999d5edc33453d4a0fbf44831025817.tar.bz2
Move download shelf from per-tab to per-window. Also disable auto-hiding of
the shelf. BUG=9025 TEST=Download file in one tab, open new tab, and check that download shelf is still open. Also try the shelf's close button and the "show all downloads" link. When saving a file, the download animation should not show up. Review URL: http://codereview.chromium.org/115740 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17595 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc24
-rw-r--r--chrome/browser/automation/automation_provider.h1
-rw-r--r--chrome/browser/browser.cc23
-rw-r--r--chrome/browser/browser.h4
-rw-r--r--chrome/browser/browser_window.h8
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h8
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm19
-rw-r--r--chrome/browser/download/download_file.cc19
-rw-r--r--chrome/browser/download/download_shelf.cc14
-rw-r--r--chrome/browser/download/download_shelf.h29
-rw-r--r--chrome/browser/download/download_uitest.cc66
-rw-r--r--chrome/browser/download/save_package.cc4
-rw-r--r--chrome/browser/download/save_page_uitest.cc13
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc19
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h6
-rw-r--r--chrome/browser/gtk/download_item_gtk.cc76
-rw-r--r--chrome/browser/gtk/download_item_gtk.h10
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc54
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.h11
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc27
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.h9
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc11
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc95
-rw-r--r--chrome/browser/tab_contents/tab_contents.h35
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h7
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc26
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h5
-rw-r--r--chrome/browser/views/download_shelf_view.cc47
-rw-r--r--chrome/browser/views/download_shelf_view.h10
-rw-r--r--chrome/browser/views/frame/browser_view.cc59
-rw-r--r--chrome/browser/views/frame/browser_view.h14
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc42
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h5
33 files changed, 392 insertions, 408 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index c2e0877..7fce063 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -24,6 +24,7 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/find_bar.h"
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/find_notification_details.h"
@@ -1082,6 +1083,7 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
SetEnableExtensionAutomation)
+ IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
IPC_END_MESSAGE_MAP()
}
@@ -1956,11 +1958,27 @@ void AutomationProvider::ExecuteJavascript(int handle,
void AutomationProvider::GetShelfVisibility(int handle, bool* visible) {
*visible = false;
- TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
- if (tab_contents)
- *visible = tab_contents->IsDownloadShelfVisible();
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ if (browser) {
+ *visible = browser->window()->IsDownloadShelfVisible();
+ }
+ }
+}
+
+void AutomationProvider::SetShelfVisibility(int handle, bool visible) {
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ if (browser) {
+ if (visible)
+ browser->window()->GetDownloadShelf()->Show();
+ else
+ browser->window()->GetDownloadShelf()->Close();
+ }
+ }
}
+
void AutomationProvider::GetConstrainedWindowCount(int handle, int* count) {
*count = -1; // -1 is the error code
if (tab_tracker_->ContainsHandle(handle)) {
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 1506868..8673bed 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -215,6 +215,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
const std::wstring& script,
IPC::Message* reply_message);
void GetShelfVisibility(int handle, bool* visible);
+ void SetShelfVisibility(int handle, bool visible);
void SetFilteredInet(const IPC::Message& message, bool enabled);
void SetProxyConfig(const std::string& new_proxy_config);
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 92c8ab6..fe99bdd 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -18,7 +18,10 @@
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/debugger/debugger_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
+#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/download/download_shelf.h"
+#include "chrome/browser/download/download_started_animation.h"
#include "chrome/browser/find_bar.h"
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/location_bar.h"
@@ -42,6 +45,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/page_transition_types.h"
+#include "chrome/common/platform_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/url_constants.h"
@@ -1153,6 +1157,25 @@ void Browser::OpenHelpTab() {
false, NULL);
}
+void Browser::OnStartDownload(DownloadItem* download) {
+ if (!window())
+ return;
+
+ // GetDownloadShelf creates the download shelf if it was not yet created.
+ window()->GetDownloadShelf()->AddDownload(new DownloadItemModel(download));
+
+// TODO(port): port for mac.
+#if defined(OS_WIN) || defined(OS_LINUX)
+ // Don't show the animation for "Save file" downloads.
+ if (download->total_bytes() > 0) {
+ TabContents* current_tab = GetSelectedTabContents();
+ // We make this check for the case of minimized windows, unit tests, etc.
+ if (platform_util::IsVisible(current_tab->GetNativeView()))
+ DownloadStartedAnimation::Show(current_tab);
+ }
+#endif
+}
+
///////////////////////////////////////////////////////////////////////////////
// static
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index b2950fd..789c9ef 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -381,6 +381,9 @@ class Browser : public TabStripModelDelegate,
void OpenAboutChromeDialog();
void OpenHelpTab();
+ virtual void OnStartDownload(DownloadItem* download);
+ virtual void UpdateDownloadShelfVisibility(bool visible);
+
/////////////////////////////////////////////////////////////////////////////
static void RegisterPrefs(PrefService* prefs);
@@ -481,7 +484,6 @@ class Browser : public TabStripModelDelegate,
// is the mouse leaving the view.
virtual void ContentsMouseEvent(TabContents* source, bool motion);
virtual void UpdateTargetURL(TabContents* source, const GURL& url);
- virtual void UpdateDownloadShelfVisibility(bool visible);
virtual void ContentsZoomChange(bool zoom_in);
virtual bool IsApplication() const;
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index 3ce7097..743cc94 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -10,6 +10,8 @@
class Browser;
class BrowserList;
class BrowserWindowTesting;
+class DownloadItem;
+class DownloadShelf;
class FindBar;
class GURL;
class LocationBar;
@@ -143,6 +145,12 @@ class BrowserWindow {
// |already_bookmarked| is true if the url is already bookmarked.
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) = 0;
+ // Whether or not the shelf view is visible.
+ virtual bool IsDownloadShelfVisible() const = 0;
+
+ // Returns the DownloadShelf.
+ virtual DownloadShelf* GetDownloadShelf() = 0;
+
// Shows the Report a Bug dialog box.
virtual void ShowReportBugDialog() = 0;
diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index 4cec480..69b9715 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -57,6 +57,8 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
+ virtual bool IsDownloadShelfVisible() const;
+ virtual DownloadShelf* GetDownloadShelf();
virtual void ShowReportBugDialog();
virtual void ShowClearBrowsingDataDialog();
virtual void ShowImportDialog();
@@ -86,6 +88,12 @@ class BrowserWindowCocoa : public BrowserWindow,
NSWindow* window_; // weak, owned by controller
Browser* browser_; // weak, owned by controller
BrowserWindowController* controller_; // weak, owns us
+
+ // Data for shelves and stuff ------------------------------------------------
+ // FIXME(thakis): This should probably in the controller on OS X.
+
+ // The download shelf view (view at the bottom of the page).
+ scoped_ptr<DownloadShelf> download_shelf_;
};
#endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 429c0be..d052f61 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -10,15 +10,20 @@
#import "chrome/browser/cocoa/browser_window_controller.h"
#import "chrome/browser/cocoa/clear_browsing_data_controller.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/download/download_shelf.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
+#include "chrome/common/temp_scaffolding_stubs.h"
#include "chrome/browser/profile.h"
BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
BrowserWindowController* controller,
NSWindow* window)
- : window_(window), browser_(browser), controller_(controller) {
+ : window_(window),
+ browser_(browser),
+ controller_(controller),
+ download_shelf_() {
// This pref applies to all windows, so all must watch for it.
registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
NotificationService::AllSources());
@@ -182,6 +187,18 @@ void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
NOTIMPLEMENTED();
}
+bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
+ return download_shelf_ != NULL && download_shelf_->IsShowing();
+}
+
+DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
+ NOTIMPLEMENTED();
+ if (!download_shelf_.get()) {
+ download_shelf_.reset(new DownloadShelfMac(browser_));
+ }
+ return download_shelf_.get();
+}
+
void BrowserWindowCocoa::ShowReportBugDialog() {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc
index b871540..7be3411 100644
--- a/chrome/browser/download/download_file.cc
+++ b/chrome/browser/download/download_file.cc
@@ -536,17 +536,18 @@ void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) {
void DownloadFileManager::OnOpenDownloadInShell(const FilePath& full_path,
const GURL& url,
gfx::NativeView parent_window) {
- DCHECK(MessageLoop::current() == file_loop_);
-
#if defined(OS_WIN)
- if (NULL != parent_window) {
- win_util::SaferOpenItemViaShell(parent_window, L"", full_path,
- UTF8ToWide(url.spec()));
- return;
- }
+ DCHECK(MessageLoop::current() == file_loop_);
+ if (NULL != parent_window) {
+ win_util::SaferOpenItemViaShell(parent_window, L"", full_path,
+ UTF8ToWide(url.spec()));
+ } else {
+ win_util::OpenItemViaShell(full_path);
+ }
+#else
+ // TODO(port) implement me.
+ NOTIMPLEMENTED();
#endif
-
- platform_util::OpenItem(full_path);
}
// The DownloadManager in the UI thread has provided a final name for the
diff --git a/chrome/browser/download/download_shelf.cc b/chrome/browser/download/download_shelf.cc
index 6962a3e..0b468c4 100644
--- a/chrome/browser/download/download_shelf.cc
+++ b/chrome/browser/download/download_shelf.cc
@@ -6,11 +6,11 @@
#include "app/l10n_util.h"
#include "base/file_util.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/dom_ui/downloads_ui.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
@@ -22,17 +22,11 @@
// DownloadShelf ---------------------------------------------------------------
void DownloadShelf::ShowAllDownloads() {
- Profile* profile = tab_contents_->profile();
+ Profile* profile = browser_->profile();
if (profile)
UserMetrics::RecordAction(L"ShowDownloads", profile);
- tab_contents_->OpenURL(GURL(chrome::kChromeUIDownloadsURL), GURL(),
- SINGLETON_TAB, PageTransition::AUTO_BOOKMARK);
-}
-
-void DownloadShelf::ChangeTabContents(TabContents* old_contents,
- TabContents* new_contents) {
- DCHECK(old_contents == tab_contents_);
- tab_contents_ = new_contents;
+ browser_->OpenURL(GURL(chrome::kChromeUIDownloadsURL), GURL(),
+ NEW_FOREGROUND_TAB, PageTransition::AUTO_BOOKMARK);
}
// DownloadShelfContextMenu ----------------------------------------------------
diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h
index 1b455c0..1ad0b71 100644
--- a/chrome/browser/download/download_shelf.h
+++ b/chrome/browser/download/download_shelf.h
@@ -7,47 +7,48 @@
#include <string>
+#include "base/logging.h"
#include "base/basictypes.h"
class BaseDownloadItemModel;
+class Browser;
class DownloadItem;
-class TabContents;
// DownloadShelf is an interface for platform-specific download shelves to
// implement. It also contains some shared logic. This class should not be
// instantiated directly, but rather created via a call to Create().
+// It is a view object.
class DownloadShelf {
public:
- explicit DownloadShelf(TabContents* tab_contents)
- : tab_contents_(tab_contents) { }
+ explicit DownloadShelf(Browser* browser)
+ : browser_(browser) { DCHECK(browser_); }
virtual ~DownloadShelf() { }
- // Creates a platform-specific DownloadShelf, passing ownership to the caller.
- static DownloadShelf* Create(TabContents* tab_contents);
-
// A new download has started, so add it to our shelf. This object will
- // take ownership of |download_model|.
+ // take ownership of |download_model|. Also make the shelf visible.
virtual void AddDownload(BaseDownloadItemModel* download_model) = 0;
// Invoked when the user clicks the 'show all downloads' link button.
void ShowAllDownloads();
- // Invoked when the download shelf is migrated from one tab contents to a new
- // one.
- void ChangeTabContents(TabContents* old_contents, TabContents* new_contents);
-
// The browser view needs to know when we are going away to properly return
// the resize corner size to WebKit so that we don't draw on top of it.
- // This returns the showing state of our animation which is set to false at
- // the beginning Show and true at the beginning of a Hide.
+ // This returns the showing state of our animation which is set to true at
+ // the beginning Show and false at the beginning of a Hide.
virtual bool IsShowing() const = 0;
// Returns whether the download shelf is showing the close animation.
virtual bool IsClosing() const = 0;
+ // Opens the shelf.
+ virtual void Show() = 0;
+
+ // Closes the shelf.
+ virtual void Close() = 0;
+
protected:
- TabContents* tab_contents_;
+ Browser* browser_;
private:
DISALLOW_COPY_AND_ASSIGN(DownloadShelf);
diff --git a/chrome/browser/download/download_uitest.cc b/chrome/browser/download/download_uitest.cc
index 78a3683..8f7eb99 100644
--- a/chrome/browser/download/download_uitest.cc
+++ b/chrome/browser/download/download_uitest.cc
@@ -131,9 +131,7 @@ class DownloadTest : public UITest {
// TODO(tc): check download status text
// Make sure the download shelf is showing.
- scoped_refptr<TabProxy> dl_tab(window->GetTab(0));
- ASSERT_TRUE(dl_tab.get());
- EXPECT_TRUE(WaitForDownloadShelfVisible(dl_tab.get()));
+ EXPECT_TRUE(WaitForDownloadShelfVisible(window.get()));
}
FilePath filename;
@@ -170,9 +168,9 @@ TEST_F(DownloadTest, DownloadMimeType) {
CleanUpDownload(file);
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
- ASSERT_TRUE(tab_proxy.get());
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab_proxy.get()));
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}
// Access a file with a viewable mime-type, verify that a download
@@ -196,9 +194,9 @@ TEST_F(DownloadTest, NoDownload) {
if (file_util::PathExists(file_path))
ASSERT_TRUE(file_util::Delete(file_path, false));
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
- ASSERT_TRUE(tab_proxy.get());
- EXPECT_FALSE(WaitForDownloadShelfVisible(tab_proxy.get()));
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+ EXPECT_FALSE(WaitForDownloadShelfVisible(browser.get()));
}
// Download a 0-size file with a content-disposition header, verify that the
@@ -218,12 +216,54 @@ TEST_F(DownloadTest, ContentDisposition) {
CleanUpDownload(download_file, file);
- // Ensure the download shelf is visible on the current tab.
- scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
- ASSERT_TRUE(tab_proxy.get());
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab_proxy.get()));
+ // Ensure the download shelf is visible on the window.
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}
+// Test that the download shelf is per-window by starting a download in one
+// tab, opening a second tab, closing the shelf, going back to the first tab,
+// and checking that the shelf is closed.
+TEST_F(DownloadTest, PerWindowShelf) {
+ FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
+ FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));
+
+ EXPECT_EQ(1, GetTabCount());
+
+ NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file.ToWStringHack()));
+ WaitUntilTabCount(1);
+
+ // Wait until the file is downloaded.
+ PlatformThread::Sleep(action_timeout_ms());
+
+ CleanUpDownload(download_file, file);
+
+ // Ensure the download shelf is visible on the window.
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
+
+ // Open a second tab
+ browser->AppendTab(GURL(""));
+ WaitUntilTabCount(2);
+
+ // Hide shelf
+ browser->SetShelfVisible(false);
+ EXPECT_TRUE(WaitForDownloadShelfInvisible(browser.get()));
+
+ // Go to first tab
+ EXPECT_TRUE(browser->ActivateTab(0));
+ int tab_count;
+ EXPECT_TRUE(browser->GetTabCount(&tab_count));
+ ASSERT_EQ(2, tab_count);
+
+ bool shelf_visible;
+ EXPECT_TRUE(browser->IsShelfVisible(&shelf_visible));
+ ASSERT_FALSE(shelf_visible);
+}
+
+
// UnknownSize and KnownSize are tests which depend on
// URLRequestSlowDownloadJob to serve content in a certain way. Data will be
// sent in two chunks where the first chunk is 35K and the second chunk is 10K.
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 645346b..cd23fc2 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -252,9 +252,7 @@ bool SavePackage::Init() {
FilePath(), Time::Now(), 0, -1, -1, false);
download_->set_manager(tab_contents_->profile()->GetDownloadManager());
#if !defined(OS_MACOSX)
- DownloadShelf* shelf = tab_contents_->GetDownloadShelf(true);
- shelf->AddDownload(new SavePageModel(this, download_));
- tab_contents_->SetDownloadShelfVisible(true);
+ tab_contents_->OnStartDownload(download_);
#else
// TODO(port): Create a download shelf for mac.
NOTIMPLEMENTED();
diff --git a/chrome/browser/download/save_page_uitest.cc b/chrome/browser/download/save_page_uitest.cc
index 4562d20..840a9f0 100644
--- a/chrome/browser/download/save_page_uitest.cc
+++ b/chrome/browser/download/save_page_uitest.cc
@@ -85,7 +85,8 @@ TEST_F(SavePageTest, SaveHTMLOnly) {
EXPECT_TRUE(tab->SavePage(full_file_name.ToWStringHack(), dir.ToWStringHack(),
SavePackage::SAVE_AS_ONLY_HTML));
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab.get()));
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
CheckFile(full_file_name, FilePath::FromWStringHack(UTF8ToWide(file_name)),
true);
@@ -105,7 +106,8 @@ TEST_F(SavePageTest, SaveCompleteHTML) {
EXPECT_TRUE(tab->SavePage(full_file_name.ToWStringHack(), dir.ToWStringHack(),
SavePackage::SAVE_AS_COMPLETE_HTML));
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab.get()));
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
CheckFile(dir.AppendASCII("1.png"), FilePath(FILE_PATH_LITERAL("1.png")),
true);
@@ -128,7 +130,8 @@ TEST_F(SavePageTest, NoSave) {
EXPECT_FALSE(tab->SavePage(full_file_name.ToWStringHack(),
dir.ToWStringHack(),
SavePackage::SAVE_AS_ONLY_HTML));
- EXPECT_FALSE(WaitForDownloadShelfVisible(tab.get()));
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ EXPECT_FALSE(WaitForDownloadShelfVisible(browser.get()));
}
TEST_F(SavePageTest, FilenameFromPageTitle) {
@@ -148,7 +151,7 @@ TEST_F(SavePageTest, FilenameFromPageTitle) {
scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
automation()->SavePackageShouldPromptUser(false);
EXPECT_TRUE(browser->RunCommandAsync(IDC_SAVE_PAGE));
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab.get()));
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
automation()->SavePackageShouldPromptUser(true);
CheckFile(dir.AppendASCII("1.png"), FilePath(FILE_PATH_LITERAL("1.png")),
@@ -180,7 +183,7 @@ TEST_F(SavePageTest, CleanFilenameFromPageTitle) {
scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
automation()->SavePackageShouldPromptUser(false);
EXPECT_TRUE(browser->RunCommandAsync(IDC_SAVE_PAGE));
- EXPECT_TRUE(WaitForDownloadShelfVisible(tab.get()));
+ EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
automation()->SavePackageShouldPromptUser(true);
CheckFile(full_file_name, FilePath::FromWStringHack(UTF8ToWide(file_name)),
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 5c090d6..f4b86f2 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -18,10 +18,13 @@
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/download/download_item_model.h"
+#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/gtk/about_chrome_dialog.h"
#include "chrome/browser/gtk/bookmark_bar_gtk.h"
#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h"
+#include "chrome/browser/gtk/download_shelf_gtk.h"
#include "chrome/browser/gtk/go_button_gtk.h"
#include "chrome/browser/gtk/import_dialog_gtk.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"
@@ -566,6 +569,17 @@ void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url,
toolbar_->star()->ShowStarBubble(url, !already_bookmarked);
}
+bool BrowserWindowGtk::IsDownloadShelfVisible() const {
+ return download_shelf_.get() && download_shelf_->IsShowing();
+}
+
+DownloadShelf* BrowserWindowGtk::GetDownloadShelf() {
+ if (!download_shelf_.get())
+ download_shelf_.reset(new DownloadShelfGtk(browser_.get(),
+ render_area_vbox_));
+ return download_shelf_.get();
+}
+
void BrowserWindowGtk::ShowReportBugDialog() {
NOTIMPLEMENTED();
}
@@ -604,11 +618,12 @@ void BrowserWindowGtk::UserChangedTheme() {
}
int BrowserWindowGtk::GetExtraRenderViewHeight() const {
- // The download shelf is controlled by its TabContents, so we don't have to
- // worry about it here.
int sum = infobar_container_->TotalHeightOfClosingBars();
if (bookmark_bar_->IsClosing())
sum += bookmark_bar_->GetHeight();
+ if (download_shelf_.get() && download_shelf_->IsClosing()) {
+ sum += download_shelf_->GetHeight();
+ }
return sum;
}
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 8e6dee5..4e5f067ad 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -19,6 +19,7 @@
class BookmarkBarGtk;
class BrowserToolbarGtk;
+class DownloadShelfGtk;
class FindBarGtk;
class InfoBarContainerGtk;
class LocationBar;
@@ -71,6 +72,8 @@ class BrowserWindowGtk : public BrowserWindow,
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
+ virtual bool IsDownloadShelfVisible() const;
+ virtual DownloadShelf* GetDownloadShelf();
virtual void ShowReportBugDialog();
virtual void ShowClearBrowsingDataDialog();
virtual void ShowImportDialog();
@@ -136,6 +139,9 @@ class BrowserWindowGtk : public BrowserWindow,
scoped_ptr<Browser> browser_;
+ // The download shelf view (view at the bottom of the page).
+ scoped_ptr<DownloadShelfGtk> download_shelf_;
+
private:
// Sets the default size for the window and the the way the user is allowed to
// resize it.
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc
index 55ef572..22f2b3a 100644
--- a/chrome/browser/gtk/download_item_gtk.cc
+++ b/chrome/browser/gtk/download_item_gtk.cc
@@ -177,18 +177,18 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
InitNineBoxes();
LoadIcon();
- body_ = gtk_button_new();
- gtk_widget_set_app_paintable(body_, TRUE);
- g_signal_connect(body_, "expose-event",
+ body_.Own(gtk_button_new());
+ gtk_widget_set_app_paintable(body_.get(), TRUE);
+ g_signal_connect(body_.get(), "expose-event",
G_CALLBACK(OnExpose), this);
- g_signal_connect(body_, "clicked",
+ g_signal_connect(body_.get(), "clicked",
G_CALLBACK(OnClick), this);
- GTK_WIDGET_UNSET_FLAGS(body_, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS(body_.get(), GTK_CAN_FOCUS);
// Remove internal padding on the button.
GtkRcStyle* no_padding_style = gtk_rc_style_new();
no_padding_style->xthickness = 0;
no_padding_style->ythickness = 0;
- gtk_widget_modify_style(body_, no_padding_style);
+ gtk_widget_modify_style(body_.get(), no_padding_style);
g_object_unref(no_padding_style);
name_label_ = gtk_label_new(NULL);
@@ -221,18 +221,18 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
// We use a GtkFixed because we don't want it to have its own window.
// This choice of widget is not critically important though.
- progress_area_ = gtk_fixed_new();
- gtk_widget_set_size_request(progress_area_,
+ progress_area_.Own(gtk_fixed_new());
+ gtk_widget_set_size_request(progress_area_.get(),
download_util::kSmallProgressIconSize,
download_util::kSmallProgressIconSize);
- gtk_widget_set_app_paintable(progress_area_, TRUE);
- g_signal_connect(progress_area_, "expose-event",
+ gtk_widget_set_app_paintable(progress_area_.get(), TRUE);
+ g_signal_connect(progress_area_.get(), "expose-event",
G_CALLBACK(OnProgressAreaExpose), this);
// Put the download progress icon on the left of the labels.
GtkWidget* body_hbox = gtk_hbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(body_), body_hbox);
- gtk_box_pack_start(GTK_BOX(body_hbox), progress_area_, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(body_.get()), body_hbox);
+ gtk_box_pack_start(GTK_BOX(body_hbox), progress_area_.get(), FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(body_hbox), text_stack, TRUE, TRUE, 0);
menu_button_ = gtk_button_new();
@@ -247,12 +247,12 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
gtk_widget_set_size_request(menu_button_, kMenuButtonWidth, 0);
GtkWidget* shelf_hbox = parent_shelf->GetHBox();
- hbox_ = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox_), body_, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox_), menu_button_, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(shelf_hbox), hbox_, FALSE, FALSE, 0);
+ hbox_.Own(gtk_hbox_new(FALSE, 0));
+ gtk_box_pack_start(GTK_BOX(hbox_.get()), body_.get(), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_.get()), menu_button_, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(shelf_hbox), hbox_.get(), FALSE, FALSE, 0);
// Insert as the leftmost item.
- gtk_box_reorder_child(GTK_BOX(shelf_hbox), hbox_, 1);
+ gtk_box_reorder_child(GTK_BOX(shelf_hbox), hbox_.get(), 1);
resize_handler_id_ = g_signal_connect(G_OBJECT(shelf_hbox), "size-allocate",
G_CALLBACK(OnShelfResized), this);
@@ -261,11 +261,11 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
new_item_animation_.reset(new SlideAnimation(this));
new_item_animation_->SetSlideDuration(kNewItemAnimationDurationMs);
- gtk_widget_show_all(hbox_);
+ gtk_widget_show_all(hbox_.get());
if (IsDangerous()) {
// Hide the download item components for now.
- gtk_widget_hide(body_);
+ gtk_widget_hide(body_.get());
gtk_widget_hide(menu_button_);
// Create an hbox to hold it all.
@@ -327,7 +327,7 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
gtk_alignment_set_padding(GTK_ALIGNMENT(dangerous_prompt_),
0, 0, kDangerousElementPadding, kDangerousElementPadding);
gtk_container_add(GTK_CONTAINER(dangerous_prompt_), dangerous_hbox_);
- gtk_box_pack_start(GTK_BOX(hbox_), dangerous_prompt_, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_.get()), dangerous_prompt_, FALSE, FALSE, 0);
gtk_widget_set_app_paintable(dangerous_prompt_, TRUE);
g_signal_connect(dangerous_prompt_, "expose-event",
G_CALLBACK(OnDangerousPromptExpose), this);
@@ -346,9 +346,23 @@ DownloadItemGtk::DownloadItemGtk(DownloadShelfGtk* parent_shelf,
DownloadItemGtk::~DownloadItemGtk() {
StopDownloadProgress();
- g_signal_handler_disconnect(parent_shelf_->GetHBox(), resize_handler_id_);
- gtk_widget_destroy(hbox_);
+
+ // If the top-level window was already destroyed, the signal handler was
+ // already disconnected. Disconnect if that's not the case.
+ if (g_signal_handler_find(parent_shelf_->GetHBox(),
+ G_SIGNAL_MATCH_ID,
+ resize_handler_id_,
+ 0,
+ NULL,
+ NULL,
+ NULL) != 0) {
+ g_signal_handler_disconnect(parent_shelf_->GetHBox(), resize_handler_id_);
+ }
get_download()->RemoveObserver(this);
+
+ hbox_.Destroy();
+ progress_area_.Destroy();
+ body_.Destroy();
}
void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) {
@@ -357,7 +371,7 @@ void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) {
if (dangerous_prompt_ != NULL &&
download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
// We have been approved.
- gtk_widget_show_all(hbox_);
+ gtk_widget_show_all(hbox_.get());
gtk_widget_destroy(dangerous_prompt_);
dangerous_prompt_ = NULL;
}
@@ -407,7 +421,7 @@ void DownloadItemGtk::OnDownloadUpdated(DownloadItem* download) {
void DownloadItemGtk::AnimationProgressed(const Animation* animation) {
if (animation == complete_animation_.get()) {
- gtk_widget_queue_draw(progress_area_);
+ gtk_widget_queue_draw(progress_area_.get());
} else {
if (IsDangerous()) {
int progress = (dangerous_hbox_full_width_ -
@@ -424,7 +438,7 @@ void DownloadItemGtk::AnimationProgressed(const Animation* animation) {
download_util::kSmallProgressIconSize) *
new_item_animation_->GetCurrentValue()));
showing_width = std::max(showing_width, kMinDownloadItemWidth);
- gtk_widget_set_size_request(body_, showing_width, -1);
+ gtk_widget_set_size_request(body_.get(), showing_width, -1);
}
}
}
@@ -443,7 +457,7 @@ void DownloadItemGtk::UpdateDownloadProgress() {
progress_angle_ = (progress_angle_ +
download_util::kUnknownIncrementDegrees) %
download_util::kMaxDegrees;
- gtk_widget_queue_draw(progress_area_);
+ gtk_widget_queue_draw(progress_area_.get());
}
void DownloadItemGtk::StartDownloadProgress() {
@@ -463,7 +477,7 @@ void DownloadItemGtk::StopDownloadProgress() {
void DownloadItemGtk::OnLoadIconComplete(IconManager::Handle handle,
SkBitmap* icon_bitmap) {
icon_ = icon_bitmap;
- gtk_widget_queue_draw(progress_area_);
+ gtk_widget_queue_draw(progress_area_.get());
}
void DownloadItemGtk::LoadIcon() {
@@ -543,7 +557,7 @@ gboolean DownloadItemGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e,
DownloadItemGtk* download_item) {
NineBox* nine_box = NULL;
// If true, this widget is |body_|, otherwise it is |menu_button_|.
- bool is_body = widget == download_item->body_;
+ bool is_body = widget == download_item->body_.get();
if (GTK_WIDGET_STATE(widget) == GTK_STATE_PRELIGHT)
nine_box = is_body ? body_nine_box_prelight_ : menu_nine_box_prelight_;
else if (GTK_WIDGET_STATE(widget) == GTK_STATE_ACTIVE)
@@ -641,11 +655,11 @@ gboolean DownloadItemGtk::OnMenuButtonPressEvent(GtkWidget* button,
void DownloadItemGtk::OnShelfResized(GtkWidget *widget,
GtkAllocation *allocation,
DownloadItemGtk* item) {
- if (item->hbox_->allocation.x + item->hbox_->allocation.width >
+ if (item->hbox_.get()->allocation.x + item->hbox_.get()->allocation.width >
item->bounding_widget_->allocation.x)
- gtk_widget_hide(item->hbox_);
+ gtk_widget_hide(item->hbox_.get());
else
- gtk_widget_show(item->hbox_);
+ gtk_widget_show(item->hbox_.get());
}
// static
diff --git a/chrome/browser/gtk/download_item_gtk.h b/chrome/browser/gtk/download_item_gtk.h
index 13680cd..e2fbf10 100644
--- a/chrome/browser/gtk/download_item_gtk.h
+++ b/chrome/browser/gtk/download_item_gtk.h
@@ -11,6 +11,7 @@
#include "base/scoped_ptr.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/icon_manager.h"
+#include "chrome/common/owned_widget_gtk.h"
class BaseDownloadItemModel;
class DownloadShelfContextMenuGtk;
@@ -26,8 +27,7 @@ class DownloadItemGtk : public DownloadItem::Observer,
DownloadItemGtk(DownloadShelfGtk* parent_shelf,
BaseDownloadItemModel* download_item_model);
- // We put |hbox_| in |parent_shelf| and rely on |parent_shelf| recursively
- // destroying its children. Hence we do nothing in the destructor.
+ // Destroys all widgets belonging to this DownloadItemGtk.
~DownloadItemGtk();
// DownloadItem::Observer implementation.
@@ -109,11 +109,11 @@ class DownloadItemGtk : public DownloadItem::Observer,
DownloadShelfGtk* parent_shelf_;
// The widget that contains the body and menu dropdown.
- GtkWidget* hbox_;
+ OwnedWidgetGtk hbox_;
// The widget that contains the name of the download and the progress
// animation.
- GtkWidget* body_;
+ OwnedWidgetGtk body_;
// The GtkLabel that holds the download title text.
GtkWidget* name_label_;
@@ -130,7 +130,7 @@ class DownloadItemGtk : public DownloadItem::Observer,
// The widget that contains the animation progress and the file's icon
// (as well as the complete animation).
- GtkWidget* progress_area_;
+ OwnedWidgetGtk progress_area_;
// In degrees. Only used for downloads with no known total size.
int progress_angle_;
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index 005536e..ab5e4c3 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -7,8 +7,10 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/gfx/gtk_util.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_util.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/download_item_gtk.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
@@ -47,13 +49,8 @@ const int kShelfAnimationDurationMs = 120;
} // namespace
-// static
-DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
- return new DownloadShelfGtk(tab_contents);
-}
-
-DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
- : DownloadShelf(tab_contents),
+DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent)
+ : DownloadShelf(browser),
is_showing_(false) {
// Logically, the shelf is a vbox that contains two children: a one pixel
// tall event box, which serves as the top border, and an hbox, which holds
@@ -69,8 +66,8 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
gtk_widget_modify_bg(top_border, GTK_STATE_NORMAL, &kBorderColor);
// Create |hbox_|.
- hbox_ = gtk_hbox_new(FALSE, kDownloadItemPadding);
- gtk_widget_set_size_request(hbox_, -1, kDownloadItemHeight);
+ hbox_.Own(gtk_hbox_new(FALSE, kDownloadItemPadding));
+ gtk_widget_set_size_request(hbox_.get(), -1, kDownloadItemHeight);
// Get the padding and background color for |hbox_| right.
GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
@@ -79,7 +76,7 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
kTopBottomPadding - 1, kTopBottomPadding, kLeftPadding, kRightPadding);
GtkWidget* padding_bg = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(padding_bg), padding);
- gtk_container_add(GTK_CONTAINER(padding), hbox_);
+ gtk_container_add(GTK_CONTAINER(padding), hbox_.get());
gtk_widget_modify_bg(padding_bg, GTK_STATE_NORMAL, &kBackgroundColor);
shelf_.Own(gtk_vbox_new(FALSE, 0));
@@ -88,7 +85,7 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
// Create and pack the close button.
close_button_.reset(CustomDrawButton::CloseButton());
- gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0);
+ gtk_util::CenterWidgetInHBox(hbox_.get(), close_button_->widget(), true, 0);
g_signal_connect(close_button_->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
@@ -112,16 +109,16 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
link_hbox_ = gtk_hbox_new(FALSE, 5);
gtk_util::CenterWidgetInHBox(link_hbox_, download_image, false, 0);
gtk_util::CenterWidgetInHBox(link_hbox_, link_button, false, 0);
- gtk_box_pack_end(GTK_BOX(hbox_), link_hbox_, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(hbox_.get()), link_hbox_, FALSE, FALSE, 0);
slide_widget_.reset(new SlideAnimatorGtk(shelf_.get(),
SlideAnimatorGtk::UP,
kShelfAnimationDurationMs,
false, NULL));
gtk_widget_show_all(shelf_.get());
- // Stick ourselves at the bottom of the parent tab contents.
- GtkWidget* parent_contents = tab_contents->GetNativeView();
- gtk_box_pack_end(GTK_BOX(parent_contents), slide_widget_->widget(),
+
+ // Stick ourselves at the bottom of the parent browser.
+ gtk_box_pack_end(GTK_BOX(parent), slide_widget_->widget(),
FALSE, FALSE, 0);
slide_widget_->Open();
}
@@ -133,11 +130,12 @@ DownloadShelfGtk::~DownloadShelfGtk() {
}
shelf_.Destroy();
+ hbox_.Destroy();
}
void DownloadShelfGtk::AddDownload(BaseDownloadItemModel* download_model_) {
download_items_.push_back(new DownloadItemGtk(this, download_model_));
- slide_widget_->Open();
+ Show();
}
bool DownloadShelfGtk::IsShowing() const {
@@ -148,6 +146,21 @@ bool DownloadShelfGtk::IsClosing() const {
return slide_widget_->IsClosing();
}
+void DownloadShelfGtk::Show() {
+ slide_widget_->Open();
+}
+
+void DownloadShelfGtk::Close() {
+ slide_widget_->Close();
+
+ // TODO(estade): Remove. The status bubble should query its window instead.
+ browser_->UpdateDownloadShelfVisibility(false);
+}
+
+int DownloadShelfGtk::GetHeight() const {
+ return slide_widget_->widget()->allocation.height;
+}
+
void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) {
DCHECK(download_item);
std::vector<DownloadItemGtk*>::iterator i =
@@ -157,7 +170,9 @@ void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) {
delete download_item;
if (download_items_.empty()) {
slide_widget_->CloseWithoutAnimation();
- tab_contents_->SetDownloadShelfVisible(false);
+
+ // TODO(estade): Remove. The status bubble should query its window instead.
+ browser_->UpdateDownloadShelfVisibility(false);
}
}
@@ -166,15 +181,14 @@ GtkWidget* DownloadShelfGtk::GetRightBoundingWidget() const {
}
GtkWidget* DownloadShelfGtk::GetHBox() const {
- return hbox_;
+ return hbox_.get();
}
// static
void DownloadShelfGtk::OnButtonClick(GtkWidget* button,
DownloadShelfGtk* shelf) {
if (button == shelf->close_button_->widget()) {
- shelf->slide_widget_->Close();
- shelf->tab_contents_->SetDownloadShelfVisible(false);
+ shelf->Close();
} else {
// The link button was clicked.
shelf->ShowAllDownloads();
diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h
index 4ed81b7..afafd27 100644
--- a/chrome/browser/gtk/download_shelf_gtk.h
+++ b/chrome/browser/gtk/download_shelf_gtk.h
@@ -9,18 +9,20 @@
#include <vector>
+#include "base/gfx/native_widget_types.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/common/owned_widget_gtk.h"
class BaseDownloadItemModel;
+class Browser;
class CustomDrawButton;
class DownloadItemGtk;
class SlideAnimatorGtk;
class DownloadShelfGtk : public DownloadShelf {
public:
- explicit DownloadShelfGtk(TabContents* tab_contents);
+ explicit DownloadShelfGtk(Browser* browser, gfx::NativeView view);
~DownloadShelfGtk();
@@ -28,6 +30,11 @@ class DownloadShelfGtk : public DownloadShelf {
virtual void AddDownload(BaseDownloadItemModel* download_model);
virtual bool IsShowing() const;
virtual bool IsClosing() const;
+ virtual void Show();
+ virtual void Close();
+
+ // Returns the current height of the shelf.
+ int GetHeight() const;
private:
// Remove |download_item| from the download shelf and delete it.
@@ -45,7 +52,7 @@ class DownloadShelfGtk : public DownloadShelf {
scoped_ptr<SlideAnimatorGtk> slide_widget_;
// |hbox_| holds the download items and buttons of the shelf.
- GtkWidget* hbox_;
+ OwnedWidgetGtk hbox_;
// |shelf_| is the second highest level widget. See the constructor
// for an explanation of the widget layout.
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index c2a3be6..87920c3 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -91,9 +91,6 @@ TabRendererGtk::TabImage TabRendererGtk::tab_alpha = {0};
TabRendererGtk::TabImage TabRendererGtk::tab_hover_ = {0};
gfx::Font* TabRendererGtk::title_font_ = NULL;
int TabRendererGtk::title_font_height_ = 0;
-SkBitmap* TabRendererGtk::download_icon_ = NULL;
-int TabRendererGtk::download_icon_width_ = 0;
-int TabRendererGtk::download_icon_height_ = 0;
int TabRendererGtk::close_button_width_ = 0;
int TabRendererGtk::close_button_height_ = 0;
@@ -173,7 +170,6 @@ class TabRendererGtk::FavIconCrashAnimation : public Animation,
TabRendererGtk::TabRendererGtk()
: showing_icon_(false),
- showing_download_icon_(false),
showing_close_button_(false),
fav_icon_hiding_offset_(0),
should_display_crashed_favicon_(false),
@@ -200,7 +196,6 @@ void TabRendererGtk::UpdateData(TabContents* contents, bool loading_only) {
if (!loading_only) {
data_.title = UTF16ToWideHack(contents->GetTitle());
data_.off_the_record = contents->profile()->IsOffTheRecord();
- data_.show_download_icon = contents->IsDownloadShelfVisible();
data_.crashed = contents->is_crashed();
data_.favicon = contents->GetFavIcon();
}
@@ -303,10 +298,6 @@ void TabRendererGtk::LoadTabImages() {
close_button_width_ = rb.GetBitmapNamed(IDR_TAB_CLOSE)->width();
close_button_height_ = rb.GetBitmapNamed(IDR_TAB_CLOSE)->height();
-
- download_icon_ = rb.GetBitmapNamed(IDR_DOWNLOAD_ICON);
- download_icon_width_ = download_icon_->width();
- download_icon_height_ = download_icon_->height();
}
void TabRendererGtk::SetBounds(const gfx::Rect& bounds) {
@@ -378,10 +369,8 @@ void TabRendererGtk::Paint(gfx::Canvas* canvas) {
// See if the model changes whether the icons should be painted.
const bool show_icon = ShouldShowIcon();
- const bool show_download_icon = data_.show_download_icon;
const bool show_close_button = ShouldShowCloseBox();
if (show_icon != showing_icon_ ||
- show_download_icon != showing_download_icon_ ||
show_close_button != showing_close_button_)
Layout();
@@ -418,11 +407,6 @@ void TabRendererGtk::Paint(gfx::Canvas* canvas) {
}
}
- if (show_download_icon) {
- canvas->DrawBitmapInt(*download_icon_,
- download_icon_bounds_.x(), download_icon_bounds_.y());
- }
-
// Paint the Title.
std::wstring title = data_.title;
if (title.empty()) {
@@ -475,15 +459,6 @@ void TabRendererGtk::Layout() {
favicon_bounds_.SetRect(local_bounds.x(), local_bounds.y(), 0, 0);
}
- // Size the download icon.
- showing_download_icon_ = data_.show_download_icon;
- if (showing_download_icon_) {
- int icon_top = kTopPadding + (content_height - download_icon_height_) / 2;
- download_icon_bounds_.SetRect(local_bounds.width() - download_icon_width_,
- icon_top, download_icon_width_,
- download_icon_height_);
- }
-
// Size the Close button.
showing_close_button_ = ShouldShowCloseBox();
if (showing_close_button_) {
@@ -518,8 +493,6 @@ void TabRendererGtk::Layout() {
} else {
title_width = std::max(local_bounds.width() - title_left, 0);
}
- if (data_.show_download_icon)
- title_width = std::max(title_width - download_icon_width_, 0);
title_bounds_.SetRect(title_left, title_top, title_width, title_font_height_);
// TODO(jhawkins): Handle RTL layout.
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
index 4f555a1..990081f 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
@@ -161,7 +161,6 @@ class TabRendererGtk : public AnimationDelegate {
bool crashed;
bool off_the_record;
bool show_icon;
- bool show_download_icon;
};
// TODO(jhawkins): Move into TabResources class.
@@ -238,7 +237,6 @@ class TabRendererGtk : public AnimationDelegate {
// The bounds of various sections of the display.
gfx::Rect favicon_bounds_;
- gfx::Rect download_icon_bounds_;
gfx::Rect title_bounds_;
gfx::Rect close_button_bounds_;
@@ -252,10 +250,6 @@ class TabRendererGtk : public AnimationDelegate {
static gfx::Font* title_font_;
static int title_font_height_;
- static SkBitmap* download_icon_;
- static int download_icon_width_;
- static int download_icon_height_;
-
static int close_button_width_;
static int close_button_height_;
@@ -266,9 +260,6 @@ class TabRendererGtk : public AnimationDelegate {
// changes and layout appropriately.
bool showing_icon_;
- // Whether we are showing the download icon. Comes from the model.
- bool showing_download_icon_;
-
// Whether we are showing the close button. It is cached so that we can
// detect when it changes and layout appropriately.
bool showing_close_button_;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc
index f9d51d7..09a8833 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host_uitest.cc
@@ -68,11 +68,8 @@ TEST_F(ResourceDispatcherTest, SniffNoContentTypeNoData) {
// Make sure the download shelf is not showing.
scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
- scoped_refptr<TabProxy> dl_tab(browser->GetTab(0));
- ASSERT_TRUE(dl_tab.get());
-
bool visible = false;
- ASSERT_TRUE(dl_tab->IsShelfVisible(&visible));
+ ASSERT_TRUE(browser->IsShelfVisible(&visible));
EXPECT_FALSE(visible);
}
@@ -155,10 +152,12 @@ TEST_F(ResourceDispatcherTest, SyncXMLHttpRequest_DuringUnload) {
EXPECT_FALSE(timed_out);
// Check that the new page got loaded, and that no download was triggered.
- bool shelf_is_visible = false;
EXPECT_TRUE(tab->GetTabTitle(&tab_title));
- EXPECT_TRUE(tab->IsShelfVisible(&shelf_is_visible));
EXPECT_EQ(L"Title Of Awesomeness", tab_title);
+
+ bool shelf_is_visible = false;
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ EXPECT_TRUE(browser->IsShelfVisible(&shelf_is_visible));
EXPECT_FALSE(shelf_is_visible);
}
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 3e15f10..4bc4366 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -21,8 +21,6 @@
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_request_manager.h"
-#include "chrome/browser/download/download_shelf.h"
-#include "chrome/browser/download/download_started_animation.h"
#include "chrome/browser/gears_integration.h"
#include "chrome/browser/google_util.h"
#include "chrome/browser/hung_renderer_dialog.h"
@@ -43,7 +41,6 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/page_action.h"
-#include "chrome/common/platform_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/render_messages.h"
@@ -115,10 +112,6 @@ const int kSyncWaitDelay = 40;
// contents.
const int kJavascriptMessageExpectedDelay = 1000;
-// Minimum amount of time in ms that has to elapse since the download shelf was
-// shown for us to hide it when navigating away from the current page.
-const int kDownloadShelfHideDelay = 5000;
-
const char kLinkDoctorBaseURL[] =
"http://linkhelp.clients.google.com/tbproxy/lh/fixurl";
@@ -235,11 +228,8 @@ TabContents::TabContents(Profile* profile,
is_starred_(false),
contents_mime_type_(),
encoding_(),
- download_shelf_(),
- shelf_visible_(false),
blocked_popups_(NULL),
infobar_delegates_(),
- last_download_shelf_show_(),
find_ui_active_(false),
find_op_aborted_(false),
current_find_request_id_(find_request_id_counter_++),
@@ -926,32 +916,6 @@ bool TabContents::IsBookmarkBarAlwaysVisible() {
return false; // Default.
}
-void TabContents::SetDownloadShelfVisible(bool visible) {
- if (shelf_visible_ != visible) {
- if (visible) {
- // Invoke GetDownloadShelf to force the shelf to be created.
- GetDownloadShelf(true);
- }
- shelf_visible_ = visible;
-
- NotifyNavigationStateChanged(INVALIDATE_TAB);
-
- if (delegate())
- delegate()->UpdateDownloadShelfVisibility(visible);
- }
-
- // SetShelfVisible can force-close the shelf, so make sure we lay out
- // everything correctly, as if the animation had finished. This doesn't
- // matter for showing the shelf, as the show animation will do it.
- ToolbarSizeChanged(false);
-
- if (visible) {
- // Always set this value as it reflects the last time the download shelf
- // was made visible (even if it was already visible).
- last_download_shelf_show_ = base::TimeTicks::Now();
- }
-}
-
void TabContents::ToolbarSizeChanged(bool is_animating) {
TabContentsDelegate* d = delegate();
if (d)
@@ -964,42 +928,8 @@ void TabContents::OnStartDownload(DownloadItem* download) {
// Download in a constrained popup is shown in the tab that opened it.
TabContents* tab_contents = delegate()->GetConstrainingContents(this);
- // GetDownloadShelf creates the download shelf if it was not yet created.
- tab_contents->GetDownloadShelf(true)->AddDownload(
- new DownloadItemModel(download));
- tab_contents->SetDownloadShelfVisible(true);
-
-// TODO(port): port for mac.
-#if defined(OS_WIN) || defined(OS_LINUX)
- // We make this check for the case of minimized windows, unit tests, etc.
- if (platform_util::IsVisible(GetNativeView())) {
- DownloadStartedAnimation::Show(tab_contents);
- }
-#endif
-}
-
-DownloadShelf* TabContents::GetDownloadShelf(bool create) {
- if (!download_shelf_.get() && create)
- download_shelf_.reset(DownloadShelf::Create(this));
- return download_shelf_.get();
-}
-
-void TabContents::MigrateShelfFrom(TabContents* tab_contents) {
- download_shelf_.reset(tab_contents->GetDownloadShelf(true));
- download_shelf_->ChangeTabContents(tab_contents, this);
- tab_contents->ReleaseDownloadShelf();
-}
-
-void TabContents::ReleaseDownloadShelf() {
- download_shelf_.release();
-}
-
-// static
-void TabContents::MigrateShelf(TabContents* from, TabContents* to) {
- bool was_shelf_visible = from->IsDownloadShelfVisible();
- if (was_shelf_visible)
- to->MigrateShelfFrom(from);
- to->SetDownloadShelfVisible(was_shelf_visible);
+ if (tab_contents && tab_contents->delegate())
+ tab_contents->delegate()->OnStartDownload(download);
}
void TabContents::WillClose(ConstrainedWindow* window) {
@@ -1296,27 +1226,6 @@ DOMUI* TabContents::GetDOMUIForCurrentState() {
void TabContents::DidNavigateMainFramePostCommit(
const NavigationController::LoadCommittedDetails& details,
const ViewHostMsg_FrameNavigate_Params& params) {
- // Hide the download shelf if all the following conditions are true:
- // - there are no active downloads.
- // - this is a navigation to a different TLD.
- // - at least 5 seconds have elapsed since the download shelf was shown.
- // TODO(jcampan): bug 1156075 when user gestures are reliable, they should
- // be used to ensure we are hiding only on user initiated
- // navigations.
- DownloadManager* download_manager = profile()->GetDownloadManager();
- // download_manager can be NULL in unit test context.
- if (download_manager && download_manager->in_progress_count() == 0 &&
- !details.previous_url.is_empty() &&
- !net::RegistryControlledDomainService::SameDomainOrHost(
- details.previous_url, details.entry->url())) {
- base::TimeDelta time_delta(
- base::TimeTicks::Now() - last_download_shelf_show_);
- if (time_delta >
- base::TimeDelta::FromMilliseconds(kDownloadShelfHideDelay)) {
- SetDownloadShelfVisible(false);
- }
- }
-
if (details.is_user_initiated_main_frame_load()) {
// Clear the status bubble. This is a workaround for a bug where WebKit
// doesn't let us know that the cursor left an element during a
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index c43a919..026cf3d 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -66,7 +66,6 @@ class BlockedPopupContainer;
class DOMUI;
class DOMUIContents;
class DownloadItem;
-class DownloadShelf;
class LoadNotificationDetails;
class PageAction;
class PasswordManager;
@@ -405,30 +404,12 @@ class TabContents : public PageNavigator,
// Returns whether the bookmark bar should be visible.
virtual bool IsBookmarkBarAlwaysVisible();
- // Whether or not the shelf view is visible.
- virtual void SetDownloadShelfVisible(bool visible);
- bool IsDownloadShelfVisible() { return shelf_visible_; }
+ // Notifies the delegate that a download started.
+ void OnStartDownload(DownloadItem* download);
// Notify our delegate that some of our content has animated.
void ToolbarSizeChanged(bool is_animating);
- // Displays the download shelf and animation when a download occurs.
- void OnStartDownload(DownloadItem* download);
-
- // Returns the DownloadShelf. If the shelf doesn't exist and |create| is true,
- // this function will create the shelf.
- DownloadShelf* GetDownloadShelf(bool create);
-
- // Transfer the shelf view from |tab_contents| to the receiving TabContents.
- // |tab_contents| no longer owns the shelf after this call. The shelf is owned
- // by the receiving TabContents.
- void MigrateShelfFrom(TabContents* tab_contents);
-
- // Migrate the shelf view between 2 TabContents. This helper function is
- // currently called by NavigationController::DiscardPendingEntry. We may
- // want to generalize this if we need to migrate some other state.
- static void MigrateShelf(TabContents* from, TabContents* to);
-
// Called when a ConstrainedWindow we own is about to be closed.
void WillClose(ConstrainedWindow* window);
@@ -641,9 +622,6 @@ class TabContents : public PageNavigator,
// determines whether to show itself).
bool ShowingBlockedPopupNotification() const;
- // Releases the download shelf. This method is used by MigrateShelfFrom.
- void ReleaseDownloadShelf();
-
// Called by derived classes to indicate that we're no longer waiting for a
// response. This won't actually update the throbber, but it will get picked
// up at the next animation step if the throbber is going.
@@ -992,12 +970,6 @@ class TabContents : public PageNavigator,
// Data for shelves and stuff ------------------------------------------------
- // The download shelf view (view at the bottom of the page).
- scoped_ptr<DownloadShelf> download_shelf_;
-
- // Whether the shelf view is visible.
- bool shelf_visible_;
-
// ConstrainedWindow with additional methods for managing blocked
// popups. This pointer also goes in |child_windows_| for ownership,
// repositioning, etc.
@@ -1006,9 +978,6 @@ class TabContents : public PageNavigator,
// Delegates for InfoBars associated with this TabContents.
std::vector<InfoBarDelegate*> infobar_delegates_;
- // The last time that the download shelf was made visible.
- base::TimeTicks last_download_shelf_show_;
-
// Data for find in page -----------------------------------------------------
// TODO(brettw) this should be separated into a helper class.
diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h
index 465877f..da5bd60 100644
--- a/chrome/browser/tab_contents/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents/tab_contents_delegate.h
@@ -11,6 +11,7 @@
#include "chrome/common/page_transition_types.h"
#include "webkit/glue/window_open_disposition.h"
+class DownloadItem;
class ExtensionFunctionDispatcher;
class RenderViewHost;
class TabContents;
@@ -89,9 +90,6 @@ class TabContentsDelegate {
// Notification that the target URL has changed
virtual void UpdateTargetURL(TabContents* source, const GURL& url) = 0;
- // Notification that the download shelf visibility state has been toggled.
- virtual void UpdateDownloadShelfVisibility(bool visible) { }
-
// Notification that there was a mouse event
virtual void ContentsMouseEvent(TabContents* source, bool motion) { }
@@ -178,6 +176,9 @@ class TabContentsDelegate {
return 0;
}
+ virtual void OnStartDownload(DownloadItem* download) {
+ }
+
protected:
~TabContentsDelegate() {}
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index 174b7e7..5103bc0 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -98,12 +98,10 @@ TabContentsView* TabContentsView::Create(TabContents* tab_contents) {
TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
: TabContentsView(tab_contents),
- vbox_(gtk_vbox_new(FALSE, 0)) {
- fixed_ = gtk_fixed_new();
- gtk_box_pack_start(GTK_BOX(vbox_.get()), fixed_, TRUE, TRUE, 0);
- g_signal_connect(fixed_, "size-allocate",
+ fixed_(gtk_fixed_new()) {
+ g_signal_connect(fixed_.get(), "size-allocate",
G_CALLBACK(OnSizeAllocate), this);
- gtk_widget_show(fixed_);
+ gtk_widget_show(fixed_.get());
registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
Source<TabContents>(tab_contents));
registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
@@ -111,7 +109,7 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
}
TabContentsViewGtk::~TabContentsViewGtk() {
- vbox_.Destroy();
+ fixed_.Destroy();
}
void TabContentsViewGtk::CreateView() {
@@ -153,7 +151,7 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
}
gfx::NativeView TabContentsViewGtk::GetNativeView() const {
- return vbox_.get();
+ return fixed_.get();
}
gfx::NativeView TabContentsViewGtk::GetContentNativeView() const {
@@ -175,10 +173,10 @@ void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const {
// animation.
int x = 0;
int y = 0;
- if (vbox_.get()->window)
- gdk_window_get_origin(vbox_.get()->window, &x, &y);
- out->SetRect(x + vbox_.get()->allocation.x, y + vbox_.get()->allocation.y,
- vbox_.get()->allocation.width, vbox_.get()->allocation.height);
+ if (fixed_.get()->window)
+ gdk_window_get_origin(fixed_.get()->window, &x, &y);
+ out->SetRect(x + fixed_.get()->allocation.x, y + fixed_.get()->allocation.y,
+ fixed_.get()->allocation.width, fixed_.get()->allocation.height);
}
void TabContentsViewGtk::OnContentsDestroy() {
@@ -304,7 +302,7 @@ void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) {
}
void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) {
- gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0);
+ gtk_fixed_put(GTK_FIXED(fixed_.get()), widget, 0, 0);
}
gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget,
@@ -317,9 +315,7 @@ gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
GtkAllocation* allocation,
TabContentsViewGtk* view) {
int width = allocation->width;
- DownloadShelf* shelf = view->tab_contents()->GetDownloadShelf(false);
- int height = shelf && shelf->IsClosing() ?
- widget->parent->allocation.height : allocation->height;
+ int height = allocation->height;
height += view->tab_contents()->delegate()->GetExtraRenderViewHeight();
gfx::Size size(width, height);
gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size);
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 9e6fdc4..b6908ff 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -74,12 +74,9 @@ class TabContentsViewGtk : public TabContentsView,
GtkAllocation* config,
TabContentsViewGtk* view);
- // The native widget for the tab.
- OwnedWidgetGtk vbox_;
-
// This container holds the tab's web page views. It is a GtkFixed so that we
// can control the size of the web pages.
- GtkWidget* fixed_;
+ OwnedWidgetGtk fixed_;
// The context menu is reset every time we show it, but we keep a pointer to
// between uses so that it won't go out of scope before we're done with it.
diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc
index fcf01df..d651548 100644
--- a/chrome/browser/views/download_shelf_view.cc
+++ b/chrome/browser/views/download_shelf_view.cc
@@ -10,12 +10,13 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/logging.h"
+#include "chrome/browser/browser.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/download_item_view.h"
+#include "chrome/browser/views/frame/browser_view.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/background.h"
@@ -70,13 +71,9 @@ int CenterPosition(int size, int target_size) {
} // namespace
-// static
-DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
- return new DownloadShelfView(tab_contents);
-}
-
-DownloadShelfView::DownloadShelfView(TabContents* tab_contents)
- : DownloadShelf(tab_contents) {
+DownloadShelfView::DownloadShelfView(Browser* browser, BrowserView* parent)
+ : DownloadShelf(browser), parent_(parent) {
+ parent->AddChildView(this);
Init();
}
@@ -105,14 +102,11 @@ void DownloadShelfView::Init() {
shelf_animation_.reset(new SlideAnimation(this));
shelf_animation_->SetSlideDuration(kShelfAnimationDurationMs);
- shelf_animation_->Show();
-
- // The download shelf view is always owned by its tab contents.
- SetParentOwned(false);
+ Show();
}
void DownloadShelfView::AddDownloadView(View* view) {
- shelf_animation_->Show();
+ Show();
DCHECK(view);
download_views_.push_back(view);
@@ -139,7 +133,7 @@ void DownloadShelfView::RemoveDownloadView(View* view) {
RemoveChildView(view);
delete view;
if (download_views_.empty())
- tab_contents_->SetDownloadShelfVisible(false);
+ Close();
Layout();
SchedulePaint();
}
@@ -182,26 +176,18 @@ void DownloadShelfView::AnimationProgressed(const Animation *animation) {
// otherwise leave blank white areas where the shelf was and where the
// user's eye is. Thankfully bottom-resizing is a lot faster than
// top-resizing.
- tab_contents_->ToolbarSizeChanged(shelf_animation_->IsShowing());
+ parent_->SelectedTabToolbarSizeChanged(shelf_animation_->IsShowing());
}
}
void DownloadShelfView::AnimationEnded(const Animation *animation) {
if (animation == shelf_animation_.get()) {
- tab_contents_->SetDownloadShelfVisible(shelf_animation_->IsShowing());
+ if (download_views_.empty())
+ parent_->SetDownloadShelfVisible(shelf_animation_->IsShowing());
}
}
void DownloadShelfView::Layout() {
- // When the download shelf is not visible it is not parented to anything,
- // which means it is not safe to lay out the controls, so we return early.
- // Otherwise, we can have problems when for example the user switches to
- // another tab (that doesn't have a download shelf) _before_ the download
- // has started and we'll crash when calling SetVisible() below because
- // the NativeControlContainer ctor tries to use the Container.
- if (!GetWidget())
- return;
-
// Now that we know we have a parent, we can safely set our theme colors.
show_all_view_->SetColor(
GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT));
@@ -301,7 +287,7 @@ void DownloadShelfView::LinkActivated(views::Link* source, int event_flags) {
}
void DownloadShelfView::ButtonPressed(views::Button* button) {
- shelf_animation_->Hide();
+ Close();
}
bool DownloadShelfView::IsShowing() const {
@@ -312,3 +298,12 @@ bool DownloadShelfView::IsClosing() const {
// TODO(estade): This is never called. For now just return false.
return false;
}
+
+void DownloadShelfView::Show() {
+ shelf_animation_->Show();
+}
+
+void DownloadShelfView::Close() {
+ parent_->SetDownloadShelfVisible(false);
+ shelf_animation_->Hide();
+}
diff --git a/chrome/browser/views/download_shelf_view.h b/chrome/browser/views/download_shelf_view.h
index 0b722b8..e11d468 100644
--- a/chrome/browser/views/download_shelf_view.h
+++ b/chrome/browser/views/download_shelf_view.h
@@ -16,7 +16,8 @@ class ImageView;
}
class BaseDownloadItemModel;
-class TabContents;
+class Browser;
+class BrowserView;
class DownloadAnimation;
@@ -33,7 +34,7 @@ class DownloadShelfView : public DownloadShelf,
public views::LinkController,
public AnimationDelegate {
public:
- explicit DownloadShelfView(TabContents* tab_contents);
+ explicit DownloadShelfView(Browser* browser, BrowserView* parent);
// Implementation of View.
virtual gfx::Size GetPreferredSize();
@@ -57,6 +58,8 @@ class DownloadShelfView : public DownloadShelf,
virtual void AddDownload(BaseDownloadItemModel* download_model);
virtual bool IsShowing() const;
virtual bool IsClosing() const;
+ virtual void Show();
+ virtual void Close();
// Removes a specified download view. The supplied view is deleted after
// it's removed.
@@ -97,6 +100,9 @@ class DownloadShelfView : public DownloadShelf,
// deleted by View.
views::ImageButton* close_button_;
+ // The window this shelf belongs to.
+ BrowserView* parent_;
+
DISALLOW_COPY_AND_ASSIGN(DownloadShelfView);
};
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 078faac..9d41882 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -300,9 +300,9 @@ BrowserView::BrowserView(Browser* browser)
frame_(NULL),
browser_(browser),
active_bookmark_bar_(NULL),
- active_download_shelf_(NULL),
tabstrip_(NULL),
toolbar_(NULL),
+ download_shelf_(NULL),
infobar_container_(NULL),
find_bar_y_(0),
contents_container_(NULL),
@@ -818,11 +818,8 @@ gfx::Rect BrowserView::GetRootWindowResizerRect() const {
// shelf, so we don't want others to do it for us in this case.
// Currently, the only visible bottom shelf is the download shelf.
// Other tests should be added here if we add more bottom shelves.
- TabContents* current_tab = browser_->GetSelectedTabContents();
- if (current_tab && current_tab->IsDownloadShelfVisible()) {
- DownloadShelf* download_shelf = current_tab->GetDownloadShelf(true);
- if (download_shelf && download_shelf->IsShowing())
- return gfx::Rect();
+ if (download_shelf_ && download_shelf_->IsShowing()) {
+ return gfx::Rect();
}
gfx::Rect client_rect = contents_container_->bounds();
@@ -854,6 +851,32 @@ void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
toolbar_->star_button()->ShowStarBubble(url, !already_bookmarked);
}
+void BrowserView::SetDownloadShelfVisible(bool visible) {
+ if (IsDownloadShelfVisible() != visible) {
+ if (visible) {
+ // Invoke GetDownloadShelf to force the shelf to be created.
+ GetDownloadShelf();
+ }
+
+ browser_->UpdateDownloadShelfVisibility(visible);
+ }
+
+ // SetDownloadShelfVisible can force-close the shelf, so make sure we lay out
+ // everything correctly, as if the animation had finished. This doesn't
+ // matter for showing the shelf, as the show animation will do it.
+ SelectedTabToolbarSizeChanged(false);
+}
+
+bool BrowserView::IsDownloadShelfVisible() const {
+ return download_shelf_ && download_shelf_->IsShowing();
+}
+
+DownloadShelf* BrowserView::GetDownloadShelf() {
+ if (!download_shelf_)
+ download_shelf_ = new DownloadShelfView(browser_.get(), this);
+ return download_shelf_;
+}
+
void BrowserView::ShowReportBugDialog() {
// Retrieve the URL for the current tab (if any) and tell the BugReportView
TabContents* current_tab = browser_->GetSelectedTabContents();
@@ -1451,14 +1474,14 @@ void BrowserView::LayoutTabContents(int top, int bottom) {
}
int BrowserView::LayoutDownloadShelf(int bottom) {
- if (active_download_shelf_) {
+ if (IsDownloadShelfVisible()) {
bool visible = browser_->SupportsWindowFeature(
Browser::FEATURE_DOWNLOADSHELF);
- int height =
- visible ? active_download_shelf_->GetPreferredSize().height() : 0;
- active_download_shelf_->SetVisible(visible);
- active_download_shelf_->SetBounds(0, bottom - height, width(), height);
- active_download_shelf_->Layout();
+ DCHECK(download_shelf_);
+ int height = visible ? download_shelf_->GetPreferredSize().height() : 0;
+ download_shelf_->SetVisible(visible);
+ download_shelf_->SetBounds(0, bottom - height, width(), height);
+ download_shelf_->Layout();
bottom -= height;
}
return bottom;
@@ -1514,21 +1537,9 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) {
return true;
}
-bool BrowserView::MaybeShowDownloadShelf(TabContents* contents) {
- views::View* new_shelf = NULL;
- if (contents && contents->IsDownloadShelfVisible()) {
- new_shelf =
- static_cast<DownloadShelfView*>(contents->GetDownloadShelf(true));
- if (new_shelf != active_download_shelf_)
- new_shelf->AddChildView(new ResizeCorner());
- }
- return UpdateChildViewAndLayout(new_shelf, &active_download_shelf_);
-}
-
void BrowserView::UpdateUIForContents(TabContents* contents) {
bool needs_layout = MaybeShowBookmarkBar(contents);
needs_layout |= MaybeShowInfoBar(contents);
- needs_layout |= MaybeShowDownloadShelf(contents);
if (needs_layout)
Layout();
}
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index f4c0983..98d1e56 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -28,6 +28,7 @@ class BookmarkBarView;
class Browser;
class BrowserBubble;
class BrowserToolbarView;
+class DownloadShelfView;
class EncodingMenuControllerDelegate;
class ExtensionShelf;
class FullscreenExitBubble;
@@ -215,6 +216,9 @@ class BrowserView : public BrowserWindow,
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
+ virtual void SetDownloadShelfVisible(bool visible);
+ virtual bool IsDownloadShelfVisible() const;
+ virtual DownloadShelf* GetDownloadShelf();
virtual void ShowReportBugDialog();
virtual void ShowClearBrowsingDataDialog();
virtual void ShowImportDialog();
@@ -317,12 +321,6 @@ class BrowserView : public BrowserWindow,
// |contents| can be NULL.
bool MaybeShowInfoBar(TabContents* contents);
- // Prepare to show a Download Shelf for the specified TabContents. Returns
- // true if there is a Download Shelf to show and one is supported for this
- // Browser type, and there should be a subsequent re-layout to show it.
- // |contents| can be NULL.
- bool MaybeShowDownloadShelf(TabContents* contents);
-
// Updates various optional child Views, e.g. Bookmarks Bar, Info Bar or the
// Download Shelf in response to a change notification from the specified
// |contents|. |contents| can be NULL. In this case, all optional UI will be
@@ -365,7 +363,6 @@ class BrowserView : public BrowserWindow,
// active_bookmark_bar_ is either NULL, if the bookmark bar isn't showing,
// or is bookmark_bar_view_ if the bookmark bar is showing.
views::View* active_bookmark_bar_;
- views::View* active_download_shelf_;
// The TabStrip.
TabStrip* tabstrip_;
@@ -376,6 +373,9 @@ class BrowserView : public BrowserWindow,
// The Bookmark Bar View for this window. Lazily created.
scoped_ptr<BookmarkBarView> bookmark_bar_view_;
+ // The download shelf view (view at the bottom of the page).
+ DownloadShelfView* download_shelf_;
+
// The InfoBarContainer that contains InfoBars for the current tab.
InfoBarContainer* infobar_container_;
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index c270f20..fefae85 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -65,9 +65,6 @@ static SkBitmap* crashed_fav_icon = NULL;
static int loading_animation_frame_count = 0;
static int waiting_animation_frame_count = 0;
static int waiting_to_loading_frame_count_ratio = 0;
-static SkBitmap* download_icon = NULL;
-static int download_icon_width = 0;
-static int download_icon_height = 0;
TabRenderer::TabImage TabRenderer::tab_alpha = {0};
TabRenderer::TabImage TabRenderer::tab_active = {0};
@@ -138,10 +135,6 @@ void InitResources() {
crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON);
- download_icon = rb.GetBitmapNamed(IDR_DOWNLOAD_ICON);
- download_icon_width = download_icon->width();
- download_icon_height = download_icon->height();
-
initialized = true;
}
}
@@ -237,7 +230,6 @@ TabRenderer::TabRenderer()
: animation_state_(ANIMATION_NONE),
animation_frame_(0),
showing_icon_(false),
- showing_download_icon_(false),
showing_close_button_(false),
fav_icon_hiding_offset_(0),
crash_animation_(NULL),
@@ -286,7 +278,6 @@ void TabRenderer::UpdateData(TabContents* contents, bool loading_only) {
if (!loading_only) {
data_.title = UTF16ToWideHack(contents->GetTitle());
data_.off_the_record = contents->profile()->IsOffTheRecord();
- data_.show_download_icon = contents->IsDownloadShelfVisible();
data_.crashed = contents->is_crashed();
data_.favicon = contents->GetFavIcon();
}
@@ -400,10 +391,8 @@ void TabRenderer::Paint(gfx::Canvas* canvas) {
// See if the model changes whether the icons should be painted.
const bool show_icon = ShouldShowIcon();
- const bool show_download_icon = data_.show_download_icon;
const bool show_close_button = ShouldShowCloseBox();
if (show_icon != showing_icon_ ||
- show_download_icon != showing_download_icon_ ||
show_close_button != showing_close_button_)
Layout();
@@ -442,11 +431,6 @@ void TabRenderer::Paint(gfx::Canvas* canvas) {
}
}
- if (show_download_icon) {
- canvas->DrawBitmapInt(*download_icon,
- download_icon_bounds_.x(), download_icon_bounds_.y());
- }
-
// Paint the Title.
std::wstring title = data_.title;
if (title.empty()) {
@@ -487,14 +471,6 @@ void TabRenderer::Layout() {
favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
}
- // Size the download icon.
- showing_download_icon_ = data_.show_download_icon;
- if (showing_download_icon_) {
- int icon_top = kTopPadding + (content_height - download_icon_height) / 2;
- download_icon_bounds_.SetRect(lb.width() - download_icon_width, icon_top,
- download_icon_width, download_icon_height);
- }
-
// Size the Close button.
showing_close_button_ = ShouldShowCloseBox();
if (showing_close_button_) {
@@ -530,21 +506,17 @@ void TabRenderer::Layout() {
} else {
title_width = std::max(lb.width() - title_left, 0);
}
- if (data_.show_download_icon)
- title_width = std::max(title_width - download_icon_width, 0);
title_bounds_.SetRect(title_left, title_top, title_width, title_font_height);
- // Certain UI elements within the Tab (the favicon, the download icon, etc.)
- // are not represented as child Views (which is the preferred method).
- // Instead, these UI elements are drawn directly on the canvas from within
- // Tab::Paint(). The Tab's child Views (for example, the Tab's close button
- // which is a views::Button instance) are automatically mirrored by the
- // mirroring infrastructure in views. The elements Tab draws directly
- // on the canvas need to be manually mirrored if the View's layout is
- // right-to-left.
+ // Certain UI elements within the Tab (the favicon, etc.) are not represented
+ // as child Views (which is the preferred method). Instead, these UI elements
+ // are drawn directly on the canvas from within Tab::Paint(). The Tab's child
+ // Views (for example, the Tab's close button which is a views::Button
+ // instance) are automatically mirrored by the mirroring infrastructure in
+ // views. The elements Tab draws directly on the canvas need to be manually
+ // mirrored if the View's layout is right-to-left.
favicon_bounds_.set_x(MirroredLeftPointForRect(favicon_bounds_));
title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_));
- download_icon_bounds_.set_x(MirroredLeftPointForRect(download_icon_bounds_));
}
void TabRenderer::OnMouseEntered(const views::MouseEvent& e) {
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index 26dc4cd..f0785ab 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -135,7 +135,6 @@ class TabRenderer : public views::View,
// The bounds of various sections of the display.
gfx::Rect favicon_bounds_;
- gfx::Rect download_icon_bounds_;
gfx::Rect title_bounds_;
// Current state of the animation.
@@ -163,7 +162,6 @@ class TabRenderer : public views::View,
bool crashed;
bool off_the_record;
bool show_icon;
- bool show_download_icon;
};
TabData data_;
@@ -183,9 +181,6 @@ class TabRenderer : public views::View,
// changes and layout appropriately.
bool showing_icon_;
- // Whether we are showing the download icon. Comes from the model.
- bool showing_download_icon_;
-
// Whether we are showing the close button. It is cached so that we can
// detect when it changes and layout appropriately.
bool showing_close_button_;