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/dragdrop/os_exchange_data_provider_win.h" | 5 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 483 } |
484 | 484 |
485 bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const { | 485 bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const { |
486 FORMATETC format_etc = | 486 FORMATETC format_etc = |
487 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; | 487 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; |
488 return (source_object_->QueryGetData(&format_etc) == S_OK); | 488 return (source_object_->QueryGetData(&format_etc) == S_OK); |
489 } | 489 } |
490 | 490 |
491 void OSExchangeDataProviderWin::SetDownloadFileInfo( | 491 void OSExchangeDataProviderWin::SetDownloadFileInfo( |
492 const OSExchangeData::DownloadFileInfo& download) { | 492 const OSExchangeData::DownloadFileInfo& download) { |
493 // If the filename is not provided, set stoarge to NULL to indicate that | 493 // If the filename is not provided, set storage to NULL to indicate that |
494 // the delay rendering will be used. | 494 // the delay rendering will be used. |
| 495 // TODO(dcheng): Is it actually possible for filename to be empty here? I |
| 496 // think we always synthesize one in WebContentsDragWin. |
495 STGMEDIUM* storage = NULL; | 497 STGMEDIUM* storage = NULL; |
496 if (!download.filename.empty()) | 498 if (!download.filename.empty()) |
497 storage = GetStorageForFileName(download.filename); | 499 storage = GetStorageForFileName(download.filename); |
498 | 500 |
499 // Add CF_HDROP. | 501 // Add CF_HDROP. |
500 DataObjectImpl::StoredDataInfo* info = new DataObjectImpl::StoredDataInfo( | 502 DataObjectImpl::StoredDataInfo* info = new DataObjectImpl::StoredDataInfo( |
501 ClipboardUtil::GetCFHDropFormat()->cfFormat, storage); | 503 ClipboardUtil::GetCFHDropFormat()->cfFormat, storage); |
502 info->downloader = download.downloader; | 504 info->downloader = download.downloader; |
503 data_->contents_.push_back(info); | 505 data_->contents_.push_back(info); |
504 } | 506 } |
505 | 507 |
| 508 void OSExchangeDataProviderWin::SetInDragLoop(bool in_drag_loop) { |
| 509 data_->set_in_drag_loop(in_drag_loop); |
| 510 } |
| 511 |
506 #if defined(USE_AURA) | 512 #if defined(USE_AURA) |
507 | 513 |
508 void OSExchangeDataProviderWin::SetDragImage( | 514 void OSExchangeDataProviderWin::SetDragImage( |
509 const gfx::ImageSkia& image, | 515 const gfx::ImageSkia& image, |
510 const gfx::Vector2d& cursor_offset) { | 516 const gfx::Vector2d& cursor_offset) { |
511 drag_image_ = image; | 517 drag_image_ = image; |
512 drag_image_offset_ = cursor_offset; | 518 drag_image_offset_ = cursor_offset; |
513 } | 519 } |
514 | 520 |
515 const gfx::ImageSkia& OSExchangeDataProviderWin::GetDragImage() const { | 521 const gfx::ImageSkia& OSExchangeDataProviderWin::GetDragImage() const { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 } | 597 } |
592 | 598 |
593 destination->tymed = source->tymed; | 599 destination->tymed = source->tymed; |
594 destination->pUnkForRelease = source->pUnkForRelease; | 600 destination->pUnkForRelease = source->pUnkForRelease; |
595 if (destination->pUnkForRelease) | 601 if (destination->pUnkForRelease) |
596 destination->pUnkForRelease->AddRef(); | 602 destination->pUnkForRelease->AddRef(); |
597 } | 603 } |
598 | 604 |
599 DataObjectImpl::DataObjectImpl() | 605 DataObjectImpl::DataObjectImpl() |
600 : is_aborting_(false), | 606 : is_aborting_(false), |
| 607 in_drag_loop_(false), |
601 in_async_mode_(false), | 608 in_async_mode_(false), |
602 async_operation_started_(false), | 609 async_operation_started_(false), |
603 observer_(NULL) { | 610 observer_(NULL) { |
604 } | 611 } |
605 | 612 |
606 DataObjectImpl::~DataObjectImpl() { | 613 DataObjectImpl::~DataObjectImpl() { |
607 StopDownloads(); | 614 StopDownloads(); |
608 STLDeleteContainerPointers(contents_.begin(), contents_.end()); | 615 STLDeleteContainerPointers(contents_.begin(), contents_.end()); |
609 if (observer_) | 616 if (observer_) |
610 observer_->OnDataObjectDisposed(); | 617 observer_->OnDataObjectDisposed(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 | 674 |
668 StoredData::iterator iter = contents_.begin(); | 675 StoredData::iterator iter = contents_.begin(); |
669 while (iter != contents_.end()) { | 676 while (iter != contents_.end()) { |
670 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat && | 677 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat && |
671 (*iter)->format_etc.lindex == format_etc->lindex && | 678 (*iter)->format_etc.lindex == format_etc->lindex && |
672 ((*iter)->format_etc.tymed & format_etc->tymed)) { | 679 ((*iter)->format_etc.tymed & format_etc->tymed)) { |
673 // If medium is NULL, delay-rendering will be used. | 680 // If medium is NULL, delay-rendering will be used. |
674 if ((*iter)->medium) { | 681 if ((*iter)->medium) { |
675 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); | 682 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); |
676 } else { | 683 } else { |
677 // Check if the left button is down. | 684 // Fail all GetData() attempts for DownloadURL data if the drag and drop |
678 bool is_left_button_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0; | 685 // operation is still in progress. |
| 686 if (in_drag_loop_) |
| 687 return DV_E_FORMATETC; |
679 | 688 |
680 bool wait_for_data = false; | 689 bool wait_for_data = false; |
681 if ((*iter)->in_delay_rendering) { | |
682 // Make sure the left button is up. Sometimes the drop target, like | |
683 // Shell, might be too aggresive in calling GetData when the left | |
684 // button is not released. | |
685 if (is_left_button_down) | |
686 return DV_E_FORMATETC; | |
687 | 690 |
688 // In async mode, we do not want to start waiting for the data before | 691 // In async mode, we do not want to start waiting for the data before |
689 // the async operation is started. This is because we want to postpone | 692 // the async operation is started. This is because we want to postpone |
690 // until Shell kicks off a background thread to do the work so that | 693 // until Shell kicks off a background thread to do the work so that |
691 // we do not block the UI thread. | 694 // we do not block the UI thread. |
692 if (!in_async_mode_ || async_operation_started_) | 695 if (!in_async_mode_ || async_operation_started_) |
693 wait_for_data = true; | 696 wait_for_data = true; |
694 } else { | |
695 // If the left button is up and the target has not requested the data | |
696 // yet, it probably means that the target does not support delay- | |
697 // rendering. So instead, we wait for the data. | |
698 if (is_left_button_down) { | |
699 (*iter)->in_delay_rendering = true; | |
700 memset(medium, 0, sizeof(STGMEDIUM)); | |
701 } else { | |
702 wait_for_data = true; | |
703 } | |
704 } | |
705 | 697 |
706 if (!wait_for_data) | 698 if (!wait_for_data) |
707 return DV_E_FORMATETC; | 699 return DV_E_FORMATETC; |
708 | 700 |
709 // Notify the observer we start waiting for the data. This gives | 701 // Notify the observer we start waiting for the data. This gives |
710 // an observer a chance to end the drag and drop. | 702 // an observer a chance to end the drag and drop. |
711 if (observer_) | 703 if (observer_) |
712 observer_->OnWaitForData(); | 704 observer_->OnWaitForData(); |
713 | 705 |
714 // Now we can start the download. | 706 // Now we can start the download. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 *local_medium = *medium; | 754 *local_medium = *medium; |
763 } else { | 755 } else { |
764 DuplicateMedium(format_etc->cfFormat, medium, local_medium); | 756 DuplicateMedium(format_etc->cfFormat, medium, local_medium); |
765 } | 757 } |
766 | 758 |
767 DataObjectImpl::StoredDataInfo* info = | 759 DataObjectImpl::StoredDataInfo* info = |
768 new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium); | 760 new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium); |
769 info->medium->tymed = format_etc->tymed; | 761 info->medium->tymed = format_etc->tymed; |
770 info->owns_medium = !!should_release; | 762 info->owns_medium = !!should_release; |
771 // Make newly added data appear first. | 763 // Make newly added data appear first. |
| 764 // TODO(dcheng): Make various setters agree whether elements should be |
| 765 // prioritized from front to back or back to front. |
772 contents_.insert(contents_.begin(), info); | 766 contents_.insert(contents_.begin(), info); |
773 | 767 |
774 return S_OK; | 768 return S_OK; |
775 } | 769 } |
776 | 770 |
777 HRESULT DataObjectImpl::EnumFormatEtc( | 771 HRESULT DataObjectImpl::EnumFormatEtc( |
778 DWORD direction, IEnumFORMATETC** enumerator) { | 772 DWORD direction, IEnumFORMATETC** enumerator) { |
779 if (direction == DATADIR_GET) { | 773 if (direction == DATADIR_GET) { |
780 FormatEtcEnumerator* e = | 774 FormatEtcEnumerator* e = |
781 new FormatEtcEnumerator(contents_.begin(), contents_.end()); | 775 new FormatEtcEnumerator(contents_.begin(), contents_.end()); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 return new OSExchangeDataProviderWin(); | 980 return new OSExchangeDataProviderWin(); |
987 } | 981 } |
988 | 982 |
989 // static | 983 // static |
990 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( | 984 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( |
991 const std::string& type) { | 985 const std::string& type) { |
992 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str()); | 986 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str()); |
993 } | 987 } |
994 | 988 |
995 } // namespace ui | 989 } // namespace ui |
OLD | NEW |