From b6d9749b1f5ac0001432fe56eadacbf8808ccca9 Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Thu, 25 Jun 2009 00:35:35 +0000 Subject: Fork bookmark context menu logic across platforms. There's too much crazy stuff going on here, I can't begin to unravel it on more than one platform at a time. TBR=sky BUG=none TEST=none Review URL: http://codereview.chromium.org/146125 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19207 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/bookmarks/bookmark_context_menu.cc | 557 --------------------- chrome/browser/bookmarks/bookmark_context_menu.h | 154 ------ .../browser/bookmarks/bookmark_context_menu_gtk.cc | 31 -- .../bookmarks/bookmark_context_menu_test.cc | 296 ----------- .../bookmarks/bookmark_context_menu_views.cc | 43 -- chrome/browser/gtk/bookmark_bar_gtk.cc | 2 +- chrome/browser/gtk/bookmark_context_menu.cc | 557 +++++++++++++++++++++ chrome/browser/gtk/bookmark_context_menu.h | 154 ++++++ chrome/browser/gtk/bookmark_context_menu_gtk.cc | 31 ++ chrome/browser/gtk/bookmark_manager_gtk.h | 2 +- chrome/browser/gtk/bookmark_menu_controller_gtk.cc | 2 +- chrome/browser/views/bookmark_bar_view.cc | 2 +- chrome/browser/views/bookmark_context_menu.cc | 557 +++++++++++++++++++++ chrome/browser/views/bookmark_context_menu.h | 154 ++++++ chrome/browser/views/bookmark_context_menu_test.cc | 296 +++++++++++ .../browser/views/bookmark_context_menu_views.cc | 43 ++ chrome/browser/views/bookmark_manager_view.h | 2 +- .../browser/views/bookmark_menu_controller_views.h | 2 +- chrome/chrome.gyp | 15 +- 19 files changed, 1807 insertions(+), 1093 deletions(-) delete mode 100644 chrome/browser/bookmarks/bookmark_context_menu.cc delete mode 100644 chrome/browser/bookmarks/bookmark_context_menu.h delete mode 100644 chrome/browser/bookmarks/bookmark_context_menu_gtk.cc delete mode 100644 chrome/browser/bookmarks/bookmark_context_menu_test.cc delete mode 100644 chrome/browser/bookmarks/bookmark_context_menu_views.cc create mode 100644 chrome/browser/gtk/bookmark_context_menu.cc create mode 100644 chrome/browser/gtk/bookmark_context_menu.h create mode 100644 chrome/browser/gtk/bookmark_context_menu_gtk.cc create mode 100644 chrome/browser/views/bookmark_context_menu.cc create mode 100644 chrome/browser/views/bookmark_context_menu.h create mode 100644 chrome/browser/views/bookmark_context_menu_test.cc create mode 100644 chrome/browser/views/bookmark_context_menu_views.cc (limited to 'chrome') diff --git a/chrome/browser/bookmarks/bookmark_context_menu.cc b/chrome/browser/bookmarks/bookmark_context_menu.cc deleted file mode 100644 index 0f554b2..0000000 --- a/chrome/browser/bookmarks/bookmark_context_menu.cc +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) 2009 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/bookmarks/bookmark_context_menu.h" - -#include "app/l10n_util.h" -#include "base/compiler_specific.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" -#include "chrome/browser/bookmarks/bookmark_manager.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/input_window_dialog.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" -#include "grit/generated_resources.h" - -// TODO(port): Port these files. -#if defined(OS_WIN) -#include "views/window/window.h" -#endif - -namespace { - -// Returns true if the specified node is of type URL, or has a descendant -// of type URL. -bool NodeHasURLs(BookmarkNode* node) { - if (node->is_url()) - return true; - - for (int i = 0; i < node->GetChildCount(); ++i) { - if (NodeHasURLs(node->GetChild(i))) - return true; - } - return false; -} - -// EditFolderController ------------------------------------------------------- - -// EditFolderController manages the editing and/or creation of a folder. If the -// user presses ok, the name change is committed to the model. -// -// EditFolderController deletes itself when the window is closed. -class EditFolderController : public InputWindowDialog::Delegate, - public BookmarkModelObserver { - public: - virtual ~EditFolderController() { - if (model_) - model_->RemoveObserver(this); - } - - static void Show(Profile* profile, - gfx::NativeView wnd, - BookmarkNode* node, - bool is_new, - bool show_in_manager) { - // EditFolderController deletes itself when done. - EditFolderController* controller = - new EditFolderController(profile, wnd, node, is_new, show_in_manager); - controller->Show(); - } - - private: - EditFolderController(Profile* profile, - gfx::NativeView wnd, - BookmarkNode* node, - bool is_new, - bool show_in_manager) - : profile_(profile), - model_(profile->GetBookmarkModel()), - node_(node), - is_new_(is_new), - show_in_manager_(show_in_manager) { - DCHECK(is_new_ || node); - - std::wstring title = is_new_ ? - l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE_NEW) : - l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE); - std::wstring label = - l10n_util::GetString(IDS_BOOMARK_BAR_EDIT_FOLDER_LABEL); - std::wstring contents = is_new_ ? - l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME) : - node_->GetTitle(); - - dialog_ = InputWindowDialog::Create(wnd, title, label, contents, this); - model_->AddObserver(this); - } - - void Show() { - dialog_->Show(); - } - - // InputWindowDialog::Delegate methods. - virtual bool IsValid(const std::wstring& text) { - return !text.empty(); - } - - virtual void InputAccepted(const std::wstring& text) { - if (is_new_) { - ALLOW_UNUSED BookmarkNode* node = - model_->AddGroup(node_, node_->GetChildCount(), text); - if (show_in_manager_) { -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - BookmarkManager::SelectInTree(profile_, node); -#else - NOTIMPLEMENTED() << "BookmarkManager not yet implemented"; -#endif - } - } else { - model_->SetTitle(node_, text); - } - } - - virtual void InputCanceled() { - } - - // BookmarkModelObserver methods, all invoke ModelChanged and close the - // dialog. - virtual void Loaded(BookmarkModel* model) {} - virtual void BookmarkModelBeingDeleted(BookmarkModel* model) { - model_->RemoveObserver(this); - model_ = NULL; - ModelChanged(); - } - - virtual void BookmarkNodeMoved(BookmarkModel* model, - BookmarkNode* old_parent, - int old_index, - BookmarkNode* new_parent, - int new_index) { - ModelChanged(); - } - - virtual void BookmarkNodeAdded(BookmarkModel* model, - BookmarkNode* parent, - int index) { - ModelChanged(); - } - - virtual void BookmarkNodeRemoved(BookmarkModel* model, - BookmarkNode* parent, - int index, - BookmarkNode* node) { - ModelChanged(); - } - - virtual void BookmarkNodeChanged(BookmarkModel* model, BookmarkNode* node) { - ModelChanged(); - } - - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, - BookmarkNode* node) {} - - virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, - BookmarkNode* node) { - ModelChanged(); - } - - void ModelChanged() { - dialog_->Close(); - } - - Profile* profile_; - BookmarkModel* model_; - // If is_new is true, this is the parent to create the new node under. - // Otherwise this is the node to change the title of. - BookmarkNode* node_; - - bool is_new_; - - // If is_new_ is true and a new node is created, it is selected in the - // bookmark manager. - bool show_in_manager_; - InputWindowDialog* dialog_; - - DISALLOW_COPY_AND_ASSIGN(EditFolderController); -}; - -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) -// SelectOnCreationHandler ---------------------------------------------------- - -// Used when adding a new bookmark. If a new bookmark is created it is selected -// in the bookmark manager. -class SelectOnCreationHandler : public BookmarkEditor::Handler { - public: - explicit SelectOnCreationHandler(Profile* profile) : profile_(profile) { - } - - virtual void NodeCreated(BookmarkNode* new_node) { - BookmarkManager::SelectInTree(profile_, new_node); - } - - private: - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(SelectOnCreationHandler); -}; -#endif // #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - -} // namespace - -// BookmarkContextMenu ------------------------------------------- - -BookmarkContextMenu::BookmarkContextMenu( - gfx::NativeView wnd, - Profile* profile, - Browser* browser, - PageNavigator* navigator, - BookmarkNode* parent, - const std::vector& selection, - ConfigurationType configuration) - : wnd_(wnd), - profile_(profile), - browser_(browser), - navigator_(navigator), - parent_(parent), - selection_(selection), - model_(profile->GetBookmarkModel()), - configuration_(configuration) { - DCHECK(profile_); - DCHECK(model_->IsLoaded()); - CreateMenuObject(); - - if (configuration != BOOKMARK_MANAGER_ORGANIZE_MENU) { - if (selection.size() == 1 && selection[0]->is_url()) { - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB); - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, - IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW); - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, - IDS_BOOMARK_BAR_OPEN_INCOGNITO); - } else { - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_ALL); - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, - IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW); - AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, - IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO); - } - AppendSeparator(); - } - - if (selection.size() == 1 && selection[0]->is_folder()) { - AppendItem(IDS_BOOKMARK_BAR_RENAME_FOLDER); - } else { - AppendItem(IDS_BOOKMARK_BAR_EDIT); - } - AppendItem(IDS_BOOKMARK_BAR_REMOVE); - - if (configuration == BOOKMARK_MANAGER_TABLE || - configuration == BOOKMARK_MANAGER_TABLE_OTHER || - configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || - configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { - AppendItem(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER); - } - - if (configuration == BOOKMARK_MANAGER_TABLE || - configuration == BOOKMARK_MANAGER_TABLE_OTHER || - configuration == BOOKMARK_MANAGER_TREE || - configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || - configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { - AppendSeparator(); - AppendItem(IDS_CUT); - AppendItem(IDS_COPY); - AppendItem(IDS_PASTE); - } - - if (configuration == BOOKMARK_MANAGER_ORGANIZE_MENU) { - AppendSeparator(); - AppendItem(IDS_BOOKMARK_MANAGER_SORT); - } - - AppendSeparator(); - - AppendItem(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK); - AppendItem(IDS_BOOMARK_BAR_NEW_FOLDER); - - if (configuration == BOOKMARK_BAR) { - AppendSeparator(); - AppendItem(IDS_BOOKMARK_MANAGER); - AppendCheckboxItem(IDS_BOOMARK_BAR_ALWAYS_SHOW); - } - - model_->AddObserver(this); -} - -BookmarkContextMenu::~BookmarkContextMenu() { - if (model_) - model_->RemoveObserver(this); -} - -void BookmarkContextMenu::ExecuteCommand(int id) { - switch (id) { - case IDS_BOOMARK_BAR_OPEN_ALL: - case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: - case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: { - PageNavigator* navigator = browser_ ? - browser_->GetSelectedTabContents() : navigator_; - WindowOpenDisposition initial_disposition; - if (id == IDS_BOOMARK_BAR_OPEN_ALL) { - initial_disposition = NEW_FOREGROUND_TAB; - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_OpenAll", - profile_); - } else if (id == IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW) { - initial_disposition = NEW_WINDOW; - UserMetrics::RecordAction( - L"BookmarkBar_ContextMenu_OpenAllInNewWindow", profile_); - } else { - initial_disposition = OFF_THE_RECORD; - UserMetrics::RecordAction( - L"BookmarkBar_ContextMenu_OpenAllIncognito", profile_); - } - - bookmark_utils::OpenAll(wnd_, profile_, navigator, selection_, - initial_disposition); - break; - } - - case IDS_BOOKMARK_BAR_RENAME_FOLDER: - case IDS_BOOKMARK_BAR_EDIT: - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Edit", profile_); - - if (selection_.size() != 1) { - NOTREACHED(); - return; - } - - if (selection_[0]->is_url()) { -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - BookmarkEditor::Configuration editor_config; - if (configuration_ == BOOKMARK_BAR) - editor_config = BookmarkEditor::SHOW_TREE; - else - editor_config = BookmarkEditor::NO_TREE; - BookmarkEditor::Show(wnd_, profile_, NULL, selection_[0], - editor_config, NULL); -#else - NOTIMPLEMENTED(); -#endif - } else { - EditFolderController::Show(profile_, wnd_, selection_[0], false, - false); - } - break; - - case IDS_BOOKMARK_BAR_REMOVE: { - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Remove", profile_); - BookmarkModel* model = RemoveModelObserver(); - - for (size_t i = 0; i < selection_.size(); ++i) { - model->Remove(selection_[i]->GetParent(), - selection_[i]->GetParent()->IndexOfChild(selection_[i])); - } - selection_.clear(); - break; - } - - case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: { - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Add", profile_); - -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - BookmarkEditor::Configuration editor_config; - BookmarkEditor::Handler* handler = NULL; - if (configuration_ == BOOKMARK_BAR) { - editor_config = BookmarkEditor::SHOW_TREE; - } else { - editor_config = BookmarkEditor::NO_TREE; - // This is owned by the BookmarkEditorView. - handler = new SelectOnCreationHandler(profile_); - } - BookmarkEditor::Show(wnd_, profile_, GetParentForNewNodes(), NULL, - editor_config, handler); -#else - NOTIMPLEMENTED(); -#endif - break; - } - - case IDS_BOOMARK_BAR_NEW_FOLDER: { - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_NewFolder", - profile_); - EditFolderController::Show(profile_, wnd_, GetParentForNewNodes(), - true, (configuration_ != BOOKMARK_BAR)); - break; - } - - case IDS_BOOMARK_BAR_ALWAYS_SHOW: - bookmark_utils::ToggleWhenVisible(profile_); - break; - - case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: - UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_ShowInFolder", - profile_); - - if (selection_.size() != 1) { - NOTREACHED(); - return; - } - -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - BookmarkManager::SelectInTree(profile_, selection_[0]); -#else - NOTIMPLEMENTED() << "Bookmark Manager not implemented"; -#endif - break; - - case IDS_BOOKMARK_MANAGER: - UserMetrics::RecordAction(L"ShowBookmarkManager", profile_); -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) - BookmarkManager::Show(profile_); -#else - NOTIMPLEMENTED() << "Bookmark Manager not implemented"; -#endif - break; - - case IDS_BOOKMARK_MANAGER_SORT: - UserMetrics::RecordAction(L"BookmarkManager_Sort", profile_); - model_->SortChildren(parent_); - break; - - case IDS_COPY: - case IDS_CUT: - bookmark_utils::CopyToClipboard(profile_->GetBookmarkModel(), - selection_, id == IDS_CUT); - break; - - case IDS_PASTE: { - // Always paste to parent. - if (!parent_) - return; - - int index = (selection_.size() == 1) ? - parent_->IndexOfChild(selection_[0]) : -1; - if (index != -1) - index++; - bookmark_utils::PasteFromClipboard(profile_->GetBookmarkModel(), - parent_, index); - break; - } - - default: - NOTREACHED(); - } -} - -bool BookmarkContextMenu::IsItemChecked(int id) const { - DCHECK(id == IDS_BOOMARK_BAR_ALWAYS_SHOW); - return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); -} - -bool BookmarkContextMenu::IsCommandEnabled(int id) const { - bool is_root_node = - (selection_.size() == 1 && - selection_[0]->GetParent() == model_->root_node()); - switch (id) { - case IDS_BOOMARK_BAR_OPEN_INCOGNITO: - return !profile_->IsOffTheRecord(); - - case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: - return HasURLs() && !profile_->IsOffTheRecord(); - - case IDS_BOOMARK_BAR_OPEN_ALL: - case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: - return HasURLs(); - - case IDS_BOOKMARK_BAR_RENAME_FOLDER: - case IDS_BOOKMARK_BAR_EDIT: - return selection_.size() == 1 && !is_root_node; - - case IDS_BOOKMARK_BAR_REMOVE: - return !selection_.empty() && !is_root_node; - - case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: - return (configuration_ == BOOKMARK_MANAGER_TABLE_OTHER || - configuration_ == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) && - selection_.size() == 1; - - case IDS_BOOKMARK_MANAGER_SORT: - return parent_ && parent_ != model_->root_node(); - - case IDS_BOOMARK_BAR_NEW_FOLDER: - case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: - return GetParentForNewNodes() != NULL; - - case IDS_COPY: - case IDS_CUT: - return selection_.size() > 0 && !is_root_node; - - case IDS_PASTE: - // Always paste to parent. - return bookmark_utils::CanPasteFromClipboard(parent_); - } - return true; -} - -void BookmarkContextMenu::BookmarkModelBeingDeleted(BookmarkModel* model) { - ModelChanged(); -} - -void BookmarkContextMenu::BookmarkNodeMoved(BookmarkModel* model, - BookmarkNode* old_parent, - int old_index, - BookmarkNode* new_parent, - int new_index) { - ModelChanged(); -} - -void BookmarkContextMenu::BookmarkNodeAdded(BookmarkModel* model, - BookmarkNode* parent, - int index) { - ModelChanged(); -} - -void BookmarkContextMenu::BookmarkNodeRemoved(BookmarkModel* model, - BookmarkNode* parent, - int index, - BookmarkNode* node) { - ModelChanged(); -} - -void BookmarkContextMenu::BookmarkNodeChanged(BookmarkModel* model, - BookmarkNode* node) { - ModelChanged(); -} - -void BookmarkContextMenu::BookmarkNodeChildrenReordered(BookmarkModel* model, - BookmarkNode* node) { - ModelChanged(); -} - -void BookmarkContextMenu::ModelChanged() { - menu_->Cancel(); -} - -BookmarkModel* BookmarkContextMenu::RemoveModelObserver() { - BookmarkModel* model = model_; - model_->RemoveObserver(this); - model_ = NULL; - return model; -} - -bool BookmarkContextMenu::HasURLs() const { - for (size_t i = 0; i < selection_.size(); ++i) { - if (NodeHasURLs(selection_[i])) - return true; - } - return false; -} - -BookmarkNode* BookmarkContextMenu::GetParentForNewNodes() const { - return (selection_.size() == 1 && selection_[0]->is_folder()) ? - selection_[0] : parent_; -} diff --git a/chrome/browser/bookmarks/bookmark_context_menu.h b/chrome/browser/bookmarks/bookmark_context_menu.h deleted file mode 100644 index 9903f44..0000000 --- a/chrome/browser/bookmarks/bookmark_context_menu.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ -#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ - -#include - -#include "base/basictypes.h" -#include "base/gfx/native_widget_types.h" -#include "chrome/browser/bookmarks/bookmark_model.h" - -// TODO(port): Port this file. -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) -#include "views/controls/menu/chrome_menu.h" -#elif defined(OS_LINUX) -#include "chrome/browser/gtk/menu_gtk.h" -#else -#include "chrome/common/temp_scaffolding_stubs.h" -#endif - -class Browser; -class PageNavigator; - -// BookmarkContextMenu manages the context menu shown for the -// bookmark bar, items on the bookmark bar, submenus of the bookmark bar and -// the bookmark manager. -class BookmarkContextMenu : public BookmarkModelObserver, -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) - public views::MenuDelegate -#elif defined(OS_LINUX) - public MenuGtk::Delegate -#endif -{ - public: - // Used to configure what the context menu shows. - enum ConfigurationType { - BOOKMARK_BAR, - BOOKMARK_MANAGER_TABLE, - // Used when the source is the table in the bookmark manager and the table - // is showing recently bookmarked or searched. - BOOKMARK_MANAGER_TABLE_OTHER, - BOOKMARK_MANAGER_TREE, - BOOKMARK_MANAGER_ORGANIZE_MENU, - // Used when the source is the bookmark manager and the table is showing - // recently bookmarked or searched. - BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER - }; - - // Creates the bookmark context menu. - // |profile| is used for opening urls as well as enabling 'open incognito'. - // |browser| is used to determine the PageNavigator and may be null. - // |navigator| is used if |browser| is null, and is provided for testing. - // |parent| is the parent for newly created nodes if |selection| is empty. - // |selection| is the nodes the context menu operates on and may be empty. - // |configuration| determines which items to show. - BookmarkContextMenu(gfx::NativeView hwnd, - Profile* profile, - Browser* browser, - PageNavigator* navigator, - BookmarkNode* parent, - const std::vector& selection, - ConfigurationType configuration); - virtual ~BookmarkContextMenu(); - -#if defined(TOOLKIT_VIEWS) - // Shows the menu at the specified place. - void RunMenuAt(int x, int y); - - // Returns the menu. - views::MenuItemView* menu() const { return menu_.get(); } -#elif defined(OS_LINUX) - // Pops up this menu. This call doesn't block. - void PopupAsContext(guint32 event_time); - - // Returns the menu. - GtkWidget* menu() const { return menu_->widget(); } -#endif - - // Menu::Delegate / MenuGtk::Delegate methods. - virtual void ExecuteCommand(int id); - virtual bool IsItemChecked(int id) const; - virtual bool IsCommandEnabled(int id) const; - - private: - // BookmarkModelObserver method. Any change to the model results in closing - // the menu. - virtual void Loaded(BookmarkModel* model) {} - virtual void BookmarkModelBeingDeleted(BookmarkModel* model); - virtual void BookmarkNodeMoved(BookmarkModel* model, - BookmarkNode* old_parent, - int old_index, - BookmarkNode* new_parent, - int new_index); - virtual void BookmarkNodeAdded(BookmarkModel* model, - BookmarkNode* parent, - int index); - virtual void BookmarkNodeRemoved(BookmarkModel* model, - BookmarkNode* parent, - int index, - BookmarkNode* node); - virtual void BookmarkNodeChanged(BookmarkModel* model, - BookmarkNode* node); - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, - BookmarkNode* node) {} - virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, - BookmarkNode* node); - - // Invoked from the various bookmark model observer methods. Closes the menu. - void ModelChanged(); - - // Builds the platform specific menu object. - void CreateMenuObject(); - - // Adds a IDS_* style command to the menu. - void AppendItem(int id); - // Adds a IDS_* style command to the menu with a different localized string. - void AppendItem(int id, int localization_id); - // Adds a separator to the menu. - void AppendSeparator(); - // Adds a checkable item to the menu. - void AppendCheckboxItem(int id); - - // Removes the observer from the model and NULLs out model_. - BookmarkModel* RemoveModelObserver(); - - // Returns true if selection_ has at least one bookmark of type url. - bool HasURLs() const; - - // Returns the parent for newly created folders/bookmarks. If selection_ - // has one element and it is a folder, selection_[0] is returned, otherwise - // parent_ is returned. - BookmarkNode* GetParentForNewNodes() const; - - gfx::NativeView wnd_; - Profile* profile_; - Browser* browser_; - PageNavigator* navigator_; - BookmarkNode* parent_; - std::vector selection_; - BookmarkModel* model_; - ConfigurationType configuration_; - -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) - scoped_ptr menu_; -#elif defined(OS_LINUX) - scoped_ptr menu_; -#endif - - DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenu); -}; - -#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ diff --git a/chrome/browser/bookmarks/bookmark_context_menu_gtk.cc b/chrome/browser/bookmarks/bookmark_context_menu_gtk.cc deleted file mode 100644 index 2b2181b..0000000 --- a/chrome/browser/bookmarks/bookmark_context_menu_gtk.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2009 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/bookmarks/bookmark_context_menu.h" - -#include "app/l10n_util.h" - -void BookmarkContextMenu::PopupAsContext(guint32 event_time) { - menu_->PopupAsContext(event_time); -} - -void BookmarkContextMenu::CreateMenuObject() { - menu_.reset(new MenuGtk(this, false)); -} - -void BookmarkContextMenu::AppendItem(int id) { - menu_->AppendMenuItemWithLabel(id, l10n_util::GetStringUTF8(id)); -} - -void BookmarkContextMenu::AppendItem(int id, int localization_id) { - menu_->AppendMenuItemWithLabel(id, l10n_util::GetStringUTF8(localization_id)); -} - -void BookmarkContextMenu::AppendSeparator() { - menu_->AppendSeparator(); -} - -void BookmarkContextMenu::AppendCheckboxItem(int id) { - menu_->AppendCheckMenuItemWithLabel(id, l10n_util::GetStringUTF8(id)); -} diff --git a/chrome/browser/bookmarks/bookmark_context_menu_test.cc b/chrome/browser/bookmarks/bookmark_context_menu_test.cc deleted file mode 100644 index d11d14a..0000000 --- a/chrome/browser/bookmarks/bookmark_context_menu_test.cc +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) 2006-2008 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/bookmarks/bookmark_context_menu.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/profile.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/test/testing_profile.h" -#include "grit/generated_resources.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_WIN) -#include "chrome/browser/views/bookmark_bar_view.h" -#endif - -namespace { - -// PageNavigator implementation that records the URL. -class TestingPageNavigator : public PageNavigator { - public: - virtual void OpenURL(const GURL& url, - const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - urls_.push_back(url); - } - - std::vector urls_; -}; - -} // namespace - -class BookmarkContextMenuTest : public testing::Test { - public: - BookmarkContextMenuTest() - : model_(NULL) { - } - - virtual void SetUp() { -#if defined(OS_WIN) - BookmarkBarView::testing_ = true; -#endif - - profile_.reset(new TestingProfile()); - profile_->set_has_history_service(true); - profile_->CreateBookmarkModel(true); - profile_->BlockUntilBookmarkModelLoaded(); - - model_ = profile_->GetBookmarkModel(); - - AddTestData(); - } - - virtual void TearDown() { -#if defined(OS_WIN) - BookmarkBarView::testing_ = false; -#endif - - // Flush the message loop to make Purify happy. - message_loop_.RunAllPending(); - } - - protected: - MessageLoopForUI message_loop_; - scoped_ptr profile_; - BookmarkModel* model_; - TestingPageNavigator navigator_; - - private: - // Creates the following structure: - // a - // F1 - // f1a - // F11 - // f11a - // F2 - // F3 - // F4 - // f4a - void AddTestData() { - std::string test_base = "file:///c:/tmp/"; - - model_->AddURL(model_->GetBookmarkBarNode(), 0, L"a", - GURL(test_base + "a")); - BookmarkNode* f1 = - model_->AddGroup(model_->GetBookmarkBarNode(), 1, L"F1"); - model_->AddURL(f1, 0, L"f1a", GURL(test_base + "f1a")); - BookmarkNode* f11 = model_->AddGroup(f1, 1, L"F11"); - model_->AddURL(f11, 0, L"f11a", GURL(test_base + "f11a")); - model_->AddGroup(model_->GetBookmarkBarNode(), 2, L"F2"); - model_->AddGroup(model_->GetBookmarkBarNode(), 3, L"F3"); - BookmarkNode* f4 = - model_->AddGroup(model_->GetBookmarkBarNode(), 4, L"F4"); - model_->AddURL(f4, 0, L"f4a", GURL(test_base + "f4a")); - } -}; - -// Tests Deleting from the menu. -TEST_F(BookmarkContextMenuTest, DeleteURL) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), nodes, - BookmarkContextMenu::BOOKMARK_BAR); - GURL url = model_->GetBookmarkBarNode()->GetChild(0)->GetURL(); - ASSERT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - // Delete the URL. - controller.ExecuteCommand(IDS_BOOKMARK_BAR_REMOVE); - // Model shouldn't have URL anymore. - ASSERT_FALSE(model_->IsBookmarked(url)); -} - -// Tests open all on a folder with a couple of bookmarks. -TEST_F(BookmarkContextMenuTest, OpenAll) { - BookmarkNode* folder = model_->GetBookmarkBarNode()->GetChild(1); - bookmark_utils::OpenAll( - NULL, profile_.get(), &navigator_, folder, NEW_FOREGROUND_TAB); - - // Should have navigated to F1's children. - ASSERT_EQ(static_cast(2), navigator_.urls_.size()); - ASSERT_TRUE(folder->GetChild(0)->GetURL() == navigator_.urls_[0]); - ASSERT_TRUE(folder->GetChild(1)->GetChild(0)->GetURL() == - navigator_.urls_[1]); -} - -// Tests the enabled state of the menus when supplied an empty vector. -TEST_F(BookmarkContextMenuTest, EmptyNodes) { - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, model_->other_node(), - std::vector(), BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with a single -// url. -TEST_F(BookmarkContextMenuTest, SingleURL) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// urls. -TEST_F(BookmarkContextMenuTest, MultipleURLs) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(1)->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied an vector with a single -// folder. -TEST_F(BookmarkContextMenuTest, SingleFolder) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// folders, all of which are empty. -TEST_F(BookmarkContextMenuTest, MultipleEmptyFolders) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of the menus when supplied a vector with multiple -// folders, some of which contain URLs. -TEST_F(BookmarkContextMenuTest, MultipleFoldersWithURLs) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(4)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_TRUE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} - -// Tests the enabled state of open incognito. -TEST_F(BookmarkContextMenuTest, DisableIncognito) { - std::vector nodes; - nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), - nodes, BookmarkContextMenu::BOOKMARK_BAR); - profile_->set_off_the_record(true); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); -} - -// Tests that you can't remove/edit when showing the other node. -TEST_F(BookmarkContextMenuTest, DisabledItemsWithOtherNode) { - std::vector nodes; - nodes.push_back(model_->other_node()); - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, nodes[0], nodes, - BookmarkContextMenu::BOOKMARK_BAR); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_EDIT)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); -} - -// Tests the enabled state of the menus when supplied an empty vector and null -// parent. -TEST_F(BookmarkContextMenuTest, EmptyNodesNullParent) { - BookmarkContextMenu controller( - NULL, profile_.get(), NULL, NULL, NULL, std::vector(), - BookmarkContextMenu::BOOKMARK_MANAGER_ORGANIZE_MENU); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); - EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); - EXPECT_FALSE( - controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); -} diff --git a/chrome/browser/bookmarks/bookmark_context_menu_views.cc b/chrome/browser/bookmarks/bookmark_context_menu_views.cc deleted file mode 100644 index 9baf3b9..0000000 --- a/chrome/browser/bookmarks/bookmark_context_menu_views.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2009 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/bookmarks/bookmark_context_menu.h" - -#include "app/l10n_util.h" - -void BookmarkContextMenu::RunMenuAt(int x, int y) { - if (!model_->IsLoaded()) { - NOTREACHED(); - return; - } - // width/height don't matter here. - views::MenuItemView::AnchorPosition anchor = - (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ? - views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT; - menu_->RunMenuAt(wnd_, gfx::Rect(x, y, 0, 0), anchor, true); -} - -void BookmarkContextMenu::CreateMenuObject() { - menu_.reset(new views::MenuItemView(this)); -} - -void BookmarkContextMenu::AppendItem(int id) { - menu_->AppendMenuItemWithLabel( - id, l10n_util::GetString(id)); -} - -void BookmarkContextMenu::AppendItem(int id, int localization_id) { - menu_->AppendMenuItemWithLabel( - id, l10n_util::GetString(localization_id)); -} - -void BookmarkContextMenu::AppendSeparator() { - menu_->AppendSeparator(); -} - -void BookmarkContextMenu::AppendCheckboxItem(int id) { - menu_->AppendMenuItem(id, - l10n_util::GetString(id), - views::MenuItemView::CHECKBOX); -} diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index 37f654e..183c12d 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -11,10 +11,10 @@ #include "app/resource_bundle.h" #include "base/gfx/gtk_util.h" #include "base/pickle.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_drag_data.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" +#include "chrome/browser/gtk/bookmark_context_menu.h" #include "chrome/browser/gtk/bookmark_menu_controller_gtk.h" #include "chrome/browser/gtk/bookmark_tree_model.h" #include "chrome/browser/gtk/bookmark_utils_gtk.h" diff --git a/chrome/browser/gtk/bookmark_context_menu.cc b/chrome/browser/gtk/bookmark_context_menu.cc new file mode 100644 index 0000000..ff92135 --- /dev/null +++ b/chrome/browser/gtk/bookmark_context_menu.cc @@ -0,0 +1,557 @@ +// Copyright (c) 2009 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/gtk/bookmark_context_menu.h" + +#include "app/l10n_util.h" +#include "base/compiler_specific.h" +#include "chrome/browser/bookmarks/bookmark_editor.h" +#include "chrome/browser/bookmarks/bookmark_manager.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/input_window_dialog.h" +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/page_navigator.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "grit/generated_resources.h" + +// TODO(port): Port these files. +#if defined(OS_WIN) +#include "views/window/window.h" +#endif + +namespace { + +// Returns true if the specified node is of type URL, or has a descendant +// of type URL. +bool NodeHasURLs(BookmarkNode* node) { + if (node->is_url()) + return true; + + for (int i = 0; i < node->GetChildCount(); ++i) { + if (NodeHasURLs(node->GetChild(i))) + return true; + } + return false; +} + +// EditFolderController ------------------------------------------------------- + +// EditFolderController manages the editing and/or creation of a folder. If the +// user presses ok, the name change is committed to the model. +// +// EditFolderController deletes itself when the window is closed. +class EditFolderController : public InputWindowDialog::Delegate, + public BookmarkModelObserver { + public: + virtual ~EditFolderController() { + if (model_) + model_->RemoveObserver(this); + } + + static void Show(Profile* profile, + gfx::NativeView wnd, + BookmarkNode* node, + bool is_new, + bool show_in_manager) { + // EditFolderController deletes itself when done. + EditFolderController* controller = + new EditFolderController(profile, wnd, node, is_new, show_in_manager); + controller->Show(); + } + + private: + EditFolderController(Profile* profile, + gfx::NativeView wnd, + BookmarkNode* node, + bool is_new, + bool show_in_manager) + : profile_(profile), + model_(profile->GetBookmarkModel()), + node_(node), + is_new_(is_new), + show_in_manager_(show_in_manager) { + DCHECK(is_new_ || node); + + std::wstring title = is_new_ ? + l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE_NEW) : + l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE); + std::wstring label = + l10n_util::GetString(IDS_BOOMARK_BAR_EDIT_FOLDER_LABEL); + std::wstring contents = is_new_ ? + l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME) : + node_->GetTitle(); + + dialog_ = InputWindowDialog::Create(wnd, title, label, contents, this); + model_->AddObserver(this); + } + + void Show() { + dialog_->Show(); + } + + // InputWindowDialog::Delegate methods. + virtual bool IsValid(const std::wstring& text) { + return !text.empty(); + } + + virtual void InputAccepted(const std::wstring& text) { + if (is_new_) { + ALLOW_UNUSED BookmarkNode* node = + model_->AddGroup(node_, node_->GetChildCount(), text); + if (show_in_manager_) { +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::SelectInTree(profile_, node); +#else + NOTIMPLEMENTED() << "BookmarkManager not yet implemented"; +#endif + } + } else { + model_->SetTitle(node_, text); + } + } + + virtual void InputCanceled() { + } + + // BookmarkModelObserver methods, all invoke ModelChanged and close the + // dialog. + virtual void Loaded(BookmarkModel* model) {} + virtual void BookmarkModelBeingDeleted(BookmarkModel* model) { + model_->RemoveObserver(this); + model_ = NULL; + ModelChanged(); + } + + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + ModelChanged(); + } + + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + ModelChanged(); + } + + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + ModelChanged(); + } + + virtual void BookmarkNodeChanged(BookmarkModel* model, BookmarkNode* node) { + ModelChanged(); + } + + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) {} + + virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); + } + + void ModelChanged() { + dialog_->Close(); + } + + Profile* profile_; + BookmarkModel* model_; + // If is_new is true, this is the parent to create the new node under. + // Otherwise this is the node to change the title of. + BookmarkNode* node_; + + bool is_new_; + + // If is_new_ is true and a new node is created, it is selected in the + // bookmark manager. + bool show_in_manager_; + InputWindowDialog* dialog_; + + DISALLOW_COPY_AND_ASSIGN(EditFolderController); +}; + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) +// SelectOnCreationHandler ---------------------------------------------------- + +// Used when adding a new bookmark. If a new bookmark is created it is selected +// in the bookmark manager. +class SelectOnCreationHandler : public BookmarkEditor::Handler { + public: + explicit SelectOnCreationHandler(Profile* profile) : profile_(profile) { + } + + virtual void NodeCreated(BookmarkNode* new_node) { + BookmarkManager::SelectInTree(profile_, new_node); + } + + private: + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(SelectOnCreationHandler); +}; +#endif // #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + +} // namespace + +// BookmarkContextMenu ------------------------------------------- + +BookmarkContextMenu::BookmarkContextMenu( + gfx::NativeView wnd, + Profile* profile, + Browser* browser, + PageNavigator* navigator, + BookmarkNode* parent, + const std::vector& selection, + ConfigurationType configuration) + : wnd_(wnd), + profile_(profile), + browser_(browser), + navigator_(navigator), + parent_(parent), + selection_(selection), + model_(profile->GetBookmarkModel()), + configuration_(configuration) { + DCHECK(profile_); + DCHECK(model_->IsLoaded()); + CreateMenuObject(); + + if (configuration != BOOKMARK_MANAGER_ORGANIZE_MENU) { + if (selection.size() == 1 && selection[0]->is_url()) { + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, + IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, + IDS_BOOMARK_BAR_OPEN_INCOGNITO); + } else { + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_ALL); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, + IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, + IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO); + } + AppendSeparator(); + } + + if (selection.size() == 1 && selection[0]->is_folder()) { + AppendItem(IDS_BOOKMARK_BAR_RENAME_FOLDER); + } else { + AppendItem(IDS_BOOKMARK_BAR_EDIT); + } + AppendItem(IDS_BOOKMARK_BAR_REMOVE); + + if (configuration == BOOKMARK_MANAGER_TABLE || + configuration == BOOKMARK_MANAGER_TABLE_OTHER || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { + AppendItem(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER); + } + + if (configuration == BOOKMARK_MANAGER_TABLE || + configuration == BOOKMARK_MANAGER_TABLE_OTHER || + configuration == BOOKMARK_MANAGER_TREE || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { + AppendSeparator(); + AppendItem(IDS_CUT); + AppendItem(IDS_COPY); + AppendItem(IDS_PASTE); + } + + if (configuration == BOOKMARK_MANAGER_ORGANIZE_MENU) { + AppendSeparator(); + AppendItem(IDS_BOOKMARK_MANAGER_SORT); + } + + AppendSeparator(); + + AppendItem(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK); + AppendItem(IDS_BOOMARK_BAR_NEW_FOLDER); + + if (configuration == BOOKMARK_BAR) { + AppendSeparator(); + AppendItem(IDS_BOOKMARK_MANAGER); + AppendCheckboxItem(IDS_BOOMARK_BAR_ALWAYS_SHOW); + } + + model_->AddObserver(this); +} + +BookmarkContextMenu::~BookmarkContextMenu() { + if (model_) + model_->RemoveObserver(this); +} + +void BookmarkContextMenu::ExecuteCommand(int id) { + switch (id) { + case IDS_BOOMARK_BAR_OPEN_ALL: + case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: + case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: { + PageNavigator* navigator = browser_ ? + browser_->GetSelectedTabContents() : navigator_; + WindowOpenDisposition initial_disposition; + if (id == IDS_BOOMARK_BAR_OPEN_ALL) { + initial_disposition = NEW_FOREGROUND_TAB; + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_OpenAll", + profile_); + } else if (id == IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW) { + initial_disposition = NEW_WINDOW; + UserMetrics::RecordAction( + L"BookmarkBar_ContextMenu_OpenAllInNewWindow", profile_); + } else { + initial_disposition = OFF_THE_RECORD; + UserMetrics::RecordAction( + L"BookmarkBar_ContextMenu_OpenAllIncognito", profile_); + } + + bookmark_utils::OpenAll(wnd_, profile_, navigator, selection_, + initial_disposition); + break; + } + + case IDS_BOOKMARK_BAR_RENAME_FOLDER: + case IDS_BOOKMARK_BAR_EDIT: + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Edit", profile_); + + if (selection_.size() != 1) { + NOTREACHED(); + return; + } + + if (selection_[0]->is_url()) { +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkEditor::Configuration editor_config; + if (configuration_ == BOOKMARK_BAR) + editor_config = BookmarkEditor::SHOW_TREE; + else + editor_config = BookmarkEditor::NO_TREE; + BookmarkEditor::Show(wnd_, profile_, NULL, selection_[0], + editor_config, NULL); +#else + NOTIMPLEMENTED(); +#endif + } else { + EditFolderController::Show(profile_, wnd_, selection_[0], false, + false); + } + break; + + case IDS_BOOKMARK_BAR_REMOVE: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Remove", profile_); + BookmarkModel* model = RemoveModelObserver(); + + for (size_t i = 0; i < selection_.size(); ++i) { + model->Remove(selection_[i]->GetParent(), + selection_[i]->GetParent()->IndexOfChild(selection_[i])); + } + selection_.clear(); + break; + } + + case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Add", profile_); + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkEditor::Configuration editor_config; + BookmarkEditor::Handler* handler = NULL; + if (configuration_ == BOOKMARK_BAR) { + editor_config = BookmarkEditor::SHOW_TREE; + } else { + editor_config = BookmarkEditor::NO_TREE; + // This is owned by the BookmarkEditorView. + handler = new SelectOnCreationHandler(profile_); + } + BookmarkEditor::Show(wnd_, profile_, GetParentForNewNodes(), NULL, + editor_config, handler); +#else + NOTIMPLEMENTED(); +#endif + break; + } + + case IDS_BOOMARK_BAR_NEW_FOLDER: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_NewFolder", + profile_); + EditFolderController::Show(profile_, wnd_, GetParentForNewNodes(), + true, (configuration_ != BOOKMARK_BAR)); + break; + } + + case IDS_BOOMARK_BAR_ALWAYS_SHOW: + bookmark_utils::ToggleWhenVisible(profile_); + break; + + case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_ShowInFolder", + profile_); + + if (selection_.size() != 1) { + NOTREACHED(); + return; + } + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::SelectInTree(profile_, selection_[0]); +#else + NOTIMPLEMENTED() << "Bookmark Manager not implemented"; +#endif + break; + + case IDS_BOOKMARK_MANAGER: + UserMetrics::RecordAction(L"ShowBookmarkManager", profile_); +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::Show(profile_); +#else + NOTIMPLEMENTED() << "Bookmark Manager not implemented"; +#endif + break; + + case IDS_BOOKMARK_MANAGER_SORT: + UserMetrics::RecordAction(L"BookmarkManager_Sort", profile_); + model_->SortChildren(parent_); + break; + + case IDS_COPY: + case IDS_CUT: + bookmark_utils::CopyToClipboard(profile_->GetBookmarkModel(), + selection_, id == IDS_CUT); + break; + + case IDS_PASTE: { + // Always paste to parent. + if (!parent_) + return; + + int index = (selection_.size() == 1) ? + parent_->IndexOfChild(selection_[0]) : -1; + if (index != -1) + index++; + bookmark_utils::PasteFromClipboard(profile_->GetBookmarkModel(), + parent_, index); + break; + } + + default: + NOTREACHED(); + } +} + +bool BookmarkContextMenu::IsItemChecked(int id) const { + DCHECK(id == IDS_BOOMARK_BAR_ALWAYS_SHOW); + return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); +} + +bool BookmarkContextMenu::IsCommandEnabled(int id) const { + bool is_root_node = + (selection_.size() == 1 && + selection_[0]->GetParent() == model_->root_node()); + switch (id) { + case IDS_BOOMARK_BAR_OPEN_INCOGNITO: + return !profile_->IsOffTheRecord(); + + case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: + return HasURLs() && !profile_->IsOffTheRecord(); + + case IDS_BOOMARK_BAR_OPEN_ALL: + case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: + return HasURLs(); + + case IDS_BOOKMARK_BAR_RENAME_FOLDER: + case IDS_BOOKMARK_BAR_EDIT: + return selection_.size() == 1 && !is_root_node; + + case IDS_BOOKMARK_BAR_REMOVE: + return !selection_.empty() && !is_root_node; + + case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: + return (configuration_ == BOOKMARK_MANAGER_TABLE_OTHER || + configuration_ == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) && + selection_.size() == 1; + + case IDS_BOOKMARK_MANAGER_SORT: + return parent_ && parent_ != model_->root_node(); + + case IDS_BOOMARK_BAR_NEW_FOLDER: + case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: + return GetParentForNewNodes() != NULL; + + case IDS_COPY: + case IDS_CUT: + return selection_.size() > 0 && !is_root_node; + + case IDS_PASTE: + // Always paste to parent. + return bookmark_utils::CanPasteFromClipboard(parent_); + } + return true; +} + +void BookmarkContextMenu::BookmarkModelBeingDeleted(BookmarkModel* model) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::ModelChanged() { + menu_->Cancel(); +} + +BookmarkModel* BookmarkContextMenu::RemoveModelObserver() { + BookmarkModel* model = model_; + model_->RemoveObserver(this); + model_ = NULL; + return model; +} + +bool BookmarkContextMenu::HasURLs() const { + for (size_t i = 0; i < selection_.size(); ++i) { + if (NodeHasURLs(selection_[i])) + return true; + } + return false; +} + +BookmarkNode* BookmarkContextMenu::GetParentForNewNodes() const { + return (selection_.size() == 1 && selection_[0]->is_folder()) ? + selection_[0] : parent_; +} diff --git a/chrome/browser/gtk/bookmark_context_menu.h b/chrome/browser/gtk/bookmark_context_menu.h new file mode 100644 index 0000000..38dc37a --- /dev/null +++ b/chrome/browser/gtk/bookmark_context_menu.h @@ -0,0 +1,154 @@ +// Copyright (c) 2006-2008 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. + +#ifndef CHROME_BROWSER_GTK_BOOKMARK_CONTEXT_MENU_H_ +#define CHROME_BROWSER_GTK_BOOKMARK_CONTEXT_MENU_H_ + +#include + +#include "base/basictypes.h" +#include "base/gfx/native_widget_types.h" +#include "chrome/browser/bookmarks/bookmark_model.h" + +// TODO(port): Port this file. +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#include "views/controls/menu/chrome_menu.h" +#elif defined(OS_LINUX) +#include "chrome/browser/gtk/menu_gtk.h" +#else +#include "chrome/common/temp_scaffolding_stubs.h" +#endif + +class Browser; +class PageNavigator; + +// BookmarkContextMenu manages the context menu shown for the +// bookmark bar, items on the bookmark bar, submenus of the bookmark bar and +// the bookmark manager. +class BookmarkContextMenu : public BookmarkModelObserver, +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) + public views::MenuDelegate +#elif defined(OS_LINUX) + public MenuGtk::Delegate +#endif +{ + public: + // Used to configure what the context menu shows. + enum ConfigurationType { + BOOKMARK_BAR, + BOOKMARK_MANAGER_TABLE, + // Used when the source is the table in the bookmark manager and the table + // is showing recently bookmarked or searched. + BOOKMARK_MANAGER_TABLE_OTHER, + BOOKMARK_MANAGER_TREE, + BOOKMARK_MANAGER_ORGANIZE_MENU, + // Used when the source is the bookmark manager and the table is showing + // recently bookmarked or searched. + BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER + }; + + // Creates the bookmark context menu. + // |profile| is used for opening urls as well as enabling 'open incognito'. + // |browser| is used to determine the PageNavigator and may be null. + // |navigator| is used if |browser| is null, and is provided for testing. + // |parent| is the parent for newly created nodes if |selection| is empty. + // |selection| is the nodes the context menu operates on and may be empty. + // |configuration| determines which items to show. + BookmarkContextMenu(gfx::NativeView hwnd, + Profile* profile, + Browser* browser, + PageNavigator* navigator, + BookmarkNode* parent, + const std::vector& selection, + ConfigurationType configuration); + virtual ~BookmarkContextMenu(); + +#if defined(TOOLKIT_VIEWS) + // Shows the menu at the specified place. + void RunMenuAt(int x, int y); + + // Returns the menu. + views::MenuItemView* menu() const { return menu_.get(); } +#elif defined(OS_LINUX) + // Pops up this menu. This call doesn't block. + void PopupAsContext(guint32 event_time); + + // Returns the menu. + GtkWidget* menu() const { return menu_->widget(); } +#endif + + // Menu::Delegate / MenuGtk::Delegate methods. + virtual void ExecuteCommand(int id); + virtual bool IsItemChecked(int id) const; + virtual bool IsCommandEnabled(int id) const; + + private: + // BookmarkModelObserver method. Any change to the model results in closing + // the menu. + virtual void Loaded(BookmarkModel* model) {} + virtual void BookmarkModelBeingDeleted(BookmarkModel* model); + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index); + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index); + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node); + virtual void BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node); + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) {} + virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node); + + // Invoked from the various bookmark model observer methods. Closes the menu. + void ModelChanged(); + + // Builds the platform specific menu object. + void CreateMenuObject(); + + // Adds a IDS_* style command to the menu. + void AppendItem(int id); + // Adds a IDS_* style command to the menu with a different localized string. + void AppendItem(int id, int localization_id); + // Adds a separator to the menu. + void AppendSeparator(); + // Adds a checkable item to the menu. + void AppendCheckboxItem(int id); + + // Removes the observer from the model and NULLs out model_. + BookmarkModel* RemoveModelObserver(); + + // Returns true if selection_ has at least one bookmark of type url. + bool HasURLs() const; + + // Returns the parent for newly created folders/bookmarks. If selection_ + // has one element and it is a folder, selection_[0] is returned, otherwise + // parent_ is returned. + BookmarkNode* GetParentForNewNodes() const; + + gfx::NativeView wnd_; + Profile* profile_; + Browser* browser_; + PageNavigator* navigator_; + BookmarkNode* parent_; + std::vector selection_; + BookmarkModel* model_; + ConfigurationType configuration_; + +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) + scoped_ptr menu_; +#elif defined(OS_LINUX) + scoped_ptr menu_; +#endif + + DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenu); +}; + +#endif // CHROME_BROWSER_GTK_BOOKMARK_CONTEXT_MENU_H_ diff --git a/chrome/browser/gtk/bookmark_context_menu_gtk.cc b/chrome/browser/gtk/bookmark_context_menu_gtk.cc new file mode 100644 index 0000000..fc8f73b --- /dev/null +++ b/chrome/browser/gtk/bookmark_context_menu_gtk.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2009 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/gtk/bookmark_context_menu.h" + +#include "app/l10n_util.h" + +void BookmarkContextMenu::PopupAsContext(guint32 event_time) { + menu_->PopupAsContext(event_time); +} + +void BookmarkContextMenu::CreateMenuObject() { + menu_.reset(new MenuGtk(this, false)); +} + +void BookmarkContextMenu::AppendItem(int id) { + menu_->AppendMenuItemWithLabel(id, l10n_util::GetStringUTF8(id)); +} + +void BookmarkContextMenu::AppendItem(int id, int localization_id) { + menu_->AppendMenuItemWithLabel(id, l10n_util::GetStringUTF8(localization_id)); +} + +void BookmarkContextMenu::AppendSeparator() { + menu_->AppendSeparator(); +} + +void BookmarkContextMenu::AppendCheckboxItem(int id) { + menu_->AppendCheckMenuItemWithLabel(id, l10n_util::GetStringUTF8(id)); +} diff --git a/chrome/browser/gtk/bookmark_manager_gtk.h b/chrome/browser/gtk/bookmark_manager_gtk.h index da797b1..d7d802e8 100644 --- a/chrome/browser/gtk/bookmark_manager_gtk.h +++ b/chrome/browser/gtk/bookmark_manager_gtk.h @@ -11,8 +11,8 @@ #include "app/table_model_observer.h" #include "base/ref_counted.h" #include "base/task.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/gtk/bookmark_context_menu.h" #include "chrome/browser/shell_dialogs.h" class BookmarkModel; diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc index e5ee526..68b4ffdf 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc @@ -10,7 +10,7 @@ #include "app/resource_bundle.h" #include "base/gfx/gtk_util.h" #include "base/string_util.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" +#include "chrome/browser/gtk/bookmark_context_menu.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/page_navigator.h" diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index adbd864..0483ca6 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -12,7 +12,6 @@ #include "app/os_exchange_data.h" #include "app/resource_bundle.h" #include "base/string_util.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_theme_provider.h" @@ -23,6 +22,7 @@ #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/view_ids.h" +#include "chrome/browser/views/bookmark_context_menu.h" #include "chrome/browser/views/event_utils.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/location_bar_view.h" diff --git a/chrome/browser/views/bookmark_context_menu.cc b/chrome/browser/views/bookmark_context_menu.cc new file mode 100644 index 0000000..a29336b --- /dev/null +++ b/chrome/browser/views/bookmark_context_menu.cc @@ -0,0 +1,557 @@ +// Copyright (c) 2009 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/views/bookmark_context_menu.h" + +#include "app/l10n_util.h" +#include "base/compiler_specific.h" +#include "chrome/browser/bookmarks/bookmark_editor.h" +#include "chrome/browser/bookmarks/bookmark_manager.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/input_window_dialog.h" +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/page_navigator.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "grit/generated_resources.h" + +// TODO(port): Port these files. +#if defined(OS_WIN) +#include "views/window/window.h" +#endif + +namespace { + +// Returns true if the specified node is of type URL, or has a descendant +// of type URL. +bool NodeHasURLs(BookmarkNode* node) { + if (node->is_url()) + return true; + + for (int i = 0; i < node->GetChildCount(); ++i) { + if (NodeHasURLs(node->GetChild(i))) + return true; + } + return false; +} + +// EditFolderController ------------------------------------------------------- + +// EditFolderController manages the editing and/or creation of a folder. If the +// user presses ok, the name change is committed to the model. +// +// EditFolderController deletes itself when the window is closed. +class EditFolderController : public InputWindowDialog::Delegate, + public BookmarkModelObserver { + public: + virtual ~EditFolderController() { + if (model_) + model_->RemoveObserver(this); + } + + static void Show(Profile* profile, + gfx::NativeView wnd, + BookmarkNode* node, + bool is_new, + bool show_in_manager) { + // EditFolderController deletes itself when done. + EditFolderController* controller = + new EditFolderController(profile, wnd, node, is_new, show_in_manager); + controller->Show(); + } + + private: + EditFolderController(Profile* profile, + gfx::NativeView wnd, + BookmarkNode* node, + bool is_new, + bool show_in_manager) + : profile_(profile), + model_(profile->GetBookmarkModel()), + node_(node), + is_new_(is_new), + show_in_manager_(show_in_manager) { + DCHECK(is_new_ || node); + + std::wstring title = is_new_ ? + l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE_NEW) : + l10n_util::GetString(IDS_BOOMARK_FOLDER_EDITOR_WINDOW_TITLE); + std::wstring label = + l10n_util::GetString(IDS_BOOMARK_BAR_EDIT_FOLDER_LABEL); + std::wstring contents = is_new_ ? + l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME) : + node_->GetTitle(); + + dialog_ = InputWindowDialog::Create(wnd, title, label, contents, this); + model_->AddObserver(this); + } + + void Show() { + dialog_->Show(); + } + + // InputWindowDialog::Delegate methods. + virtual bool IsValid(const std::wstring& text) { + return !text.empty(); + } + + virtual void InputAccepted(const std::wstring& text) { + if (is_new_) { + ALLOW_UNUSED BookmarkNode* node = + model_->AddGroup(node_, node_->GetChildCount(), text); + if (show_in_manager_) { +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::SelectInTree(profile_, node); +#else + NOTIMPLEMENTED() << "BookmarkManager not yet implemented"; +#endif + } + } else { + model_->SetTitle(node_, text); + } + } + + virtual void InputCanceled() { + } + + // BookmarkModelObserver methods, all invoke ModelChanged and close the + // dialog. + virtual void Loaded(BookmarkModel* model) {} + virtual void BookmarkModelBeingDeleted(BookmarkModel* model) { + model_->RemoveObserver(this); + model_ = NULL; + ModelChanged(); + } + + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + ModelChanged(); + } + + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + ModelChanged(); + } + + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + ModelChanged(); + } + + virtual void BookmarkNodeChanged(BookmarkModel* model, BookmarkNode* node) { + ModelChanged(); + } + + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) {} + + virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); + } + + void ModelChanged() { + dialog_->Close(); + } + + Profile* profile_; + BookmarkModel* model_; + // If is_new is true, this is the parent to create the new node under. + // Otherwise this is the node to change the title of. + BookmarkNode* node_; + + bool is_new_; + + // If is_new_ is true and a new node is created, it is selected in the + // bookmark manager. + bool show_in_manager_; + InputWindowDialog* dialog_; + + DISALLOW_COPY_AND_ASSIGN(EditFolderController); +}; + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) +// SelectOnCreationHandler ---------------------------------------------------- + +// Used when adding a new bookmark. If a new bookmark is created it is selected +// in the bookmark manager. +class SelectOnCreationHandler : public BookmarkEditor::Handler { + public: + explicit SelectOnCreationHandler(Profile* profile) : profile_(profile) { + } + + virtual void NodeCreated(BookmarkNode* new_node) { + BookmarkManager::SelectInTree(profile_, new_node); + } + + private: + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(SelectOnCreationHandler); +}; +#endif // #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + +} // namespace + +// BookmarkContextMenu ------------------------------------------- + +BookmarkContextMenu::BookmarkContextMenu( + gfx::NativeView wnd, + Profile* profile, + Browser* browser, + PageNavigator* navigator, + BookmarkNode* parent, + const std::vector& selection, + ConfigurationType configuration) + : wnd_(wnd), + profile_(profile), + browser_(browser), + navigator_(navigator), + parent_(parent), + selection_(selection), + model_(profile->GetBookmarkModel()), + configuration_(configuration) { + DCHECK(profile_); + DCHECK(model_->IsLoaded()); + CreateMenuObject(); + + if (configuration != BOOKMARK_MANAGER_ORGANIZE_MENU) { + if (selection.size() == 1 && selection[0]->is_url()) { + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, + IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, + IDS_BOOMARK_BAR_OPEN_INCOGNITO); + } else { + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_ALL); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW, + IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW); + AppendItem(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO, + IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO); + } + AppendSeparator(); + } + + if (selection.size() == 1 && selection[0]->is_folder()) { + AppendItem(IDS_BOOKMARK_BAR_RENAME_FOLDER); + } else { + AppendItem(IDS_BOOKMARK_BAR_EDIT); + } + AppendItem(IDS_BOOKMARK_BAR_REMOVE); + + if (configuration == BOOKMARK_MANAGER_TABLE || + configuration == BOOKMARK_MANAGER_TABLE_OTHER || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { + AppendItem(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER); + } + + if (configuration == BOOKMARK_MANAGER_TABLE || + configuration == BOOKMARK_MANAGER_TABLE_OTHER || + configuration == BOOKMARK_MANAGER_TREE || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU || + configuration == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) { + AppendSeparator(); + AppendItem(IDS_CUT); + AppendItem(IDS_COPY); + AppendItem(IDS_PASTE); + } + + if (configuration == BOOKMARK_MANAGER_ORGANIZE_MENU) { + AppendSeparator(); + AppendItem(IDS_BOOKMARK_MANAGER_SORT); + } + + AppendSeparator(); + + AppendItem(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK); + AppendItem(IDS_BOOMARK_BAR_NEW_FOLDER); + + if (configuration == BOOKMARK_BAR) { + AppendSeparator(); + AppendItem(IDS_BOOKMARK_MANAGER); + AppendCheckboxItem(IDS_BOOMARK_BAR_ALWAYS_SHOW); + } + + model_->AddObserver(this); +} + +BookmarkContextMenu::~BookmarkContextMenu() { + if (model_) + model_->RemoveObserver(this); +} + +void BookmarkContextMenu::ExecuteCommand(int id) { + switch (id) { + case IDS_BOOMARK_BAR_OPEN_ALL: + case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: + case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: { + PageNavigator* navigator = browser_ ? + browser_->GetSelectedTabContents() : navigator_; + WindowOpenDisposition initial_disposition; + if (id == IDS_BOOMARK_BAR_OPEN_ALL) { + initial_disposition = NEW_FOREGROUND_TAB; + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_OpenAll", + profile_); + } else if (id == IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW) { + initial_disposition = NEW_WINDOW; + UserMetrics::RecordAction( + L"BookmarkBar_ContextMenu_OpenAllInNewWindow", profile_); + } else { + initial_disposition = OFF_THE_RECORD; + UserMetrics::RecordAction( + L"BookmarkBar_ContextMenu_OpenAllIncognito", profile_); + } + + bookmark_utils::OpenAll(wnd_, profile_, navigator, selection_, + initial_disposition); + break; + } + + case IDS_BOOKMARK_BAR_RENAME_FOLDER: + case IDS_BOOKMARK_BAR_EDIT: + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Edit", profile_); + + if (selection_.size() != 1) { + NOTREACHED(); + return; + } + + if (selection_[0]->is_url()) { +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkEditor::Configuration editor_config; + if (configuration_ == BOOKMARK_BAR) + editor_config = BookmarkEditor::SHOW_TREE; + else + editor_config = BookmarkEditor::NO_TREE; + BookmarkEditor::Show(wnd_, profile_, NULL, selection_[0], + editor_config, NULL); +#else + NOTIMPLEMENTED(); +#endif + } else { + EditFolderController::Show(profile_, wnd_, selection_[0], false, + false); + } + break; + + case IDS_BOOKMARK_BAR_REMOVE: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Remove", profile_); + BookmarkModel* model = RemoveModelObserver(); + + for (size_t i = 0; i < selection_.size(); ++i) { + model->Remove(selection_[i]->GetParent(), + selection_[i]->GetParent()->IndexOfChild(selection_[i])); + } + selection_.clear(); + break; + } + + case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_Add", profile_); + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkEditor::Configuration editor_config; + BookmarkEditor::Handler* handler = NULL; + if (configuration_ == BOOKMARK_BAR) { + editor_config = BookmarkEditor::SHOW_TREE; + } else { + editor_config = BookmarkEditor::NO_TREE; + // This is owned by the BookmarkEditorView. + handler = new SelectOnCreationHandler(profile_); + } + BookmarkEditor::Show(wnd_, profile_, GetParentForNewNodes(), NULL, + editor_config, handler); +#else + NOTIMPLEMENTED(); +#endif + break; + } + + case IDS_BOOMARK_BAR_NEW_FOLDER: { + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_NewFolder", + profile_); + EditFolderController::Show(profile_, wnd_, GetParentForNewNodes(), + true, (configuration_ != BOOKMARK_BAR)); + break; + } + + case IDS_BOOMARK_BAR_ALWAYS_SHOW: + bookmark_utils::ToggleWhenVisible(profile_); + break; + + case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: + UserMetrics::RecordAction(L"BookmarkBar_ContextMenu_ShowInFolder", + profile_); + + if (selection_.size() != 1) { + NOTREACHED(); + return; + } + +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::SelectInTree(profile_, selection_[0]); +#else + NOTIMPLEMENTED() << "Bookmark Manager not implemented"; +#endif + break; + + case IDS_BOOKMARK_MANAGER: + UserMetrics::RecordAction(L"ShowBookmarkManager", profile_); +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) + BookmarkManager::Show(profile_); +#else + NOTIMPLEMENTED() << "Bookmark Manager not implemented"; +#endif + break; + + case IDS_BOOKMARK_MANAGER_SORT: + UserMetrics::RecordAction(L"BookmarkManager_Sort", profile_); + model_->SortChildren(parent_); + break; + + case IDS_COPY: + case IDS_CUT: + bookmark_utils::CopyToClipboard(profile_->GetBookmarkModel(), + selection_, id == IDS_CUT); + break; + + case IDS_PASTE: { + // Always paste to parent. + if (!parent_) + return; + + int index = (selection_.size() == 1) ? + parent_->IndexOfChild(selection_[0]) : -1; + if (index != -1) + index++; + bookmark_utils::PasteFromClipboard(profile_->GetBookmarkModel(), + parent_, index); + break; + } + + default: + NOTREACHED(); + } +} + +bool BookmarkContextMenu::IsItemChecked(int id) const { + DCHECK(id == IDS_BOOMARK_BAR_ALWAYS_SHOW); + return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); +} + +bool BookmarkContextMenu::IsCommandEnabled(int id) const { + bool is_root_node = + (selection_.size() == 1 && + selection_[0]->GetParent() == model_->root_node()); + switch (id) { + case IDS_BOOMARK_BAR_OPEN_INCOGNITO: + return !profile_->IsOffTheRecord(); + + case IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO: + return HasURLs() && !profile_->IsOffTheRecord(); + + case IDS_BOOMARK_BAR_OPEN_ALL: + case IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW: + return HasURLs(); + + case IDS_BOOKMARK_BAR_RENAME_FOLDER: + case IDS_BOOKMARK_BAR_EDIT: + return selection_.size() == 1 && !is_root_node; + + case IDS_BOOKMARK_BAR_REMOVE: + return !selection_.empty() && !is_root_node; + + case IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER: + return (configuration_ == BOOKMARK_MANAGER_TABLE_OTHER || + configuration_ == BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER) && + selection_.size() == 1; + + case IDS_BOOKMARK_MANAGER_SORT: + return parent_ && parent_ != model_->root_node(); + + case IDS_BOOMARK_BAR_NEW_FOLDER: + case IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK: + return GetParentForNewNodes() != NULL; + + case IDS_COPY: + case IDS_CUT: + return selection_.size() > 0 && !is_root_node; + + case IDS_PASTE: + // Always paste to parent. + return bookmark_utils::CanPasteFromClipboard(parent_); + } + return true; +} + +void BookmarkContextMenu::BookmarkModelBeingDeleted(BookmarkModel* model) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node) { + ModelChanged(); +} + +void BookmarkContextMenu::ModelChanged() { + menu_->Cancel(); +} + +BookmarkModel* BookmarkContextMenu::RemoveModelObserver() { + BookmarkModel* model = model_; + model_->RemoveObserver(this); + model_ = NULL; + return model; +} + +bool BookmarkContextMenu::HasURLs() const { + for (size_t i = 0; i < selection_.size(); ++i) { + if (NodeHasURLs(selection_[i])) + return true; + } + return false; +} + +BookmarkNode* BookmarkContextMenu::GetParentForNewNodes() const { + return (selection_.size() == 1 && selection_[0]->is_folder()) ? + selection_[0] : parent_; +} diff --git a/chrome/browser/views/bookmark_context_menu.h b/chrome/browser/views/bookmark_context_menu.h new file mode 100644 index 0000000..9903f44 --- /dev/null +++ b/chrome/browser/views/bookmark_context_menu.h @@ -0,0 +1,154 @@ +// Copyright (c) 2006-2008 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. + +#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ +#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ + +#include + +#include "base/basictypes.h" +#include "base/gfx/native_widget_types.h" +#include "chrome/browser/bookmarks/bookmark_model.h" + +// TODO(port): Port this file. +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#include "views/controls/menu/chrome_menu.h" +#elif defined(OS_LINUX) +#include "chrome/browser/gtk/menu_gtk.h" +#else +#include "chrome/common/temp_scaffolding_stubs.h" +#endif + +class Browser; +class PageNavigator; + +// BookmarkContextMenu manages the context menu shown for the +// bookmark bar, items on the bookmark bar, submenus of the bookmark bar and +// the bookmark manager. +class BookmarkContextMenu : public BookmarkModelObserver, +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) + public views::MenuDelegate +#elif defined(OS_LINUX) + public MenuGtk::Delegate +#endif +{ + public: + // Used to configure what the context menu shows. + enum ConfigurationType { + BOOKMARK_BAR, + BOOKMARK_MANAGER_TABLE, + // Used when the source is the table in the bookmark manager and the table + // is showing recently bookmarked or searched. + BOOKMARK_MANAGER_TABLE_OTHER, + BOOKMARK_MANAGER_TREE, + BOOKMARK_MANAGER_ORGANIZE_MENU, + // Used when the source is the bookmark manager and the table is showing + // recently bookmarked or searched. + BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER + }; + + // Creates the bookmark context menu. + // |profile| is used for opening urls as well as enabling 'open incognito'. + // |browser| is used to determine the PageNavigator and may be null. + // |navigator| is used if |browser| is null, and is provided for testing. + // |parent| is the parent for newly created nodes if |selection| is empty. + // |selection| is the nodes the context menu operates on and may be empty. + // |configuration| determines which items to show. + BookmarkContextMenu(gfx::NativeView hwnd, + Profile* profile, + Browser* browser, + PageNavigator* navigator, + BookmarkNode* parent, + const std::vector& selection, + ConfigurationType configuration); + virtual ~BookmarkContextMenu(); + +#if defined(TOOLKIT_VIEWS) + // Shows the menu at the specified place. + void RunMenuAt(int x, int y); + + // Returns the menu. + views::MenuItemView* menu() const { return menu_.get(); } +#elif defined(OS_LINUX) + // Pops up this menu. This call doesn't block. + void PopupAsContext(guint32 event_time); + + // Returns the menu. + GtkWidget* menu() const { return menu_->widget(); } +#endif + + // Menu::Delegate / MenuGtk::Delegate methods. + virtual void ExecuteCommand(int id); + virtual bool IsItemChecked(int id) const; + virtual bool IsCommandEnabled(int id) const; + + private: + // BookmarkModelObserver method. Any change to the model results in closing + // the menu. + virtual void Loaded(BookmarkModel* model) {} + virtual void BookmarkModelBeingDeleted(BookmarkModel* model); + virtual void BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index); + virtual void BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index); + virtual void BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index, + BookmarkNode* node); + virtual void BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node); + virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) {} + virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node); + + // Invoked from the various bookmark model observer methods. Closes the menu. + void ModelChanged(); + + // Builds the platform specific menu object. + void CreateMenuObject(); + + // Adds a IDS_* style command to the menu. + void AppendItem(int id); + // Adds a IDS_* style command to the menu with a different localized string. + void AppendItem(int id, int localization_id); + // Adds a separator to the menu. + void AppendSeparator(); + // Adds a checkable item to the menu. + void AppendCheckboxItem(int id); + + // Removes the observer from the model and NULLs out model_. + BookmarkModel* RemoveModelObserver(); + + // Returns true if selection_ has at least one bookmark of type url. + bool HasURLs() const; + + // Returns the parent for newly created folders/bookmarks. If selection_ + // has one element and it is a folder, selection_[0] is returned, otherwise + // parent_ is returned. + BookmarkNode* GetParentForNewNodes() const; + + gfx::NativeView wnd_; + Profile* profile_; + Browser* browser_; + PageNavigator* navigator_; + BookmarkNode* parent_; + std::vector selection_; + BookmarkModel* model_; + ConfigurationType configuration_; + +#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) + scoped_ptr menu_; +#elif defined(OS_LINUX) + scoped_ptr menu_; +#endif + + DISALLOW_COPY_AND_ASSIGN(BookmarkContextMenu); +}; + +#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_CONTEXT_MENU_H_ diff --git a/chrome/browser/views/bookmark_context_menu_test.cc b/chrome/browser/views/bookmark_context_menu_test.cc new file mode 100644 index 0000000..44b9609 --- /dev/null +++ b/chrome/browser/views/bookmark_context_menu_test.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2006-2008 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/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" +#include "chrome/browser/views/bookmark_context_menu.h" +#include "chrome/browser/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/browser/tab_contents/page_navigator.h" +#include "chrome/test/testing_profile.h" +#include "grit/generated_resources.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(OS_WIN) +#include "chrome/browser/views/bookmark_bar_view.h" +#endif + +namespace { + +// PageNavigator implementation that records the URL. +class TestingPageNavigator : public PageNavigator { + public: + virtual void OpenURL(const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + urls_.push_back(url); + } + + std::vector urls_; +}; + +} // namespace + +class BookmarkContextMenuTest : public testing::Test { + public: + BookmarkContextMenuTest() + : model_(NULL) { + } + + virtual void SetUp() { +#if defined(OS_WIN) + BookmarkBarView::testing_ = true; +#endif + + profile_.reset(new TestingProfile()); + profile_->set_has_history_service(true); + profile_->CreateBookmarkModel(true); + profile_->BlockUntilBookmarkModelLoaded(); + + model_ = profile_->GetBookmarkModel(); + + AddTestData(); + } + + virtual void TearDown() { +#if defined(OS_WIN) + BookmarkBarView::testing_ = false; +#endif + + // Flush the message loop to make Purify happy. + message_loop_.RunAllPending(); + } + + protected: + MessageLoopForUI message_loop_; + scoped_ptr profile_; + BookmarkModel* model_; + TestingPageNavigator navigator_; + + private: + // Creates the following structure: + // a + // F1 + // f1a + // F11 + // f11a + // F2 + // F3 + // F4 + // f4a + void AddTestData() { + std::string test_base = "file:///c:/tmp/"; + + model_->AddURL(model_->GetBookmarkBarNode(), 0, L"a", + GURL(test_base + "a")); + BookmarkNode* f1 = + model_->AddGroup(model_->GetBookmarkBarNode(), 1, L"F1"); + model_->AddURL(f1, 0, L"f1a", GURL(test_base + "f1a")); + BookmarkNode* f11 = model_->AddGroup(f1, 1, L"F11"); + model_->AddURL(f11, 0, L"f11a", GURL(test_base + "f11a")); + model_->AddGroup(model_->GetBookmarkBarNode(), 2, L"F2"); + model_->AddGroup(model_->GetBookmarkBarNode(), 3, L"F3"); + BookmarkNode* f4 = + model_->AddGroup(model_->GetBookmarkBarNode(), 4, L"F4"); + model_->AddURL(f4, 0, L"f4a", GURL(test_base + "f4a")); + } +}; + +// Tests Deleting from the menu. +TEST_F(BookmarkContextMenuTest, DeleteURL) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), nodes, + BookmarkContextMenu::BOOKMARK_BAR); + GURL url = model_->GetBookmarkBarNode()->GetChild(0)->GetURL(); + ASSERT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + // Delete the URL. + controller.ExecuteCommand(IDS_BOOKMARK_BAR_REMOVE); + // Model shouldn't have URL anymore. + ASSERT_FALSE(model_->IsBookmarked(url)); +} + +// Tests open all on a folder with a couple of bookmarks. +TEST_F(BookmarkContextMenuTest, OpenAll) { + BookmarkNode* folder = model_->GetBookmarkBarNode()->GetChild(1); + bookmark_utils::OpenAll( + NULL, profile_.get(), &navigator_, folder, NEW_FOREGROUND_TAB); + + // Should have navigated to F1's children. + ASSERT_EQ(static_cast(2), navigator_.urls_.size()); + ASSERT_TRUE(folder->GetChild(0)->GetURL() == navigator_.urls_[0]); + ASSERT_TRUE(folder->GetChild(1)->GetChild(0)->GetURL() == + navigator_.urls_[1]); +} + +// Tests the enabled state of the menus when supplied an empty vector. +TEST_F(BookmarkContextMenuTest, EmptyNodes) { + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, model_->other_node(), + std::vector(), BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of the menus when supplied a vector with a single +// url. +TEST_F(BookmarkContextMenuTest, SingleURL) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of the menus when supplied a vector with multiple +// urls. +TEST_F(BookmarkContextMenuTest, MultipleURLs) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(1)->GetChild(0)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of the menus when supplied an vector with a single +// folder. +TEST_F(BookmarkContextMenuTest, SingleFolder) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of the menus when supplied a vector with multiple +// folders, all of which are empty. +TEST_F(BookmarkContextMenuTest, MultipleEmptyFolders) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(2)); + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of the menus when supplied a vector with multiple +// folders, some of which contain URLs. +TEST_F(BookmarkContextMenuTest, MultipleFoldersWithURLs) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(3)); + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(4)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_TRUE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_TRUE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} + +// Tests the enabled state of open incognito. +TEST_F(BookmarkContextMenuTest, DisableIncognito) { + std::vector nodes; + nodes.push_back(model_->GetBookmarkBarNode()->GetChild(0)); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0]->GetParent(), + nodes, BookmarkContextMenu::BOOKMARK_BAR); + profile_->set_off_the_record(true); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_INCOGNITO)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); +} + +// Tests that you can't remove/edit when showing the other node. +TEST_F(BookmarkContextMenuTest, DisabledItemsWithOtherNode) { + std::vector nodes; + nodes.push_back(model_->other_node()); + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, nodes[0], nodes, + BookmarkContextMenu::BOOKMARK_BAR); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_EDIT)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); +} + +// Tests the enabled state of the menus when supplied an empty vector and null +// parent. +TEST_F(BookmarkContextMenuTest, EmptyNodesNullParent) { + BookmarkContextMenu controller( + NULL, profile_.get(), NULL, NULL, NULL, std::vector(), + BookmarkContextMenu::BOOKMARK_MANAGER_ORGANIZE_MENU); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO)); + EXPECT_FALSE(controller.IsCommandEnabled(IDS_BOOKMARK_BAR_REMOVE)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOKMARK_MANAGER_SHOW_IN_FOLDER)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK)); + EXPECT_FALSE( + controller.IsCommandEnabled(IDS_BOOMARK_BAR_NEW_FOLDER)); +} diff --git a/chrome/browser/views/bookmark_context_menu_views.cc b/chrome/browser/views/bookmark_context_menu_views.cc new file mode 100644 index 0000000..6d00085 --- /dev/null +++ b/chrome/browser/views/bookmark_context_menu_views.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2009 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/views/bookmark_context_menu.h" + +#include "app/l10n_util.h" + +void BookmarkContextMenu::RunMenuAt(int x, int y) { + if (!model_->IsLoaded()) { + NOTREACHED(); + return; + } + // width/height don't matter here. + views::MenuItemView::AnchorPosition anchor = + (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ? + views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT; + menu_->RunMenuAt(wnd_, gfx::Rect(x, y, 0, 0), anchor, true); +} + +void BookmarkContextMenu::CreateMenuObject() { + menu_.reset(new views::MenuItemView(this)); +} + +void BookmarkContextMenu::AppendItem(int id) { + menu_->AppendMenuItemWithLabel( + id, l10n_util::GetString(id)); +} + +void BookmarkContextMenu::AppendItem(int id, int localization_id) { + menu_->AppendMenuItemWithLabel( + id, l10n_util::GetString(localization_id)); +} + +void BookmarkContextMenu::AppendSeparator() { + menu_->AppendSeparator(); +} + +void BookmarkContextMenu::AppendCheckboxItem(int id) { + menu_->AppendMenuItem(id, + l10n_util::GetString(id), + views::MenuItemView::CHECKBOX); +} diff --git a/chrome/browser/views/bookmark_manager_view.h b/chrome/browser/views/bookmark_manager_view.h index 8419a0d..2139a0b 100644 --- a/chrome/browser/views/bookmark_manager_view.h +++ b/chrome/browser/views/bookmark_manager_view.h @@ -7,9 +7,9 @@ #include "base/ref_counted.h" #include "base/task.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/shell_dialogs.h" +#include "chrome/browser/views/bookmark_context_menu.h" #include "views/controls/menu/view_menu_delegate.h" #include "views/controls/table/table_view_observer.h" #include "views/controls/textfield/textfield.h" diff --git a/chrome/browser/views/bookmark_menu_controller_views.h b/chrome/browser/views/bookmark_menu_controller_views.h index 54c11de..a87ecfe 100644 --- a/chrome/browser/views/bookmark_menu_controller_views.h +++ b/chrome/browser/views/bookmark_menu_controller_views.h @@ -9,8 +9,8 @@ #include "base/gfx/native_widget_types.h" #include "chrome/browser/bookmarks/base_bookmark_model_observer.h" -#include "chrome/browser/bookmarks/bookmark_context_menu.h" #include "chrome/browser/bookmarks/bookmark_drag_data.h" +#include "chrome/browser/views/bookmark_context_menu.h" #include "views/controls/menu/chrome_menu.h" class BookmarkContextMenu; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 41efa9b..1400829 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -617,10 +617,6 @@ 'browser/blocked_popup_container.h', 'browser/bookmarks/bookmark_codec.cc', 'browser/bookmarks/bookmark_codec.h', - 'browser/bookmarks/bookmark_context_menu_gtk.cc', - 'browser/bookmarks/bookmark_context_menu_views.cc', - 'browser/bookmarks/bookmark_context_menu.cc', - 'browser/bookmarks/bookmark_context_menu.h', 'browser/bookmarks/bookmark_drag_data.cc', 'browser/bookmarks/bookmark_drag_data.h', 'browser/bookmarks/bookmark_drop_info.cc', @@ -948,6 +944,9 @@ 'browser/gtk/bookmark_bar_gtk.h', 'browser/gtk/bookmark_bubble_gtk.cc', 'browser/gtk/bookmark_bubble_gtk.h', + 'browser/gtk/bookmark_context_menu_gtk.cc', + 'browser/gtk/bookmark_context_menu.cc', + 'browser/gtk/bookmark_context_menu.h', 'browser/gtk/bookmark_editor_gtk.cc', 'browser/gtk/bookmark_editor_gtk.h', 'browser/gtk/bookmark_manager_gtk.cc', @@ -1476,6 +1475,9 @@ 'browser/views/bookmark_bar_view.h', 'browser/views/bookmark_bubble_view.cc', 'browser/views/bookmark_bubble_view.h', + 'browser/views/bookmark_context_menu_views.cc', + 'browser/views/bookmark_context_menu.cc', + 'browser/views/bookmark_context_menu.h', 'browser/views/bookmark_editor_view.cc', 'browser/views/bookmark_editor_view.h', 'browser/views/bookmark_folder_tree_view.cc', @@ -3342,7 +3344,6 @@ 'browser/back_forward_menu_model_unittest.cc', 'browser/blocked_popup_container_unittest.cc', 'browser/bookmarks/bookmark_codec_unittest.cc', - 'browser/bookmarks/bookmark_context_menu_test.cc', 'browser/bookmarks/bookmark_drag_data_unittest.cc', 'browser/bookmarks/bookmark_folder_tree_model_unittest.cc', 'browser/bookmarks/bookmark_html_writer_unittest.cc', @@ -3500,6 +3501,7 @@ 'browser/task_manager_unittest.cc', 'browser/theme_resources_util_unittest.cc', 'browser/utility_process_host_unittest.cc', + 'browser/views/bookmark_context_menu_test.cc', 'browser/views/bookmark_editor_view_unittest.cc', 'browser/views/keyword_editor_view_unittest.cc', 'browser/visitedlink_unittest.cc', @@ -3573,6 +3575,7 @@ # might want to write our own tests for the download manager # on linux, though. 'browser/download/download_manager_unittest.cc', + 'browser/views/bookmark_context_menu_test.cc', # Compact Language Detection (cld) is not supported in linux yet. '../third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/compact_lang_det_unittest_small.cc', ], @@ -3592,7 +3595,7 @@ '../third_party/GTM', ], 'sources!': [ - 'browser/bookmarks/bookmark_context_menu_test.cc', + 'browser/views/bookmark_context_menu_test.cc', 'browser/back_forward_menu_model_unittest.cc', 'browser/download/download_manager_unittest.cc', 'browser/gtk/go_button_gtk_unittest.cc', -- cgit v1.1