diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 15:21:16 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 15:21:16 +0000 |
commit | f89a6233760f8ca8033265046ed9ea38bbc20bf9 (patch) | |
tree | a438abfbbfd918fd0cff1862ab4b26ce7507484c /chrome/browser | |
parent | f9b05c2dd900aa1850111c4a052db0da6e060a5a (diff) | |
download | chromium_src-f89a6233760f8ca8033265046ed9ea38bbc20bf9.zip chromium_src-f89a6233760f8ca8033265046ed9ea38bbc20bf9.tar.gz chromium_src-f89a6233760f8ca8033265046ed9ea38bbc20bf9.tar.bz2 |
Fixes a couple of bookmark bar bugs:
. The folders on the bookmark bar now fade in like urls.
. You can now middle click on folders to open all URLs.
. If you attempt to open a folder with more than 15 urls we'll prompt
before openning.
BUG=242 529 1295385
TEST=middle click on a folder on the bookmark bar and make sure it
opens all tabs in the background. Try this with a folder containing
more than 15 bookmarks and make sure you get a message box before
asking if you really want to open them all.
Review URL: http://codereview.chromium.org/6020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2756 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/bookmark_bar_context_menu_controller.cc | 108 | ||||
-rw-r--r-- | chrome/browser/bookmark_bar_context_menu_controller.h | 9 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 94 |
4 files changed, 161 insertions, 52 deletions
diff --git a/chrome/browser/bookmark_bar_context_menu_controller.cc b/chrome/browser/bookmark_bar_context_menu_controller.cc index 8bce486..9878df3 100644 --- a/chrome/browser/bookmark_bar_context_menu_controller.cc +++ b/chrome/browser/bookmark_bar_context_menu_controller.cc @@ -18,10 +18,15 @@ #include "chrome/views/view_container.h" #include "chrome/views/window.h" +#include "chromium_strings.h" #include "generated_resources.h" namespace { +// Number of bookmarks we'll open before prompting the user to see if they +// really want to open all. +const int kNumURLsBeforePrompting = 15; + // Returns true if the specified node is of type URL, or has a descendant // of type URL. bool NodeHasURLs(BookmarkNode* node) { @@ -35,49 +40,67 @@ bool NodeHasURLs(BookmarkNode* node) { return false; } -// Opens a tab/window for node and recursively opens all descendants. -// If open_first_in_new_window is true, the first opened node is opened -// in a new window. navigator indicates the PageNavigator to use for -// new tabs. It is reset if open_first_in_new_window is true. -// opened_url is set to true the first time a new tab is opened. -void OpenAll(BookmarkNode* node, - bool open_first_in_new_window, - PageNavigator** navigator, - bool* opened_url) { +// Implementation of OpenAll. Opens all nodes of type URL and recurses for +// groups. +void OpenAllImpl(BookmarkNode* node, + WindowOpenDisposition initial_disposition, + PageNavigator** navigator, + bool* opened_url) { if (node->GetType() == history::StarredEntry::URL) { WindowOpenDisposition disposition; if (*opened_url) disposition = NEW_BACKGROUND_TAB; - else if (open_first_in_new_window) - disposition = NEW_WINDOW; - else // Open in current window. - disposition = CURRENT_TAB; + else + disposition = initial_disposition; (*navigator)->OpenURL(node->GetURL(), disposition, PageTransition::AUTO_BOOKMARK); if (!*opened_url) { *opened_url = true; - if (open_first_in_new_window || disposition == CURRENT_TAB) { - // We opened the tab in a new window or in the current tab which - // likely reset the navigator. Need to reset the page navigator - // appropriately. - Browser* new_browser = BrowserList::GetLastActive(); - if (new_browser) { - TabContents* current_tab = new_browser->GetSelectedTabContents(); - DCHECK(new_browser && current_tab); - if (new_browser && current_tab) - *navigator = current_tab; - } // else, new_browser == NULL, which happens during testing. - } + // We opened the first URL which may have opened a new window or clobbered + // the current page, reset the navigator just to be sure. + Browser* new_browser = BrowserList::GetLastActive(); + if (new_browser) { + TabContents* current_tab = new_browser->GetSelectedTabContents(); + DCHECK(new_browser && current_tab); + if (new_browser && current_tab) + *navigator = current_tab; + } // else, new_browser == NULL, which happens during testing. } } else { // Group, recurse through children. for (int i = 0; i < node->GetChildCount(); ++i) { - OpenAll(node->GetChild(i), open_first_in_new_window, navigator, - opened_url); + OpenAllImpl(node->GetChild(i), initial_disposition, navigator, + opened_url); } } } +// Returns the number of descendants of node that are of type url. +int DescendantURLCount(BookmarkNode* node) { + int result = 0; + for (int i = 0; i < node->GetChildCount(); ++i) { + BookmarkNode* child = node->GetChild(i); + if (child->is_url()) + result++; + else + result += DescendantURLCount(child); + } + return result; +} + +bool ShouldOpenAll(HWND parent, BookmarkNode* node) { + int descendant_count = DescendantURLCount(node); + if (descendant_count < kNumURLsBeforePrompting) + return true; + + std::wstring message = + l10n_util::GetStringF(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL, + IntToWString(descendant_count)); + return (MessageBox(parent, message.c_str(), + l10n_util::GetString(IDS_PRODUCT_NAME).c_str(), + MB_YESNO | MB_ICONWARNING | MB_TOPMOST) == IDYES); +} + // EditFolderController ------------------------------------------------------- // EditFolderController manages the editing and/or creation of a folder. If the @@ -181,6 +204,20 @@ const int BookmarkBarContextMenuController::delete_bookmark_id = 8; const int BookmarkBarContextMenuController::add_bookmark_id = 9; const int BookmarkBarContextMenuController::new_folder_id = 10; +// static +void BookmarkBarContextMenuController::OpenAll( + HWND parent, + PageNavigator* navigator, + BookmarkNode* node, + WindowOpenDisposition initial_disposition) { + if (!ShouldOpenAll(parent, node)) + return; + + PageNavigator* nav = navigator; + bool opened_url = false; + OpenAllImpl(node, initial_disposition, &nav, &opened_url); +} + BookmarkBarContextMenuController::BookmarkBarContextMenuController( BookmarkBarView* view, BookmarkNode* node) @@ -284,11 +321,18 @@ void BookmarkBarContextMenuController::ExecuteCommand(int id) { L"BookmarkBar_ContextMenu_OpenAllInNewWindow", profile); } - BookmarkNode* node = node_; - PageNavigator* navigator = view_->GetPageNavigator(); - bool opened_url = false; - OpenAll(node, (id == open_all_bookmarks_in_new_window_id), &navigator, - &opened_url); + WindowOpenDisposition initial_disposition; + if (id == open_all_bookmarks_in_new_window_id) + initial_disposition = NEW_WINDOW; + else + initial_disposition = CURRENT_TAB; + + // GetViewContainer is NULL during testing. + HWND parent_hwnd = view_->GetViewContainer() ? + view_->GetViewContainer()->GetHWND() : 0; + + OpenAll(parent_hwnd, view_->GetPageNavigator(), node_, + initial_disposition); break; } diff --git a/chrome/browser/bookmark_bar_context_menu_controller.h b/chrome/browser/bookmark_bar_context_menu_controller.h index 9332bca..a6fd38a 100644 --- a/chrome/browser/bookmark_bar_context_menu_controller.h +++ b/chrome/browser/bookmark_bar_context_menu_controller.h @@ -7,6 +7,7 @@ #include "chrome/views/chrome_menu.h" #include "chrome/browser/views/bookmark_bar_view.h" +#include "webkit/glue/window_open_disposition.h" class BookmarkNode; class PageNavigator; @@ -17,6 +18,14 @@ class PageNavigator; class BookmarkBarContextMenuController : public ChromeViews::MenuDelegate, public BookmarkBarView::ModelChangedListener { public: + // Recursively opens all bookmarks of |node|. |initial_disposition| dictates + // how the first URL is opened, all subsequent URLs are opened as background + // tabs. + static void OpenAll(HWND parent, + PageNavigator* navigator, + BookmarkNode* node, + WindowOpenDisposition initial_disposition); + BookmarkBarContextMenuController(BookmarkBarView* view, BookmarkNode* node); diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h index 564393a..e3e1b3f 100644 --- a/chrome/browser/bookmarks/bookmark_drag_data.h +++ b/chrome/browser/bookmarks/bookmark_drag_data.h @@ -45,7 +45,7 @@ struct BookmarkDragData { // Returns the node represented by this DragData. If this DragData was created // from the same profile then the node from the model is returned. If the // node can't be found (may have been deleted), NULL is returned. - BookmarkNode* BookmarkDragData::GetNode(Profile* profile) const; + BookmarkNode* GetNode(Profile* profile) const; // If true, this entry represents a StarredEntry of type URL. bool is_url; diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 8d2531a..20bee0b 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -143,6 +143,9 @@ static const int kInstructionsPadding = 6; // Color of the instructional text. static const SkColor kInstructionsColor = SkColorSetRGB(128, 128, 142); +// Tag for the other button. +static const int kOtherFolderButtonTag = 1; + namespace { // Calculates the drop operation given the event and supported set of @@ -254,25 +257,25 @@ class BookmarkButton : public ChromeViews::TextButton { virtual void Paint(ChromeCanvas *canvas) { ChromeViews::TextButton::Paint(canvas); + PaintAnimation(this, canvas, show_animation_->GetCurrentValue()); + } + + static void PaintAnimation(ChromeViews::View* view, + ChromeCanvas* canvas, + double animation_value) { // Since we can't change the alpha of the button (it contains un-alphable // text), we paint the bar background over the front of the button. As the // bar background is a gradient, we have to paint the gradient at the // size of the parent (hence all the margin math below). We can't use // the parent's actual bounds because they differ from what is painted. SkPaint paint; - paint.setAlpha(static_cast<int>( - (1.0 - show_animation_->GetCurrentValue()) * 255)); + paint.setAlpha(static_cast<int>((1.0 - animation_value) * 255)); paint.setShader(gfx::CreateGradientShader(0, - height() + kTopMargin + kBottomMargin, + view->height() + kTopMargin + kBottomMargin, kTopBorderColor, kBackgroundColor))->safeUnref(); - canvas->FillRectInt(0, -kTopMargin, width(), - height() + kTopMargin + kBottomMargin, paint); - } - - virtual void AnimationProgressed(const Animation* animation) { - ChromeViews::TextButton::AnimationProgressed(animation); - SchedulePaint(); + canvas->FillRectInt(0, -kTopMargin, view->width(), + view->height() + kTopMargin + kBottomMargin, paint); } private: @@ -283,6 +286,45 @@ class BookmarkButton : public ChromeViews::TextButton { DISALLOW_COPY_AND_ASSIGN(BookmarkButton); }; +// BookmarkFolderButton ------------------------------------------------------- + +// Buttons used for folders on the bookmark bar, including the 'other folders' +// button. +class BookmarkFolderButton : public ChromeViews::MenuButton { + public: + BookmarkFolderButton(const std::wstring& title, + ChromeViews::ViewMenuDelegate* menu_delegate, + bool show_menu_marker) + : MenuButton(title, menu_delegate, show_menu_marker) { + show_animation_.reset(new SlideAnimation(this)); + if (BookmarkBarView::testing_) { + // For some reason during testing the events generated by animating + // throw off the test. So, don't animate while testing. + show_animation_->Reset(1); + } else { + show_animation_->Show(); + } + } + + virtual bool IsTriggerableEvent(const ChromeViews::MouseEvent& e) { + // This is hard coded to avoid potential notification on left mouse down, + // which we want to show the menu. + return e.IsMiddleMouseButton(); + } + + virtual void Paint(ChromeCanvas *canvas) { + ChromeViews::MenuButton::Paint(canvas, false); + + BookmarkButton::PaintAnimation(this, canvas, + show_animation_->GetCurrentValue()); + } + + private: + scoped_ptr<SlideAnimation> show_animation_; + + DISALLOW_COPY_AND_ASSIGN(BookmarkFolderButton); +}; + // DropInfo ------------------------------------------------------------------- // Tracks drops on the BookmarkBarView. @@ -386,6 +428,7 @@ class MenuRunner : public ChromeViews::MenuDelegate, MenuItemView* menu, int* next_menu_id) { DCHECK(!parent->GetChildCount() || + start_child_index < parent->GetChildCount()); for (int i = start_child_index; i < parent->GetChildCount(); ++i) { BookmarkNode* node = parent->GetChild(i); @@ -1127,10 +1170,11 @@ void BookmarkBarView::Init() { } MenuButton* BookmarkBarView::CreateOtherBookmarkedButton() { - MenuButton* button = new MenuButton( + MenuButton* button = new BookmarkFolderButton( l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_BOOKMARKED), this, false); button->SetIcon(GetGroupIcon()); button->SetContextMenuController(this); + button->SetListener(this, kOtherFolderButtonTag); return button; } @@ -1371,14 +1415,25 @@ void BookmarkBarView::RunMenu(ChromeViews::View* view, } void BookmarkBarView::ButtonPressed(ChromeViews::BaseButton* sender) { - int index = GetChildIndex(sender); - DCHECK(index != -1); - BookmarkNode* node = model_->GetBookmarkBarNode()->GetChild(index); + BookmarkNode* node; + if (sender->GetTag() == kOtherFolderButtonTag) { + node = model_->other_node(); + } else { + int index = GetChildIndex(sender); + DCHECK(index != -1); + node = model_->GetBookmarkBarNode()->GetChild(index); + } DCHECK(page_navigator_); - page_navigator_->OpenURL( - node->GetURL(), - event_utils::DispositionFromEventFlags(sender->mouse_event_flags()), - PageTransition::AUTO_BOOKMARK); + if (node->is_url()) { + page_navigator_->OpenURL( + node->GetURL(), + event_utils::DispositionFromEventFlags(sender->mouse_event_flags()), + PageTransition::AUTO_BOOKMARK); + } else { + BookmarkBarContextMenuController::OpenAll( + GetViewContainer()->GetHWND(), GetPageNavigator(), node, + event_utils::DispositionFromEventFlags(sender->mouse_event_flags())); + } UserMetrics::RecordAction(L"ClickedBookmarkBarURLButton", profile_); } @@ -1416,8 +1471,9 @@ ChromeViews::View* BookmarkBarView::CreateBookmarkButton(BookmarkNode* node) { return button; } else { ChromeViews::MenuButton* button = - new ChromeViews::MenuButton(node->GetTitle(), this, false); + new BookmarkFolderButton(node->GetTitle(), this, false); button->SetIcon(GetGroupIcon()); + button->SetListener(this, 0); ConfigureButton(node, button); return button; } |