| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/base/clipboard/clipboard_aura.h" | 5 #include "ui/base/clipboard/clipboard_aura.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <list> | 10 #include <list> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 19 #include "third_party/skia/include/core/SkBitmap.h" | 19 #include "third_party/skia/include/core/SkBitmap.h" |
| 20 #include "ui/base/clipboard/clipboard_monitor.h" | 20 #include "ui/base/clipboard/clipboard_monitor.h" |
| 21 #include "ui/base/clipboard/custom_data_helper.h" | 21 #include "ui/base/clipboard/custom_data_helper.h" |
| 22 #include "ui/gfx/geometry/size.h" | 22 #include "ui/gfx/geometry/size.h" |
| 23 | 23 |
| 24 namespace ui { | 24 namespace ui { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 |
| 27 const char kMimeTypeFilename[] = "chromium/filename"; | 28 const char kMimeTypeFilename[] = "chromium/filename"; |
| 28 const char kMimeTypeBitmap[] = "image/bmp"; | 29 const char kMimeTypeBitmap[] = "image/bmp"; |
| 29 const size_t kMaxClipboardSize = 1; | 30 const size_t kMaxClipboardSize = 1; |
| 30 | 31 |
| 31 // Clipboard data format used by AuraClipboard. | 32 // Clipboard data format used by AuraClipboard. |
| 32 enum AuraClipboardFormat { | 33 enum AuraClipboardFormat { |
| 33 TEXT = 1 << 0, | 34 TEXT = 1 << 0, |
| 34 HTML = 1 << 1, | 35 HTML = 1 << 1, |
| 35 RTF = 1 << 2, | 36 RTF = 1 << 2, |
| 36 BOOKMARK = 1 << 3, | 37 BOOKMARK = 1 << 3, |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 void WriteData(std::unique_ptr<ClipboardData> data) { | 292 void WriteData(std::unique_ptr<ClipboardData> data) { |
| 292 DCHECK(data); | 293 DCHECK(data); |
| 293 AddToListEnsuringSize(std::move(data)); | 294 AddToListEnsuringSize(std::move(data)); |
| 294 ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); | 295 ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); |
| 295 } | 296 } |
| 296 | 297 |
| 297 private: | 298 private: |
| 298 // True if the data on top of the clipboard stack has format |format|. | 299 // True if the data on top of the clipboard stack has format |format|. |
| 299 bool HasFormat(AuraClipboardFormat format) const { | 300 bool HasFormat(AuraClipboardFormat format) const { |
| 300 const ClipboardData* data = GetData(); | 301 const ClipboardData* data = GetData(); |
| 301 if (!data) | 302 return data ? data->format() & format : false; |
| 302 return false; | |
| 303 | |
| 304 return data->format() & format; | |
| 305 } | 303 } |
| 306 | 304 |
| 307 void AddToListEnsuringSize(std::unique_ptr<ClipboardData> data) { | 305 void AddToListEnsuringSize(std::unique_ptr<ClipboardData> data) { |
| 308 DCHECK(data); | 306 DCHECK(data); |
| 309 sequence_number_++; | 307 sequence_number_++; |
| 310 data_list_.push_front(std::move(data)); | 308 data_list_.push_front(std::move(data)); |
| 311 | 309 |
| 312 // If the size of list becomes more than the maximum allowed, we delete the | 310 // If the size of list becomes more than the maximum allowed, we delete the |
| 313 // last element. | 311 // last element. |
| 314 if (data_list_.size() > kMaxClipboardSize) { | 312 if (data_list_.size() > kMaxClipboardSize) { |
| 315 data_list_.pop_back(); | 313 data_list_.pop_back(); |
| 316 } | 314 } |
| 317 } | 315 } |
| 318 | 316 |
| 319 // Stack containing various versions of ClipboardData. | 317 // Stack containing various versions of ClipboardData. |
| 320 std::list<std::unique_ptr<ClipboardData>> data_list_; | 318 std::list<std::unique_ptr<ClipboardData>> data_list_; |
| 321 | 319 |
| 322 // Sequence number uniquely identifying clipboard state. | 320 // Sequence number uniquely identifying clipboard state. |
| 323 uint64_t sequence_number_; | 321 uint64_t sequence_number_; |
| 324 | 322 |
| 325 DISALLOW_COPY_AND_ASSIGN(AuraClipboard); | 323 DISALLOW_COPY_AND_ASSIGN(AuraClipboard); |
| 326 }; | 324 }; |
| 327 | 325 |
| 328 AuraClipboard* aura_clipboard = NULL; | 326 AuraClipboard* g_aura_clipboard = NULL; |
| 329 | 327 |
| 330 AuraClipboard* GetClipboard() { | 328 AuraClipboard* GetClipboard() { |
| 331 if (!aura_clipboard) | 329 if (!g_aura_clipboard) |
| 332 aura_clipboard = new AuraClipboard(); | 330 g_aura_clipboard = new AuraClipboard(); |
| 333 return aura_clipboard; | 331 return g_aura_clipboard; |
| 334 } | 332 } |
| 335 | 333 |
| 336 void DeleteClipboard() { | 334 void DeleteClipboard() { |
| 337 if (aura_clipboard) | 335 delete g_aura_clipboard; |
| 338 delete aura_clipboard; | 336 g_aura_clipboard = NULL; |
| 339 aura_clipboard = NULL; | |
| 340 } | 337 } |
| 341 | 338 |
| 342 // Helper class to build a ClipboardData object and write it to clipboard. | 339 // Helper class to build a ClipboardData object and write it to clipboard. |
| 343 class ClipboardDataBuilder { | 340 class ClipboardDataBuilder { |
| 344 public: | 341 public: |
| 345 static void CommitToClipboard() { | 342 static void CommitToClipboard() { |
| 346 // Make sure there is always a valid ClipboardData object attached to | 343 GetClipboard()->WriteData(TakeCurrentData()); |
| 347 // current_data_. | |
| 348 GetCurrentData(); | |
| 349 GetClipboard()->WriteData(std::move(current_data_)); | |
| 350 } | 344 } |
| 351 | 345 |
| 352 static void WriteText(const char* text_data, size_t text_len) { | 346 static void WriteText(const char* text_data, size_t text_len) { |
| 353 ClipboardData* data = GetCurrentData(); | 347 ClipboardData* data = GetCurrentData(); |
| 354 data->set_text(std::string(text_data, text_len)); | 348 data->set_text(std::string(text_data, text_len)); |
| 355 } | 349 } |
| 356 | 350 |
| 357 static void WriteHTML(const char* markup_data, | 351 static void WriteHTML(const char* markup_data, |
| 358 size_t markup_len, | 352 size_t markup_len, |
| 359 const char* url_data, | 353 const char* url_data, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 390 static void WriteData(const std::string& format, | 384 static void WriteData(const std::string& format, |
| 391 const char* data_data, | 385 const char* data_data, |
| 392 size_t data_len) { | 386 size_t data_len) { |
| 393 ClipboardData* data = GetCurrentData(); | 387 ClipboardData* data = GetCurrentData(); |
| 394 data->SetCustomData(format, std::string(data_data, data_len)); | 388 data->SetCustomData(format, std::string(data_data, data_len)); |
| 395 } | 389 } |
| 396 | 390 |
| 397 private: | 391 private: |
| 398 static ClipboardData* GetCurrentData() { | 392 static ClipboardData* GetCurrentData() { |
| 399 if (!current_data_) | 393 if (!current_data_) |
| 400 current_data_.reset(new ClipboardData); | 394 current_data_ = new ClipboardData; |
| 401 return current_data_.get(); | 395 return current_data_; |
| 402 } | 396 } |
| 403 | 397 |
| 404 static std::unique_ptr<ClipboardData> current_data_; | 398 static std::unique_ptr<ClipboardData> TakeCurrentData() { |
| 399 std::unique_ptr<ClipboardData> data = base::WrapUnique(GetCurrentData()); |
| 400 current_data_ = nullptr; |
| 401 return data; |
| 402 } |
| 403 // This is a raw pointer instead of a std::unique_ptr to avoid adding a |
| 404 // static initializer. |
| 405 static ClipboardData* current_data_; |
| 405 }; | 406 }; |
| 406 | 407 |
| 407 std::unique_ptr<ClipboardData> ClipboardDataBuilder::current_data_; | 408 ClipboardData* ClipboardDataBuilder::current_data_ = nullptr; |
| 408 | 409 |
| 409 } // namespace | 410 } // namespace |
| 410 | 411 |
| 411 // Clipboard::FormatType implementation. | 412 // Clipboard::FormatType implementation. |
| 412 Clipboard::FormatType::FormatType() { | 413 Clipboard::FormatType::FormatType() { |
| 413 } | 414 } |
| 414 | 415 |
| 415 Clipboard::FormatType::FormatType(const std::string& native_format) | 416 Clipboard::FormatType::FormatType(const std::string& native_format) |
| 416 : data_(native_format) { | 417 : data_(native_format) { |
| 417 } | 418 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 } | 545 } |
| 545 | 546 |
| 546 bool ClipboardAura::IsFormatAvailable(const FormatType& format, | 547 bool ClipboardAura::IsFormatAvailable(const FormatType& format, |
| 547 ClipboardType type) const { | 548 ClipboardType type) const { |
| 548 DCHECK(CalledOnValidThread()); | 549 DCHECK(CalledOnValidThread()); |
| 549 DCHECK(IsSupportedClipboardType(type)); | 550 DCHECK(IsSupportedClipboardType(type)); |
| 550 AuraClipboard* clipboard = GetClipboard(); | 551 AuraClipboard* clipboard = GetClipboard(); |
| 551 if (GetPlainTextFormatType().Equals(format) || | 552 if (GetPlainTextFormatType().Equals(format) || |
| 552 GetUrlFormatType().Equals(format)) | 553 GetUrlFormatType().Equals(format)) |
| 553 return clipboard->IsFormatAvailable(TEXT); | 554 return clipboard->IsFormatAvailable(TEXT); |
| 554 else if (GetHtmlFormatType().Equals(format)) | 555 if (GetHtmlFormatType().Equals(format)) |
| 555 return clipboard->IsFormatAvailable(HTML); | 556 return clipboard->IsFormatAvailable(HTML); |
| 556 else if (GetRtfFormatType().Equals(format)) | 557 if (GetRtfFormatType().Equals(format)) |
| 557 return clipboard->IsFormatAvailable(RTF); | 558 return clipboard->IsFormatAvailable(RTF); |
| 558 else if (GetBitmapFormatType().Equals(format)) | 559 if (GetBitmapFormatType().Equals(format)) |
| 559 return clipboard->IsFormatAvailable(BITMAP); | 560 return clipboard->IsFormatAvailable(BITMAP); |
| 560 else if (GetWebKitSmartPasteFormatType().Equals(format)) | 561 if (GetWebKitSmartPasteFormatType().Equals(format)) |
| 561 return clipboard->IsFormatAvailable(WEB); | 562 return clipboard->IsFormatAvailable(WEB); |
| 562 else { | 563 const ClipboardData* data = clipboard->GetData(); |
| 563 const ClipboardData* data = clipboard->GetData(); | 564 return data && data->custom_data_format() == format.ToString(); |
| 564 if (data && data->custom_data_format() == format.ToString()) | |
| 565 return true; | |
| 566 } | |
| 567 return false; | |
| 568 } | 565 } |
| 569 | 566 |
| 570 void ClipboardAura::Clear(ClipboardType type) { | 567 void ClipboardAura::Clear(ClipboardType type) { |
| 571 DCHECK(CalledOnValidThread()); | 568 DCHECK(CalledOnValidThread()); |
| 572 DCHECK(IsSupportedClipboardType(type)); | 569 DCHECK(IsSupportedClipboardType(type)); |
| 573 AuraClipboard* clipboard = GetClipboard(); | 570 AuraClipboard* clipboard = GetClipboard(); |
| 574 clipboard->Clear(); | 571 clipboard->Clear(); |
| 575 } | 572 } |
| 576 | 573 |
| 577 void ClipboardAura::ReadAvailableTypes(ClipboardType type, | 574 void ClipboardAura::ReadAvailableTypes(ClipboardType type, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 ClipboardDataBuilder::WriteBitmap(bitmap); | 687 ClipboardDataBuilder::WriteBitmap(bitmap); |
| 691 } | 688 } |
| 692 | 689 |
| 693 void ClipboardAura::WriteData(const FormatType& format, | 690 void ClipboardAura::WriteData(const FormatType& format, |
| 694 const char* data_data, | 691 const char* data_data, |
| 695 size_t data_len) { | 692 size_t data_len) { |
| 696 ClipboardDataBuilder::WriteData(format.ToString(), data_data, data_len); | 693 ClipboardDataBuilder::WriteData(format.ToString(), data_data, data_len); |
| 697 } | 694 } |
| 698 | 695 |
| 699 } // namespace ui | 696 } // namespace ui |
| OLD | NEW |