summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorsky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-01 15:21:16 +0000
committersky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-01 15:21:16 +0000
commitf89a6233760f8ca8033265046ed9ea38bbc20bf9 (patch)
treea438abfbbfd918fd0cff1862ab4b26ce7507484c /chrome/browser
parentf9b05c2dd900aa1850111c4a052db0da6e060a5a (diff)
downloadchromium_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.cc108
-rw-r--r--chrome/browser/bookmark_bar_context_menu_controller.h9
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.h2
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc94
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;
}