1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_CONTEXT_MENU_CONTROLLER_H_
#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_CONTEXT_MENU_CONTROLLER_H_
#include <memory>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/bookmarks/bookmark_stats.h"
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/menus/simple_menu_model.h"
class Browser;
class Profile;
class BookmarkMergedSurfaceService;
struct BookmarkParentFolder;
// An interface implemented by an object that performs actions on the actual
// menu for the controller.
class BookmarkContextMenuControllerDelegate {
public:
virtual ~BookmarkContextMenuControllerDelegate() = default;
// Closes the bookmark context menu.
virtual void CloseMenu() = 0;
// Sent before any command from the menu is executed.
virtual void WillExecuteCommand(
int command_id,
const std::vector<raw_ptr<const bookmarks::BookmarkNode,
VectorExperimental>>& bookmarks) {}
// Sent after any command from the menu is executed.
virtual void DidExecuteCommand(int command_id) {}
};
// BookmarkContextMenuController creates and manages state for the context menu
// shown for any bookmark item.
class BookmarkContextMenuController
: public bookmarks::BaseBookmarkModelObserver,
public ui::SimpleMenuModel::Delegate {
public:
// Creates the bookmark context menu.
// `browser` is used to open the bookmark manager and is null in tests.
// `profile` is used for opening urls as well as enabling 'open incognito'.
// Uses a callback since this can be asynchronous. See crbug.com/1161144.
// `selection` is the nodes the context menu operates on and must be not
// empty. The parent for newly created nodes is `selection[0]` if `selection`
// has one element and it is a folder, otherwise it is `selection[0]->parent`.
BookmarkContextMenuController(
gfx::NativeWindow parent_window,
BookmarkContextMenuControllerDelegate* delegate,
Browser* browser,
Profile* profile,
BookmarkLaunchLocation opened_from,
const std::vector<raw_ptr<const bookmarks::BookmarkNode,
VectorExperimental>>& selection);
BookmarkContextMenuController(const BookmarkContextMenuController&) = delete;
BookmarkContextMenuController& operator=(
const BookmarkContextMenuController&) = delete;
~BookmarkContextMenuController() override;
ui::SimpleMenuModel* menu_model() { return menu_model_.get(); }
// Public for testing.
// Returns the parent for newly created folders/bookmarks. If `selection` has
// one element and it is a folder, `selection[0]` is returned, otherwise
// `selection[0]->parent` is returned.
static std::unique_ptr<BookmarkParentFolder> GetParentForNewNodes(
const std::vector<raw_ptr<const bookmarks::BookmarkNode,
VectorExperimental>>& selection);
// ui::SimpleMenuModel::Delegate implementation:
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
bool IsCommandIdVisible(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override;
bool IsItemForCommandIdDynamic(int command_id) const override;
std::u16string GetLabelForCommandId(int command_id) const override;
// Public for testing.
// Returns index at which the newly added nodes will be added.
size_t GetIndexForNewNodes() const;
private:
friend class BookmarkContextMenuControllerTest;
FRIEND_TEST_ALL_PREFIXES(
BookmarkContextMenuControllerTest,
ComputeNodeToFocusForBookmarkManagerForPermanentNodesSelection);
FRIEND_TEST_ALL_PREFIXES(BookmarkContextMenuControllerTest,
ComputeNodeToFocusForBookmarkManagerReturnsNoNode);
FRIEND_TEST_ALL_PREFIXES(
BookmarkContextMenuControllerTest,
ComputeNodeToFocusForBookmarkManagerForDirectChildrenOfPermanentNodes);
FRIEND_TEST_ALL_PREFIXES(
BookmarkContextMenuControllerTest,
ComputeNodeToFocusForBookmarkManagerForNonDirectChildrenOfPermanentNodes);
void BuildMenu();
// Adds a IDC_* style command to the menu with a string16.
void AddItem(int id, const std::u16string str);
// Adds a IDC_* style command to the menu with a localized string.
void AddItem(int id, int localization_id);
// Adds a separator to the menu.
void AddSeparator();
// Adds a checkable item to the menu.
void AddCheckboxItem(int id, int localization_id);
// Overridden from bookmarks::BaseBookmarkModelObserver:
// Any change to the model results in closing the menu.
void BookmarkModelChanged() override;
// Returns the node that needs to be focused based on the `selection_`.
// Returns null if no node should be focused.
const bookmarks::BookmarkNode* ComputeNodeToFocusForBookmarkManager() const;
gfx::NativeWindow parent_window_;
raw_ptr<BookmarkContextMenuControllerDelegate> delegate_;
const raw_ptr<Browser> browser_;
raw_ptr<Profile> profile_;
const BookmarkLaunchLocation opened_from_;
std::vector<raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>
selection_;
const raw_ptr<BookmarkMergedSurfaceService> bookmark_service_;
std::unique_ptr<ui::SimpleMenuModel> menu_model_;
const std::unique_ptr<BookmarkParentFolder> new_nodes_parent_;
// Used to detect deletion of |this| executing a command.
base::WeakPtrFactory<BookmarkContextMenuController> weak_factory_{this};
};
// Returns true if `selection` represents a permanent bookmark folder.
// It can be represented by two nodes (local and account) of the same permanent
// type.
bool IsSelectionPermanentBookmarkFolder(
const std::vector<
raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>& selection);
#endif // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_CONTEXT_MENU_CONTROLLER_H_
|