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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 break; | 596 break; |
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), |
jianli
2013/04/26 01:07:18
in_drag_loop_ is not initialized.
dcheng
2013/04/26 18:05:44
Done.
| |
601 in_async_mode_(false), | 607 in_async_mode_(false), |
602 async_operation_started_(false), | 608 async_operation_started_(false), |
603 observer_(NULL) { | 609 observer_(NULL) { |
604 } | 610 } |
605 | 611 |
606 DataObjectImpl::~DataObjectImpl() { | 612 DataObjectImpl::~DataObjectImpl() { |
607 StopDownloads(); | 613 StopDownloads(); |
608 STLDeleteContainerPointers(contents_.begin(), contents_.end()); | 614 STLDeleteContainerPointers(contents_.begin(), contents_.end()); |
609 if (observer_) | 615 if (observer_) |
610 observer_->OnDataObjectDisposed(); | 616 observer_->OnDataObjectDisposed(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
667 | 673 |
668 StoredData::iterator iter = contents_.begin(); | 674 StoredData::iterator iter = contents_.begin(); |
669 while (iter != contents_.end()) { | 675 while (iter != contents_.end()) { |
670 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat && | 676 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat && |
671 (*iter)->format_etc.lindex == format_etc->lindex && | 677 (*iter)->format_etc.lindex == format_etc->lindex && |
672 ((*iter)->format_etc.tymed & format_etc->tymed)) { | 678 ((*iter)->format_etc.tymed & format_etc->tymed)) { |
673 // If medium is NULL, delay-rendering will be used. | 679 // If medium is NULL, delay-rendering will be used. |
674 if ((*iter)->medium) { | 680 if ((*iter)->medium) { |
675 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); | 681 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); |
676 } else { | 682 } else { |
677 // Check if the left button is down. | 683 // Fail all GetData() attempts for DownloadURL data if the drag and drop |
678 bool is_left_button_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0; | 684 // operation is still in progress. |
685 if (in_drag_loop_) | |
686 return DV_E_FORMATETC; | |
679 | 687 |
680 bool wait_for_data = false; | 688 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 | 689 |
688 // In async mode, we do not want to start waiting for the data before | 690 // 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 | 691 // 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 | 692 // until Shell kicks off a background thread to do the work so that |
691 // we do not block the UI thread. | 693 // we do not block the UI thread. |
692 if (!in_async_mode_ || async_operation_started_) | 694 if (!in_async_mode_ || async_operation_started_) |
693 wait_for_data = true; | 695 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) { | |
jianli
2013/04/26 01:07:18
I am a bit concerned about this logic being remove
dcheng
2013/04/26 18:05:44
I have tested on XP, Vista, 7, and 8, and it works
| |
699 (*iter)->in_delay_rendering = true; | |
700 memset(medium, 0, sizeof(STGMEDIUM)); | |
701 } else { | |
702 wait_for_data = true; | |
703 } | |
704 } | |
705 | 696 |
706 if (!wait_for_data) | 697 if (!wait_for_data) |
707 return DV_E_FORMATETC; | 698 return DV_E_FORMATETC; |
708 | 699 |
709 // Notify the observer we start waiting for the data. This gives | 700 // Notify the observer we start waiting for the data. This gives |
710 // an observer a chance to end the drag and drop. | 701 // an observer a chance to end the drag and drop. |
711 if (observer_) | 702 if (observer_) |
712 observer_->OnWaitForData(); | 703 observer_->OnWaitForData(); |
713 | 704 |
714 // Now we can start the download. | 705 // Now we can start the download. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
762 *local_medium = *medium; | 753 *local_medium = *medium; |
763 } else { | 754 } else { |
764 DuplicateMedium(format_etc->cfFormat, medium, local_medium); | 755 DuplicateMedium(format_etc->cfFormat, medium, local_medium); |
765 } | 756 } |
766 | 757 |
767 DataObjectImpl::StoredDataInfo* info = | 758 DataObjectImpl::StoredDataInfo* info = |
768 new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium); | 759 new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium); |
769 info->medium->tymed = format_etc->tymed; | 760 info->medium->tymed = format_etc->tymed; |
770 info->owns_medium = !!should_release; | 761 info->owns_medium = !!should_release; |
771 // Make newly added data appear first. | 762 // Make newly added data appear first. |
763 // TODO(dcheng): Make various setters agree whether elements should be | |
764 // prioritized from front to back or back to front. | |
772 contents_.insert(contents_.begin(), info); | 765 contents_.insert(contents_.begin(), info); |
773 | 766 |
774 return S_OK; | 767 return S_OK; |
775 } | 768 } |
776 | 769 |
777 HRESULT DataObjectImpl::EnumFormatEtc( | 770 HRESULT DataObjectImpl::EnumFormatEtc( |
778 DWORD direction, IEnumFORMATETC** enumerator) { | 771 DWORD direction, IEnumFORMATETC** enumerator) { |
779 if (direction == DATADIR_GET) { | 772 if (direction == DATADIR_GET) { |
780 FormatEtcEnumerator* e = | 773 FormatEtcEnumerator* e = |
781 new FormatEtcEnumerator(contents_.begin(), contents_.end()); | 774 new FormatEtcEnumerator(contents_.begin(), contents_.end()); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 return new OSExchangeDataProviderWin(); | 979 return new OSExchangeDataProviderWin(); |
987 } | 980 } |
988 | 981 |
989 // static | 982 // static |
990 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( | 983 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( |
991 const std::string& type) { | 984 const std::string& type) { |
992 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str()); | 985 return RegisterClipboardFormat(ASCIIToUTF16(type).c_str()); |
993 } | 986 } |
994 | 987 |
995 } // namespace ui | 988 } // namespace ui |
OLD | NEW |