File: bookmark_context_menu_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (148 lines) | stat: -rw-r--r-- 6,162 bytes parent folder | download | duplicates (5)
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_