blob: 32a3ca2860d1e741b180840d92bf0948475c3d24 [file] [log] [blame]
// Copyright 2024 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_UI_OPERATIONS_HELPER_H_
#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UI_OPERATIONS_HELPER_H_
#include <cstddef>
#include "base/memory/raw_ptr.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/bookmarks/common/bookmark_metrics.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
class BookmarkMergedSurfaceService;
struct BookmarkParentFolder;
class Profile;
class Browser;
namespace bookmarks {
class BookmarkModel;
struct BookmarkNodeData;
} // namespace bookmarks
namespace chrome {
enum class BookmarkReorderDropTarget;
}
namespace internal {
class BookmarkUIOperationsHelper {
public:
virtual ~BookmarkUIOperationsHelper();
// Drops the bookmark nodes that are in `data` onto `target_parent()` at
// `index`.
// `copy` indicates the source operation: if true then the bookmarks in
// `data` are copied, otherwise they are moved if they belong to the same
// profile.
// `browser` is needed if the user should be asked to confirm whether they
// want to move a bookmark between local and account storage. Returns the drop
// type used.
ui::mojom::DragOperation DropBookmarks(
Profile* profile,
const bookmarks::BookmarkNodeData& data,
size_t index,
bool copy,
chrome::BookmarkReorderDropTarget target,
Browser* browser = nullptr);
// Copies nodes onto the clipboard. The nodes are copied in such a way that if
// pasted again new nodes can be created. Pass the calling context through as
// `source`.
static void CopyToClipboard(
bookmarks::BookmarkModel* model,
const std::vector<
raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>& nodes,
bookmarks::metrics::BookmarkEditSource source,
bool is_off_the_record);
// Copies nodes onto the clipboard then removes them from the bookmark model.
// Pass the calling context through as `source`.
static void CutToClipboard(
bookmarks::BookmarkModel* model,
const std::vector<
raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>& nodes,
bookmarks::metrics::BookmarkEditSource source,
bool is_off_the_record);
// Returns true if the user can paste from the clipboard a bookmark url/node
// into `target_parent()`.
bool CanPasteFromClipboard() const;
// Pastes from the clipboard. The new nodes are added to `target_parent()`.
// The nodes are inserted at `index`.
void PasteFromClipboard(size_t index);
protected:
// Represents the target parent node for the operation.
// For non-merged surfaces, it's a bookmark node.
// For merged surfaces, it's either a bookmark node or a permanent folder.
class TargetParent {
public:
virtual ~TargetParent();
virtual bool IsManaged() const = 0;
virtual bool IsPermanentNode() const = 0;
virtual bool IsDirectChild(const bookmarks::BookmarkNode* node) const = 0;
virtual bookmarks::BookmarkNode::Type GetType() const = 0;
virtual const bookmarks::BookmarkNode* GetNodeAtIndex(
size_t index) const = 0;
virtual size_t GetChildrenCount() const = 0;
};
virtual bookmarks::BookmarkModel* model() = 0;
virtual void AddNodesAsCopiesOfNodeData(
const bookmarks::BookmarkNodeData& data,
size_t index_to_add_at) = 0;
virtual void MoveBookmarkNodeData(const bookmarks::BookmarkNodeData& data,
const base::FilePath& profile_path,
size_t index_to_add_at,
Browser* browser) = 0;
virtual const TargetParent* target_parent() const = 0;
private:
static void CopyOrCutToClipboard(
bookmarks::BookmarkModel* model,
const std::vector<
raw_ptr<const bookmarks::BookmarkNode, VectorExperimental>>& nodes,
bool remove_nodes,
bookmarks::metrics::BookmarkEditSource source,
bool is_off_the_record);
// Updates `title` such that `url` and `title` pair are unique among the
// children of `target_parent()`.
void MakeTitleUnique(const GURL& url, std::u16string* title) const;
};
} // namespace internal
// Helper class for UI operations e.g. Drop, Copy, Paste bookmarks.
// `BookmarkUIOperationsHelperNonMergedSurfaces` must be used in non bookmark
// merged surfaces where there is a clear distinction between account and local
// bookmarks.
class BookmarkUIOperationsHelperNonMergedSurfaces
: public internal::BookmarkUIOperationsHelper {
public:
// `model` and `parent` must be not null and outlive `this`.
// `parent` is the parent node where nodes are being dropped, copy/cut ->
// paste into parent folder.
BookmarkUIOperationsHelperNonMergedSurfaces(
bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* parent);
BookmarkUIOperationsHelperNonMergedSurfaces(
const BookmarkUIOperationsHelperNonMergedSurfaces&) = delete;
BookmarkUIOperationsHelperNonMergedSurfaces& operator=(
const BookmarkUIOperationsHelperNonMergedSurfaces&) = delete;
~BookmarkUIOperationsHelperNonMergedSurfaces() override;
protected:
bookmarks::BookmarkModel* model() override;
void AddNodesAsCopiesOfNodeData(const bookmarks::BookmarkNodeData& data,
size_t index_to_add_at) override;
void MoveBookmarkNodeData(const bookmarks::BookmarkNodeData& data,
const base::FilePath& profile_path,
size_t index_to_add_at,
Browser* browser) override;
const internal::BookmarkUIOperationsHelper::TargetParent* target_parent()
const override;
private:
class TargetParent
: public internal::BookmarkUIOperationsHelper::TargetParent {
public:
static std::unique_ptr<TargetParent> CreateTargetParent(
bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* parent);
TargetParent(const bookmarks::BookmarkNode* parent, bool is_managed);
~TargetParent() override;
const bookmarks::BookmarkNode* parent_node() const;
// internal::BookmarkUIOperationsHelper::TargetParent
bool IsManaged() const override;
bool IsPermanentNode() const override;
bool IsDirectChild(const bookmarks::BookmarkNode* node) const override;
bookmarks::BookmarkNode::Type GetType() const override;
const bookmarks::BookmarkNode* GetNodeAtIndex(size_t index) const override;
size_t GetChildrenCount() const override;
private:
const raw_ptr<const bookmarks::BookmarkNode> parent_;
const bool is_managed_;
};
const bookmarks::BookmarkNode* parent_node() const;
const raw_ptr<bookmarks::BookmarkModel> model_;
const std::unique_ptr<TargetParent> target_parent_;
};
// Helper class for UI operations e.g. Drop, Copy, Paste bookmarks.
// `BookmarkUIOperationsHelperNonMergedSurfaces` must be used in bookmark
// merged surfaces (Bookmark bar, bookmark menu and side panel).
class BookmarkUIOperationsHelperMergedSurfaces
: public internal::BookmarkUIOperationsHelper {
public:
BookmarkUIOperationsHelperMergedSurfaces(
BookmarkMergedSurfaceService* merged_surface_service,
const BookmarkParentFolder* parent);
BookmarkUIOperationsHelperMergedSurfaces(
const BookmarkUIOperationsHelperMergedSurfaces&) = delete;
BookmarkUIOperationsHelperMergedSurfaces& operator=(
const BookmarkUIOperationsHelperMergedSurfaces&) = delete;
~BookmarkUIOperationsHelperMergedSurfaces() override;
// Merged bookmark surfaces can trigger a non-merged bookmark UI e.g. bookmark
// context menu can trigger the edit bookmark UI or the bookmark manager with
// a choice of a highlighted node.
// This function returns the default parent to use for non-merged surfaces UIs
// triggered from merged surfaces.
// This function treats managed nodes as some operations are allowed; e.g.
// opening the bookmark manager with a managed node highlighted. This should
// not be used by managed folders if intended to be used for adding new nodes,
// since managed bookmarks do not support creating nodes.
const bookmarks::BookmarkNode* GetDefaultParentForNonMergedSurfaces() const;
protected:
bookmarks::BookmarkModel* model() override;
void AddNodesAsCopiesOfNodeData(const bookmarks::BookmarkNodeData& data,
size_t index_to_add_at) override;
void MoveBookmarkNodeData(const bookmarks::BookmarkNodeData& data,
const base::FilePath& profile_path,
size_t index_to_add_at,
Browser* browser) override;
const internal::BookmarkUIOperationsHelper::TargetParent* target_parent()
const override;
private:
class TargetParent
: public internal::BookmarkUIOperationsHelper::TargetParent {
public:
static std::unique_ptr<TargetParent> CreateTargetParent(
BookmarkMergedSurfaceService* merged_surface_service,
const BookmarkParentFolder* parent);
TargetParent(BookmarkMergedSurfaceService* merged_surface_service,
const BookmarkParentFolder* parent);
~TargetParent() override;
const BookmarkParentFolder* parent_folder() const;
// internal::BookmarkUIOperationsHelper::TargetParent
bool IsManaged() const override;
bool IsPermanentNode() const override;
bool IsDirectChild(const bookmarks::BookmarkNode* node) const override;
bookmarks::BookmarkNode::Type GetType() const override;
const bookmarks::BookmarkNode* GetNodeAtIndex(size_t index) const override;
size_t GetChildrenCount() const override;
private:
const raw_ptr<BookmarkMergedSurfaceService> merged_surface_service_;
const raw_ptr<const BookmarkParentFolder> parent_;
};
const BookmarkParentFolder* parent_folder() const;
const raw_ptr<BookmarkMergedSurfaceService> merged_surface_service_;
const std::unique_ptr<TargetParent> target_parent_;
};
#endif // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UI_OPERATIONS_HELPER_H_