tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / platform / win / DragDataWin.cpp
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DragData.h"
28
29 #include "COMPtr.h"
30 #include "ClipboardUtilitiesWin.h"
31 #include "Frame.h"
32 #include "DocumentFragment.h"
33 #include "PlatformString.h"
34 #include "Markup.h"
35 #include "TextEncoding.h"
36 #include <objidl.h>
37 #include <shlwapi.h>
38 #include <wininet.h>
39 #include <wtf/Forward.h>
40 #include <wtf/Hashmap.h>
41 #include <wtf/PassRefPtr.h>
42 #include <wtf/RefPtr.h>
43
44 namespace WebCore {
45
46 DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition,
47     DragOperation sourceOperationMask, DragApplicationFlags flags)
48     : m_clientPosition(clientPosition)
49     , m_globalPosition(globalPosition)
50     , m_platformDragData(0)
51     , m_draggingSourceOperationMask(sourceOperationMask)
52     , m_applicationFlags(flags)
53     , m_dragDataMap(data)
54 {
55 }
56
57 bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const
58 {
59     if (m_platformDragData)
60         return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat())) 
61             || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat()))
62             || (filenamePolicy == ConvertFilenames
63                 && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat()))
64                     || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat()))));
65     return m_dragDataMap.contains(urlWFormat()->cfFormat) || m_dragDataMap.contains(urlFormat()->cfFormat)
66         || (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat)));
67 }
68
69 const DragDataMap& DragData::dragDataMap()
70 {
71     if (!m_dragDataMap.isEmpty() || !m_platformDragData)
72         return m_dragDataMap;
73     // Enumerate clipboard content and load it in the map.
74     COMPtr<IEnumFORMATETC> itr;
75
76     if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
77         return m_dragDataMap;
78
79     FORMATETC dataFormat;
80     while (itr->Next(1, &dataFormat, 0) == S_OK) {
81         Vector<String> dataStrings;
82         getClipboardData(m_platformDragData, &dataFormat, dataStrings);
83         if (!dataStrings.isEmpty())
84             m_dragDataMap.set(dataFormat.cfFormat, dataStrings); 
85     }
86     return m_dragDataMap;
87 }
88
89 void DragData::getDragFileDescriptorData(int& size, String& pathname)
90 {
91     size = 0;
92     if (m_platformDragData)
93         getFileDescriptorData(m_platformDragData, size, pathname);
94 }
95
96 void DragData::getDragFileContentData(int size, void* dataBlob)
97 {
98     if (m_platformDragData)
99         getFileContentData(m_platformDragData, size, dataBlob);
100 }
101
102 String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const
103 {
104     bool success;
105     return (m_platformDragData) ? getURL(m_platformDragData, filenamePolicy, success, title) : getURL(&m_dragDataMap, filenamePolicy, title);
106 }
107
108 bool DragData::containsFiles() const
109 {
110     return (m_platformDragData) ? SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat())) : m_dragDataMap.contains(cfHDropFormat()->cfFormat);
111 }
112
113 unsigned DragData::numberOfFiles() const
114 {
115     return 0;
116 }
117
118 void DragData::asFilenames(Vector<String>& result) const
119 {
120     if (m_platformDragData) {
121         WCHAR filename[MAX_PATH];
122         
123         STGMEDIUM medium;
124         if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
125             return;
126         
127         HDROP hdrop = (HDROP)GlobalLock(medium.hGlobal);
128         
129         if (!hdrop)
130             return;
131
132         const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
133         for (unsigned i = 0; i < numFiles; i++) {
134             if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
135                 continue;
136             result.append((UChar*)filename);
137         }
138
139         // Free up memory from drag
140         DragFinish(hdrop);
141
142         GlobalUnlock(medium.hGlobal);
143         return;
144     }
145     result = m_dragDataMap.get(cfHDropFormat()->cfFormat);
146 }
147
148 bool DragData::containsPlainText() const
149 {
150     if (m_platformDragData)
151         return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat()))
152             || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat()));
153     return m_dragDataMap.contains(plainTextWFormat()->cfFormat) || m_dragDataMap.contains(plainTextFormat()->cfFormat);
154 }
155
156 String DragData::asPlainText(Frame*) const
157 {
158     bool success;
159     return (m_platformDragData) ? getPlainText(m_platformDragData, success) : getPlainText(&m_dragDataMap);
160 }
161
162 bool DragData::containsColor() const
163 {
164     return false;
165 }
166
167 bool DragData::canSmartReplace() const
168 {
169     if (m_platformDragData)
170         return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat()));
171     return m_dragDataMap.contains(smartPasteFormat()->cfFormat);
172 }
173
174 bool DragData::containsCompatibleContent() const
175 {
176     return containsPlainText() || containsURL(0) 
177         || ((m_platformDragData) ? (containsHTML(m_platformDragData) || containsFilenames(m_platformDragData))
178             : (containsHTML(&m_dragDataMap) || containsFilenames(&m_dragDataMap)))
179         || containsColor();
180 }
181
182 PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
183 {     
184     /*
185      * Order is richest format first. On OSX this is:
186      * * Web Archive
187      * * Filenames
188      * * HTML
189      * * RTF
190      * * TIFF
191      * * PICT
192      */
193      
194     if (m_platformDragData) {
195         if (containsFilenames(m_platformDragData)) {
196             if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), m_platformDragData))
197                 return fragment;
198         }
199
200         if (containsHTML(m_platformDragData)) {
201             if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), m_platformDragData))
202                 return fragment;
203         }
204     } else {
205         if (containsFilenames(&m_dragDataMap)) {
206             if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), &m_dragDataMap))
207                 return fragment;
208         }
209
210         if (containsHTML(&m_dragDataMap)) {
211             if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), &m_dragDataMap))
212                 return fragment;
213         }
214     }
215     return 0;
216 }
217
218 Color DragData::asColor() const
219 {
220     return Color();
221 }
222
223 }