summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorbeaudoin@chromium.org <beaudoin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-05 19:40:40 +0000
committerbeaudoin@chromium.org <beaudoin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-05 19:40:40 +0000
commit0955ce35cc41779879d63485d33b84100e2f0f09 (patch)
tree63ad5128892e4aab4b0da512021d633ff8955845 /chrome
parentc21470a80f21c322054000c70ed8218f6c13ffdc (diff)
downloadchromium_src-0955ce35cc41779879d63485d33b84100e2f0f09.zip
chromium_src-0955ce35cc41779879d63485d33b84100e2f0f09.tar.gz
chromium_src-0955ce35cc41779879d63485d33b84100e2f0f09.tar.bz2
Add a shortcut to open the Apps page from the bookmark bar.
Initial patch by mad@chromium: https://codereview.chromium.org/12310109/ BUG=177377 TEST=Make sure that an app shortcut is available in the bookmark bar when instant extended is enabled, and that this button can be hidden/shown from the bookmark bar context menu. Review URL: https://chromiumcodereview.appspot.com/12386088 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186232 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/chrome_command_ids.h1
-rw-r--r--chrome/app/generated_resources.grd12
-rw-r--r--chrome/browser/bookmarks/bookmark_utils.cc10
-rw-r--r--chrome/browser/bookmarks/bookmark_utils.h3
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc186
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bar_view.h27
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc72
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc27
-rw-r--r--chrome/chrome_tests_unit.gypi1
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h1
11 files changed, 304 insertions, 40 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index 852b1ab..cbf2059 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -320,6 +320,7 @@
#define IDC_BOOKMARK_BAR_NEW_FOLDER 51008
#define IDC_BOOKMARK_MANAGER 51009
#define IDC_BOOKMARK_BAR_ALWAYS_SHOW 51010
+#define IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT 51011
// Context menu items in the status tray
#define IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND 51100
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ca27b66..b6bc68e 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8950,6 +8950,12 @@ The following plug-in is unresponsive: <ph name="PLUGIN_NAME">$1
<message name="IDS_BOOKMARK_EDITOR_CONFIRM_DELETE" desc="The message shown in the dialog asking the user to confirm deleting a folder.">
This folder contains <ph name="COUNT">$1<ex>5</ex></ph> bookmarks. Are you sure you want to delete it?
</message>
+ <message name="IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME" desc="Name shown in the bookmark bar for the apps page shortcut">
+ Apps
+ </message>
+ <message name="IDS_BOOKMARK_BAR_APPS_SHORTCUT_TOOLTIP" desc="Text shown in the tooltip of the apps page shortcut in the bookmark bar">
+ Show apps
+ </message>
<if expr="not pp_ifdef('use_titlecase')">
<message name="IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME" desc="Name shown in the tree for the mobile bookmarks folder">
Mobile bookmarks
@@ -8957,6 +8963,9 @@ The following plug-in is unresponsive: <ph name="PLUGIN_NAME">$1
<message name="IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME" desc="Name shown in the tree for the other bookmarks folder">
Other bookmarks
</message>
+ <message name="IDS_BOOKMARK_BAR_SHOW_APPS_SHORTCUT" desc="Name shown in the context menu to hide/show the apps shortcut in the bookmakr bar">
+ Show apps shortcut
+ </message>
</if>
<if expr="pp_ifdef('use_titlecase')">
<message name="IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME" desc="In Title Case: Name shown in the tree for the mobile bookmarks folder">
@@ -8965,6 +8974,9 @@ The following plug-in is unresponsive: <ph name="PLUGIN_NAME">$1
<message name="IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME" desc="In Title Case: Name shown in the tree for the other bookmarks folder">
Other Bookmarks
</message>
+ <message name="IDS_BOOKMARK_BAR_SHOW_APPS_SHORTCUT" desc="In Title Case: Name shown in the context menu to hide/show the apps shortcut in the bookmakr bar">
+ Show Apps Shortcut
+ </message>
</if>
<if expr="not pp_ifdef('android') and not pp_ifdef('ios') and pp_ifdef('use_titlecase')">
<message name="IDS_BOOKMARK_BAR_FOLDER_NAME" desc="In Title Case: Name shown in the tree for the bookmarks bar folder">
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index 2e647dd..5f35ce6 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -440,6 +440,9 @@ void RegisterUserPrefs(PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(prefs::kEditBookmarksEnabled,
true,
PrefRegistrySyncable::UNSYNCABLE_PREF);
+ registry->RegisterBooleanPref(prefs::kShowAppsShortcutInBookmarkBar,
+ true,
+ PrefRegistrySyncable::SYNCABLE_PREF);
}
const BookmarkNode* GetParentForNewNodes(
@@ -520,6 +523,13 @@ void RecordBookmarkLaunch(BookmarkLaunchLocation location) {
UMA_HISTOGRAM_ENUMERATION("Bookmarks.LaunchLocation", location, LAUNCH_LIMIT);
}
+void RecordAppsPageOpen(BookmarkLaunchLocation location) {
+ if (location == LAUNCH_DETACHED_BAR || location == LAUNCH_ATTACHED_BAR) {
+ content::RecordAction(
+ UserMetricsAction("ClickedBookmarkBarAppsShortcutButton"));
+ }
+}
+
#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(USE_AURA)
void DisableBookmarkBarViewAnimationsForTesting(bool disabled) {
g_bookmark_bar_view_animations_disabled = disabled;
diff --git a/chrome/browser/bookmarks/bookmark_utils.h b/chrome/browser/bookmarks/bookmark_utils.h
index 5294ca7..b18c5b7 100644
--- a/chrome/browser/bookmarks/bookmark_utils.h
+++ b/chrome/browser/bookmarks/bookmark_utils.h
@@ -220,6 +220,9 @@ void RecordBookmarkLaunch(BookmarkLaunchLocation location);
// Records the user opening a folder of bookmarks for UMA purposes.
void RecordBookmarkFolderOpen(BookmarkLaunchLocation location);
+// Records the user opening the apps page for UMA purposes.
+void RecordAppsPageOpen(BookmarkLaunchLocation location);
+
#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(USE_AURA)
void DisableBookmarkBarViewAnimationsForTesting(bool disabled);
bool IsBookmarkBarViewAnimationsDisabled();
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 9644589..505806e 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -30,6 +30,7 @@
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/search/search.h"
#include "chrome/browser/ui/search/search_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/view_ids.h"
@@ -147,13 +148,47 @@ static const int kSearchNewTabBookmarkBarHeight = 36;
static const int kSearchNewTabHorizontalPadding = 0;
static const int kSearchNewTabVerticalPadding = 0;
+// Tag for the 'Apps Shortcut' button.
+static const int kAppsShortcutButtonTag = 2;
+
namespace {
+// BookmarkButtonBase -----------------------------------------------
+
+// Base class for text buttons used on the bookmark bar.
+
+class BookmarkButtonBase : public views::TextButton {
+ public:
+ BookmarkButtonBase(views::ButtonListener* listener,
+ const string16& title)
+ : TextButton(listener, title) {
+ show_animation_.reset(new ui::SlideAnimation(this));
+ if (bookmark_utils::IsBookmarkBarViewAnimationsDisabled()) {
+ // For some reason during testing the events generated by anima
+ // throw off the test. So, don't animate while testing.
+ show_animation_->Reset(1);
+ } else {
+ show_animation_->Show();
+ }
+ }
+
+ virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE {
+ return e.type() == ui::ET_GESTURE_TAP ||
+ e.type() == ui::ET_GESTURE_TAP_DOWN ||
+ event_utils::IsPossibleDispositionEvent(e);
+ }
+
+ private:
+ scoped_ptr<ui::SlideAnimation> show_animation_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkButtonBase);
+};
+
// BookmarkButton -------------------------------------------------------------
// Buttons used for the bookmarks on the bookmark bar.
-class BookmarkButton : public views::TextButton {
+class BookmarkButton : public BookmarkButtonBase {
public:
// The internal view class name.
static const char kViewClassName[];
@@ -162,17 +197,9 @@ class BookmarkButton : public views::TextButton {
const GURL& url,
const string16& title,
Profile* profile)
- : TextButton(listener, title),
+ : BookmarkButtonBase(listener, title),
url_(url),
profile_(profile) {
- show_animation_.reset(new ui::SlideAnimation(this));
- if (bookmark_utils::IsBookmarkBarViewAnimationsDisabled()) {
- // 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 GetTooltipText(const gfx::Point& p,
@@ -184,12 +211,6 @@ class BookmarkButton : public views::TextButton {
return !tooltip->empty();
}
- virtual bool IsTriggerableEvent(const ui::Event& e) OVERRIDE {
- return e.type() == ui::ET_GESTURE_TAP ||
- e.type() == ui::ET_GESTURE_TAP_DOWN ||
- event_utils::IsPossibleDispositionEvent(e);
- }
-
virtual std::string GetClassName() const OVERRIDE {
return kViewClassName;
}
@@ -197,7 +218,6 @@ class BookmarkButton : public views::TextButton {
private:
const GURL& url_;
Profile* profile_;
- scoped_ptr<ui::SlideAnimation> show_animation_;
DISALLOW_COPY_AND_ASSIGN(BookmarkButton);
};
@@ -206,6 +226,33 @@ class BookmarkButton : public views::TextButton {
const char BookmarkButton::kViewClassName[] =
"browser/ui/views/bookmarks/BookmarkButton";
+// ShortcutButton -------------------------------------------------------------
+
+// Buttons used for the shortcuts on the bookmark bar.
+
+class ShortcutButton : public BookmarkButtonBase {
+ public:
+ // The internal view class name.
+ static const char kViewClassName[];
+
+ ShortcutButton(views::ButtonListener* listener,
+ const string16& title)
+ : BookmarkButtonBase(listener, title) {
+ }
+
+ virtual std::string GetClassName() const OVERRIDE {
+ return kViewClassName;
+ }
+
+ private:
+
+ DISALLOW_COPY_AND_ASSIGN(ShortcutButton);
+};
+
+// static for ShortcutButton
+const char ShortcutButton::kViewClassName[] =
+ "browser/ui/views/bookmarks/ShortcutButton";
+
// BookmarkFolderButton -------------------------------------------------------
// Buttons used for folders on the bookmark bar, including the 'other folders'
@@ -406,6 +453,7 @@ BookmarkBarView::BookmarkBarView(Browser* browser, BrowserView* browser_view)
bookmark_menu_(NULL),
bookmark_drop_menu_(NULL),
other_bookmarked_button_(NULL),
+ apps_page_shortcut_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(show_folder_method_factory_(this)),
overflow_button_(NULL),
instructions_(NULL),
@@ -627,13 +675,21 @@ gfx::Size BookmarkBarView::GetMinimumSize() {
browser_->search_model()->mode()) * current_state);
}
- gfx::Size other_bookmarked_pref =
- other_bookmarked_button_->GetPreferredSize();
- gfx::Size overflow_pref = overflow_button_->GetPreferredSize();
- gfx::Size bookmarks_separator_pref =
- bookmarks_separator_view_->GetPreferredSize();
-
+ gfx::Size other_bookmarked_pref;
+ if (other_bookmarked_button_->visible())
+ other_bookmarked_pref = other_bookmarked_button_->GetPreferredSize();
+ gfx::Size overflow_pref;
+ if (overflow_button_->visible())
+ overflow_pref = overflow_button_->GetPreferredSize();
+ gfx::Size bookmarks_separator_pref;
+ if (bookmarks_separator_view_->visible())
+ bookmarks_separator_pref = bookmarks_separator_view_->GetPreferredSize();
+
+ gfx::Size apps_page_shortcut_pref;
+ if (apps_page_shortcut_->visible())
+ apps_page_shortcut_pref = apps_page_shortcut_->GetPreferredSize();
width += other_bookmarked_pref.width() + kButtonPadding +
+ apps_page_shortcut_pref.width() + kButtonPadding +
overflow_pref.width() + kButtonPadding +
bookmarks_separator_pref.width();
@@ -1074,6 +1130,12 @@ void BookmarkBarView::OnMenuButtonClicked(views::View* view,
void BookmarkBarView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
+ if (sender->tag() == kAppsShortcutButtonTag) {
+ chrome::ShowAppLauncherPage(browser_);
+ bookmark_utils::RecordAppsPageOpen(GetBookmarkLaunchLocation());
+ return;
+ }
+
const BookmarkNode* node;
if (sender->tag() == kOtherFolderButtonTag) {
node = model_->other_node();
@@ -1113,11 +1175,12 @@ void BookmarkBarView::ShowContextMenuForView(views::View* source,
if (source == other_bookmarked_button_) {
parent = model_->other_node();
// Do this so the user can open all bookmarks. BookmarkContextMenu makes
- // sure the user can edit/delete the node in this case.
+ // sure the user can't edit/delete the node in this case.
nodes.push_back(parent);
- } else if (source != this) {
+ } else if (source != this && source != apps_page_shortcut_) {
// User clicked on one of the bookmark buttons, find which one they
- // clicked on.
+ // clicked on, except for the apps page shortcut, which must behave as if
+ // the user clicked on the bookmark bar background.
int bookmark_button_index = GetIndexOf(source);
DCHECK(bookmark_button_index != -1 &&
bookmark_button_index < GetBookmarkButtonCount());
@@ -1161,13 +1224,18 @@ void BookmarkBarView::Init() {
other_bookmarked_button_->SetEnabled(false);
AddChildView(other_bookmarked_button_);
+ apps_page_shortcut_ = CreateAppsPageShortcutButton();
+ AddChildView(apps_page_shortcut_);
+ profile_pref_registrar_.Init(browser_->profile()->GetPrefs());
+ profile_pref_registrar_.Add(
+ prefs::kShowAppsShortcutInBookmarkBar,
+ base::Bind(&BookmarkBarView::OnAppsPageShortcutVisibilityChanged,
+ base::Unretained(this)));
+ apps_page_shortcut_->SetVisible(ShouldShowAppsShortcut());
+
bookmarks_separator_view_ = new ButtonSeparatorView();
AddChildView(bookmarks_separator_view_);
-#if defined(USE_ASH)
- // Ash does not paint the bookmarks separator line because it looks odd on
- // the flat background. We keep it present for layout, but don't draw it.
- bookmarks_separator_view_->SetVisible(false);
-#endif
+ UpdateBookmarksSeparatorVisibility();
instructions_ = new BookmarkBarInstructionsView(this);
AddChildView(instructions_);
@@ -1188,8 +1256,8 @@ void BookmarkBarView::Init() {
int BookmarkBarView::GetBookmarkButtonCount() {
// We contain four non-bookmark button views: other bookmarks, bookmarks
- // separator, chevrons (for overflow), and the instruction label.
- return child_count() - 4;
+ // separator, chevrons (for overflow), apps page, and the instruction label.
+ return child_count() - 5;
}
views::TextButton* BookmarkBarView::GetBookmarkButton(int index) {
@@ -1259,6 +1327,19 @@ views::View* BookmarkBarView::CreateBookmarkButton(const BookmarkNode* node) {
}
}
+views::TextButton* BookmarkBarView::CreateAppsPageShortcutButton() {
+ views::TextButton* button = new ShortcutButton(
+ this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME));
+ button->SetTooltipText(l10n_util::GetStringUTF16(
+ IDS_BOOKMARK_BAR_APPS_SHORTCUT_TOOLTIP));
+ button->set_id(VIEW_ID_BOOKMARK_BAR_ELEMENT);
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ button->SetIcon(*rb.GetImageSkiaNamed(IDR_WEBSTORE_ICON_16));
+ button->set_context_menu_controller(this);
+ button->set_tag(kAppsShortcutButtonTag);
+ return button;
+}
+
void BookmarkBarView::ConfigureButton(const BookmarkNode* node,
views::TextButton* button) {
button->SetText(node->GetTitle());
@@ -1573,13 +1654,20 @@ void BookmarkBarView::UpdateOtherBookmarksVisibility() {
if (has_other_children == other_bookmarked_button_->visible())
return;
other_bookmarked_button_->SetVisible(has_other_children);
-#if !defined(USE_ASH)
- bookmarks_separator_view_->SetVisible(has_other_children);
-#endif
+ UpdateBookmarksSeparatorVisibility();
Layout();
SchedulePaint();
}
+void BookmarkBarView::UpdateBookmarksSeparatorVisibility() {
+ // Ash does not paint the bookmarks separator line because it looks odd on
+ // the flat background. We keep it present for layout, but don't draw it.
+ bookmarks_separator_view_->SetVisible(
+ browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH &&
+ (other_bookmarked_button_->visible() ||
+ apps_page_shortcut_->visible()));
+}
+
gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) {
gfx::Size prefsize;
if (!parent() && !compute_bounds_only)
@@ -1615,11 +1703,15 @@ gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) {
gfx::Size overflow_pref = overflow_button_->GetPreferredSize();
gfx::Size bookmarks_separator_pref =
bookmarks_separator_view_->GetPreferredSize();
+ gfx::Size apps_page_shortcut_pref = apps_page_shortcut_->visible() ?
+ apps_page_shortcut_->GetPreferredSize() : gfx::Size();
int max_x = width - overflow_pref.width() - kButtonPadding -
bookmarks_separator_pref.width();
if (other_bookmarked_button_->visible())
max_x -= other_bookmarked_pref.width() + kButtonPadding;
+ if (apps_page_shortcut_->visible())
+ max_x -= apps_page_shortcut_pref.width() + kButtonPadding;
// Next, layout out the buttons. Any buttons that are placed beyond the
// visible region and made invisible.
@@ -1688,6 +1780,15 @@ gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) {
x += other_bookmarked_pref.width() + kButtonPadding;
}
+ // The app page shortcut button.
+ if (apps_page_shortcut_->visible()) {
+ if (!compute_bounds_only) {
+ apps_page_shortcut_->SetBounds(x, y, apps_page_shortcut_pref.width(),
+ height);
+ }
+ x += apps_page_shortcut_pref.width() + kButtonPadding;
+ }
+
// Set the preferred size computed so far.
if (compute_bounds_only) {
x += kRightMargin;
@@ -1712,3 +1813,16 @@ gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) {
}
return prefsize;
}
+
+bool BookmarkBarView::ShouldShowAppsShortcut() const {
+ return chrome::search::IsInstantExtendedAPIEnabled(browser_->profile()) &&
+ browser_->profile()->GetPrefs()->GetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar);
+}
+
+void BookmarkBarView::OnAppsPageShortcutVisibilityChanged() {
+ DCHECK(apps_page_shortcut_);
+ apps_page_shortcut_->SetVisible(ShouldShowAppsShortcut());
+ UpdateBookmarksSeparatorVisibility();
+ Layout();
+}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index 4d9a83e..7faa579 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
+#include "base/prefs/public/pref_change_registrar.h"
#include "chrome/browser/bookmarks/bookmark_model_observer.h"
#include "chrome/browser/bookmarks/bookmark_node_data.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
@@ -250,6 +251,10 @@ class BookmarkBarView : public DetachableToolbarView,
friend class BookmarkBarViewEventTestBase;
FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewTest, SwitchProfile);
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewTest,
+ NoAppsShortcutWithoutInstantExtended);
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewInstantExtendedTest,
+ AppsShortcutVisibility);
// Used to identify what the user is dropping onto.
enum DropButtonType {
@@ -293,6 +298,9 @@ class BookmarkBarView : public DetachableToolbarView,
// Creates the button for rendering the specified bookmark node.
views::View* CreateBookmarkButton(const BookmarkNode* node);
+ // Creates the button for rendering the apps page shortcut.
+ views::TextButton* CreateAppsPageShortcutButton();
+
// Configures the button from the specified node. This sets the text,
// and icon.
void ConfigureButton(const BookmarkNode* node, views::TextButton* button);
@@ -345,16 +353,28 @@ class BookmarkBarView : public DetachableToolbarView,
// Updates the colors for all the child objects in the bookmarks bar.
void UpdateColors();
- // Updates the visibility of |other_bookmarked_button_| and
- // |bookmarks_separator_view_|.
+ // Updates the visibility of |other_bookmarked_button_|. Also shows or hide
+ // the separator if required.
void UpdateOtherBookmarksVisibility();
+ // Updates the visibility of |bookmarks_separator_view_|.
+ void UpdateBookmarksSeparatorVisibility();
+
// This method computes the bounds for the bookmark bar items. If
// |compute_bounds_only| = TRUE, the bounds for the items are just computed,
// but are not set. This mode is used by GetPreferredSize() to obtain the
// desired bounds. If |compute_bounds_only| = FALSE, the bounds are set.
gfx::Size LayoutItems(bool compute_bounds_only);
+ // Returns true if we should show the apps shortcut.
+ bool ShouldShowAppsShortcut() const;
+
+ // Updates the visibility of the apps shortcut based on the pref value.
+ void OnAppsPageShortcutVisibilityChanged();
+
+ // Needed to react to kShowAppsShortcutInBookmarkBar changes.
+ PrefChangeRegistrar profile_pref_registrar_;
+
// Used for opening urls.
content::PageNavigator* page_navigator_;
@@ -378,6 +398,9 @@ class BookmarkBarView : public DetachableToolbarView,
// Shows the other bookmark entries.
views::MenuButton* other_bookmarked_button_;
+ // Shows the Apps page shortcut.
+ views::TextButton* apps_page_shortcut_;
+
// Task used to delay showing of the drop menu.
base::WeakPtrFactory<BookmarkBarView> show_folder_method_factory_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
new file mode 100644
index 0000000..912ff74
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -0,0 +1,72 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
+
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/ui/search/search.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "ui/views/controls/button/text_button.h"
+
+typedef BrowserWithTestWindowTest BookmarkBarViewTest;
+
+// Verify that the apps shortcut is never visible without instant extended.
+TEST_F(BookmarkBarViewTest, NoAppsShortcutWithoutInstantExtended) {
+ profile()->CreateBookmarkModel(true);
+ profile()->BlockUntilBookmarkModelLoaded();
+ BookmarkBarView bookmark_bar_view(browser(), NULL);
+ bookmark_bar_view.set_owned_by_client();
+ EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+ browser()->profile()->GetPrefs()->SetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar, true);
+ EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+}
+
+class BookmarkBarViewInstantExtendedTest : public BrowserWithTestWindowTest {
+ public:
+ BookmarkBarViewInstantExtendedTest() {
+ chrome::search::EnableInstantExtendedAPIForTesting();
+ }
+
+ protected:
+ virtual TestingProfile* CreateProfile() OVERRIDE {
+ TestingProfile* profile = BrowserWithTestWindowTest::CreateProfile();
+ // TemplateURLService is normally NULL during testing. Instant extended
+ // needs this service so set a custom factory function.
+ TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
+ profile, &BookmarkBarViewInstantExtendedTest::CreateTemplateURLService);
+ return profile;
+ }
+
+ private:
+ static ProfileKeyedService* CreateTemplateURLService(Profile* profile) {
+ return new TemplateURLService(profile);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewInstantExtendedTest);
+};
+
+// Verify that in instant extended mode the visibility of the apps shortcut
+// button properly follows the pref value.
+TEST_F(BookmarkBarViewInstantExtendedTest, AppsShortcutVisibility) {
+ profile()->CreateBookmarkModel(true);
+ profile()->BlockUntilBookmarkModelLoaded();
+ BookmarkBarView bookmark_bar_view(browser(), NULL);
+ bookmark_bar_view.set_owned_by_client();
+ browser()->profile()->GetPrefs()->SetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar, false);
+ EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+ browser()->profile()->GetPrefs()->SetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar, true);
+ EXPECT_TRUE(bookmark_bar_view.apps_page_shortcut_->visible());
+ // Make sure we can also properly transition from true to false.
+ browser()->profile()->GetPrefs()->SetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar, false);
+ EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc
index 271a9b9..7bcce93 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_controller_views.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/search/search.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/page_navigator.h"
@@ -145,6 +146,14 @@ void BookmarkContextMenuControllerViews::ExecuteCommand(int id) {
chrome::ToggleBookmarkBarWhenVisible(profile_);
break;
+ case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT: {
+ PrefService* prefs = profile_->GetPrefs();
+ prefs->SetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar,
+ !prefs->GetBoolean(prefs::kShowAppsShortcutInBookmarkBar));
+ break;
+ }
+
case IDC_BOOKMARK_MANAGER: {
content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
if (selection_.size() != 1)
@@ -185,8 +194,14 @@ void BookmarkContextMenuControllerViews::ExecuteCommand(int id) {
}
bool BookmarkContextMenuControllerViews::IsItemChecked(int id) const {
- DCHECK_EQ(IDC_BOOKMARK_BAR_ALWAYS_SHOW, id);
- return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
+ if (id == IDC_BOOKMARK_BAR_ALWAYS_SHOW)
+ return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
+
+ // This should only be available when instant extended is enabled.
+ DCHECK(chrome::search::IsInstantExtendedAPIEnabled(profile_));
+ DCHECK_EQ(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT, id);
+ return profile_->GetPrefs()->GetBoolean(
+ prefs::kShowAppsShortcutInBookmarkBar);
}
bool BookmarkContextMenuControllerViews::IsCommandEnabled(int id) const {
@@ -229,6 +244,10 @@ bool BookmarkContextMenuControllerViews::IsCommandEnabled(int id) const {
return !profile_->GetPrefs()->IsManagedPreference(
prefs::kShowBookmarkBar);
+ case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT:
+ return !profile_->GetPrefs()->IsManagedPreference(
+ prefs::kShowAppsShortcutInBookmarkBar);
+
case IDC_COPY:
case IDC_CUT:
return !selection_.empty() && !is_root_node &&
@@ -287,6 +306,10 @@ void BookmarkContextMenuControllerViews::BuildMenu() {
delegate_->AddSeparator();
delegate_->AddItemWithStringId(IDC_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
+ if (chrome::search::IsInstantExtendedAPIEnabled(profile_)) {
+ delegate_->AddCheckboxItem(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT,
+ IDS_BOOKMARK_BAR_SHOW_APPS_SHORTCUT);
+ }
delegate_->AddCheckboxItem(IDC_BOOKMARK_BAR_ALWAYS_SHOW,
IDS_SHOW_BOOKMARK_BAR);
}
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 615f129..124dc83 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1449,6 +1449,7 @@
'browser/ui/toolbar/wrench_menu_model_unittest.cc',
'browser/ui/views/accelerator_table_unittest.cc',
'browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc',
+ 'browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc',
'browser/ui/views/bookmarks/bookmark_context_menu_test.cc',
'browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc',
'browser/ui/views/confirm_bubble_views_unittest.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 37c8a55..0efb43c 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -323,6 +323,10 @@ const char kWebKitPluginsEnabled[] = "webkit.webprefs.plugins_enabled";
// Boolean which specifies whether the bookmark bar is visible on all tabs.
const char kShowBookmarkBar[] = "bookmark_bar.show_on_all_tabs";
+// Boolean which specifies whether the apps shortcut is visible on the bookmark
+// bar.
+const char kShowAppsShortcutInBookmarkBar[] = "bookmark_bar.show_apps_shortcut";
+
// Boolean which specifies the ids of the bookmark nodes that are expanded in
// the bookmark editor.
const char kBookmarkEditorExpandedNodes[] = "bookmark_editor.expanded_nodes";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 2503471..c77fa24 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -68,6 +68,7 @@ extern const char kDefaultCharset[];
extern const char kAcceptLanguages[];
extern const char kStaticEncodings[];
extern const char kShowBookmarkBar[];
+extern const char kShowAppsShortcutInBookmarkBar[];
extern const char kBookmarkEditorExpandedNodes[];
extern const char kWebKitCommonScript[];
extern const char kWebKitStandardFontFamily[];