| // Copyright 2020 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 UI_BASE_CLIPBOARD_CLIPBOARD_DATA_H_ |
| #define UI_BASE_CLIPBOARD_CLIPBOARD_DATA_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/component_export.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/base/clipboard/file_info.h" |
| #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" |
| |
| class SkBitmap; |
| |
| namespace ui { |
| |
| // Clipboard data format used by ClipboardInternal. |
| enum class ClipboardInternalFormat { |
| kText = 1 << 0, |
| kHtml = 1 << 1, |
| kSvg = 1 << 2, |
| kRtf = 1 << 3, |
| kBookmark = 1 << 4, |
| kPng = 1 << 5, |
| kCustom = 1 << 6, |
| kWeb = 1 << 7, |
| kFilenames = 1 << 8, |
| }; |
| |
| // ClipboardData contains data copied to the Clipboard for a variety of formats. |
| // It mostly just provides APIs to cleanly access and manipulate this data. |
| class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardData { |
| public: |
| // Encode a bitmap to a PNG. Callers encoding a PNG on a background thread |
| // should use this method. |
| static std::vector<uint8_t> EncodeBitmapData(const SkBitmap& bitmap); |
| |
| ClipboardData(); |
| explicit ClipboardData(const ClipboardData&); |
| ClipboardData(ClipboardData&&); |
| ClipboardData& operator=(const ClipboardData&) = delete; |
| ~ClipboardData(); |
| |
| bool operator==(const ClipboardData& that) const; |
| bool operator!=(const ClipboardData& that) const; |
| |
| // Bitmask of ClipboardInternalFormat types. |
| int format() const { return format_; } |
| |
| // Returns the total size of the data in clipboard, or absl::nullopt if it |
| // can't be determined. |
| absl::optional<size_t> size() const; |
| |
| const std::string& text() const { return text_; } |
| void set_text(const std::string& text) { |
| text_ = text; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kText); |
| } |
| |
| const std::string& markup_data() const { return markup_data_; } |
| void set_markup_data(const std::string& markup_data) { |
| markup_data_ = markup_data; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kHtml); |
| } |
| |
| const std::string& svg_data() const { return svg_data_; } |
| void set_svg_data(const std::string& svg_data) { |
| svg_data_ = svg_data; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kSvg); |
| } |
| |
| const std::string& rtf_data() const { return rtf_data_; } |
| void SetRTFData(const std::string& rtf_data) { |
| rtf_data_ = rtf_data; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kRtf); |
| } |
| |
| const std::string& url() const { return url_; } |
| void set_url(const std::string& url) { |
| url_ = url; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kHtml); |
| } |
| |
| const std::string& bookmark_title() const { return bookmark_title_; } |
| void set_bookmark_title(const std::string& bookmark_title) { |
| bookmark_title_ = bookmark_title; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kBookmark); |
| } |
| |
| const std::string& bookmark_url() const { return bookmark_url_; } |
| void set_bookmark_url(const std::string& bookmark_url) { |
| bookmark_url_ = bookmark_url; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kBookmark); |
| } |
| |
| // Returns an encoded PNG, or absl::nullopt if either there is no image on the |
| // clipboard or there is an image which has not yet been encoded to a PNG. |
| // `GetBitmapIfPngNotEncoded()` will return a value in the latter case. |
| const absl::optional<std::vector<uint8_t>>& maybe_png() const { |
| return maybe_png_; |
| } |
| // Set PNG data. If an existing image is already on the clipboard, its |
| // contents will be overwritten. If setting the PNG after encoding the bitmap |
| // already on the clipboard, use `SetPngDataAfterEncoding()`. |
| void SetPngData(std::vector<uint8_t> png); |
| |
| // Use this method if the PNG being set was encoded from the bitmap which is |
| // already on the clipboard. This allows the operator== method to check |
| // equality of two clipboard instances if only one has been encoded to a PNG. |
| // It is invalid to call this method unless a bitmap is already on the |
| // clipboard. This method is marked const to allow setting this member on |
| // const ClipboardData instances. |
| void SetPngDataAfterEncoding(std::vector<uint8_t> png) const; |
| |
| // Prefer to use `SetPngData()` where possible. Images can be written to the |
| // clipboard as bitmaps, but must be read out as an encoded PNG. Callers are |
| // responsible for ensuring that the bitmap eventually gets encoded as a PNG. |
| // See GetBitmapIfPngNotEncoded() below. |
| void SetBitmapData(const SkBitmap& bitmap); |
| // Use this method to obtain the bitmap to be encoded to a PNG. It is only |
| // recommended to call this method after checking that `maybe_png()` returns |
| // no value. If this returns a value, use `EncodeBitmapData()` to encode the |
| // bitmap to a PNG on a background thread. |
| absl::optional<SkBitmap> GetBitmapIfPngNotEncoded() const; |
| |
| const std::string& custom_data_format() const { return custom_data_format_; } |
| const std::string& custom_data_data() const { return custom_data_data_; } |
| void SetCustomData(const std::string& data_format, |
| const std::string& data_data); |
| |
| bool web_smart_paste() const { return web_smart_paste_; } |
| void set_web_smart_paste(bool web_smart_paste) { |
| web_smart_paste_ = web_smart_paste; |
| format_ |= static_cast<int>(ClipboardInternalFormat::kWeb); |
| } |
| |
| const std::vector<ui::FileInfo>& filenames() const { return filenames_; } |
| void set_filenames(std::vector<ui::FileInfo> filenames) { |
| filenames_ = std::move(filenames); |
| if (!filenames_.empty()) |
| format_ |= static_cast<int>(ClipboardInternalFormat::kFilenames); |
| } |
| |
| DataTransferEndpoint* source() const { return src_.get(); } |
| |
| void set_source(std::unique_ptr<DataTransferEndpoint> src) { |
| src_ = std::move(src); |
| } |
| |
| private: |
| // Plain text in UTF8 format. |
| std::string text_; |
| |
| // HTML markup data in UTF8 format. |
| std::string markup_data_; |
| std::string url_; |
| |
| // RTF data. |
| std::string rtf_data_; |
| |
| // Bookmark title in UTF8 format. |
| std::string bookmark_title_; |
| std::string bookmark_url_; |
| |
| // Image data can take the form of PNGs or bitmaps. Strongly prefer PNGs where |
| // possible, since images can only be read out of this interface as PNGs. This |
| // field is marked as mutable so it can be set after a bitmap is encoded to a |
| // PNG on a const instance. The contents of the clipboard are not changing, |
| // merely the format. |
| mutable absl::optional<std::vector<uint8_t>> maybe_png_ = absl::nullopt; |
| // This member contains a value only in the following cases: |
| // 1) SetBitmapData() wrote a bitmap to the clipboard, but it has not yet been |
| // encoded into a PNG. |
| // 2) SetBitmapData() wrote a bitmap to the clipboard, then this image was |
| // encoded to PNG. SetPngDataAfterEncoding() was called to indicate that |
| // this member is the decoded version of `maybe_png_`. |
| absl::optional<SkBitmap> maybe_bitmap_ = absl::nullopt; |
| |
| // Data with custom format. |
| std::string custom_data_format_; |
| std::string custom_data_data_; |
| |
| // WebKit smart paste data. |
| bool web_smart_paste_; |
| |
| // Svg data. |
| std::string svg_data_; |
| |
| // text/uri-list filenames data. |
| std::vector<ui::FileInfo> filenames_; |
| |
| int format_; |
| |
| // The source of the data. |
| std::unique_ptr<DataTransferEndpoint> src_; |
| }; |
| |
| } // namespace ui |
| |
| #endif // UI_BASE_CLIPBOARD_CLIPBOARD_DATA_H_ |