| 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_util_win.h" | 5 #include "ui/base/clipboard/clipboard_util_win.h" |
| 6 | 6 |
| 7 #include <shellapi.h> | 7 #include <shellapi.h> |
| 8 #include <shlwapi.h> | 8 #include <shlwapi.h> |
| 9 #include <wininet.h> // For INTERNET_MAX_URL_LENGTH. | 9 #include <wininet.h> // For INTERNET_MAX_URL_LENGTH. |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 return SUCCEEDED(data_object->QueryGetData(&format_etc)); | 27 return SUCCEEDED(data_object->QueryGetData(&format_etc)); |
| 28 } | 28 } |
| 29 | 29 |
| 30 bool GetData(IDataObject* data_object, | 30 bool GetData(IDataObject* data_object, |
| 31 const Clipboard::FormatType& format, | 31 const Clipboard::FormatType& format, |
| 32 STGMEDIUM* medium) { | 32 STGMEDIUM* medium) { |
| 33 FORMATETC format_etc = format.ToFormatEtc(); | 33 FORMATETC format_etc = format.ToFormatEtc(); |
| 34 return SUCCEEDED(data_object->GetData(&format_etc, medium)); | 34 return SUCCEEDED(data_object->GetData(&format_etc, medium)); |
| 35 } | 35 } |
| 36 | 36 |
| 37 bool GetUrlFromHDrop(IDataObject* data_object, string16* url, string16* title) { | 37 bool GetUrlFromHDrop(IDataObject* data_object, |
| 38 base::string16* url, |
| 39 base::string16* title) { |
| 38 DCHECK(data_object && url && title); | 40 DCHECK(data_object && url && title); |
| 39 | 41 |
| 40 STGMEDIUM medium; | 42 STGMEDIUM medium; |
| 41 if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) | 43 if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) |
| 42 return false; | 44 return false; |
| 43 | 45 |
| 44 HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); | 46 HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); |
| 45 | 47 |
| 46 if (!hdrop) | 48 if (!hdrop) |
| 47 return false; | 49 return false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 60 } | 62 } |
| 61 } | 63 } |
| 62 | 64 |
| 63 DragFinish(hdrop); | 65 DragFinish(hdrop); |
| 64 GlobalUnlock(medium.hGlobal); | 66 GlobalUnlock(medium.hGlobal); |
| 65 // We don't need to call ReleaseStgMedium here because as far as I can tell, | 67 // We don't need to call ReleaseStgMedium here because as far as I can tell, |
| 66 // DragFinish frees the hGlobal for us. | 68 // DragFinish frees the hGlobal for us. |
| 67 return success; | 69 return success; |
| 68 } | 70 } |
| 69 | 71 |
| 70 void SplitUrlAndTitle(const string16& str, | 72 void SplitUrlAndTitle(const base::string16& str, |
| 71 string16* url, | 73 base::string16* url, |
| 72 string16* title) { | 74 base::string16* title) { |
| 73 DCHECK(url && title); | 75 DCHECK(url && title); |
| 74 size_t newline_pos = str.find('\n'); | 76 size_t newline_pos = str.find('\n'); |
| 75 if (newline_pos != string16::npos) { | 77 if (newline_pos != base::string16::npos) { |
| 76 url->assign(str, 0, newline_pos); | 78 url->assign(str, 0, newline_pos); |
| 77 title->assign(str, newline_pos + 1, string16::npos); | 79 title->assign(str, newline_pos + 1, base::string16::npos); |
| 78 } else { | 80 } else { |
| 79 url->assign(str); | 81 url->assign(str); |
| 80 title->assign(str); | 82 title->assign(str); |
| 81 } | 83 } |
| 82 } | 84 } |
| 83 | 85 |
| 84 bool GetFileUrl(IDataObject* data_object, string16* url, | 86 bool GetFileUrl(IDataObject* data_object, base::string16* url, |
| 85 string16* title) { | 87 base::string16* title) { |
| 86 STGMEDIUM store; | 88 STGMEDIUM store; |
| 87 if (GetData(data_object, Clipboard::GetFilenameWFormatType(), &store)) { | 89 if (GetData(data_object, Clipboard::GetFilenameWFormatType(), &store)) { |
| 88 bool success = false; | 90 bool success = false; |
| 89 { | 91 { |
| 90 // filename using unicode | 92 // filename using unicode |
| 91 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); | 93 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
| 92 if (data.get() && data.get()[0] && | 94 if (data.get() && data.get()[0] && |
| 93 (PathFileExists(data.get()) || PathIsUNC(data.get()))) { | 95 (PathFileExists(data.get()) || PathIsUNC(data.get()))) { |
| 94 wchar_t file_url[INTERNET_MAX_URL_LENGTH]; | 96 wchar_t file_url[INTERNET_MAX_URL_LENGTH]; |
| 95 DWORD file_url_len = arraysize(file_url); | 97 DWORD file_url_len = arraysize(file_url); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 HasData(data_object, Clipboard::GetTextHtmlFormatType()); | 159 HasData(data_object, Clipboard::GetTextHtmlFormatType()); |
| 158 } | 160 } |
| 159 | 161 |
| 160 bool ClipboardUtil::HasPlainText(IDataObject* data_object) { | 162 bool ClipboardUtil::HasPlainText(IDataObject* data_object) { |
| 161 DCHECK(data_object); | 163 DCHECK(data_object); |
| 162 return HasData(data_object, Clipboard::GetPlainTextWFormatType()) || | 164 return HasData(data_object, Clipboard::GetPlainTextWFormatType()) || |
| 163 HasData(data_object, Clipboard::GetPlainTextFormatType()); | 165 HasData(data_object, Clipboard::GetPlainTextFormatType()); |
| 164 } | 166 } |
| 165 | 167 |
| 166 bool ClipboardUtil::GetUrl(IDataObject* data_object, | 168 bool ClipboardUtil::GetUrl(IDataObject* data_object, |
| 167 string16* url, string16* title, bool convert_filenames) { | 169 base::string16* url, base::string16* title, bool convert_filenames) { |
| 168 DCHECK(data_object && url && title); | 170 DCHECK(data_object && url && title); |
| 169 if (!HasUrl(data_object)) | 171 if (!HasUrl(data_object)) |
| 170 return false; | 172 return false; |
| 171 | 173 |
| 172 // Try to extract a URL from |data_object| in a variety of formats. | 174 // Try to extract a URL from |data_object| in a variety of formats. |
| 173 STGMEDIUM store; | 175 STGMEDIUM store; |
| 174 if (GetUrlFromHDrop(data_object, url, title)) | 176 if (GetUrlFromHDrop(data_object, url, title)) |
| 175 return true; | 177 return true; |
| 176 | 178 |
| 177 if (GetData(data_object, Clipboard::GetMozUrlFormatType(), &store) || | 179 if (GetData(data_object, Clipboard::GetMozUrlFormatType(), &store) || |
| (...skipping 18 matching lines...) Expand all Loading... |
| 196 } | 198 } |
| 197 | 199 |
| 198 if (convert_filenames) { | 200 if (convert_filenames) { |
| 199 return GetFileUrl(data_object, url, title); | 201 return GetFileUrl(data_object, url, title); |
| 200 } else { | 202 } else { |
| 201 return false; | 203 return false; |
| 202 } | 204 } |
| 203 } | 205 } |
| 204 | 206 |
| 205 bool ClipboardUtil::GetFilenames(IDataObject* data_object, | 207 bool ClipboardUtil::GetFilenames(IDataObject* data_object, |
| 206 std::vector<string16>* filenames) { | 208 std::vector<base::string16>* filenames) { |
| 207 DCHECK(data_object && filenames); | 209 DCHECK(data_object && filenames); |
| 208 if (!HasFilenames(data_object)) | 210 if (!HasFilenames(data_object)) |
| 209 return false; | 211 return false; |
| 210 | 212 |
| 211 STGMEDIUM medium; | 213 STGMEDIUM medium; |
| 212 if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) | 214 if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) |
| 213 return false; | 215 return false; |
| 214 | 216 |
| 215 HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); | 217 HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); |
| 216 if (!hdrop) | 218 if (!hdrop) |
| 217 return false; | 219 return false; |
| 218 | 220 |
| 219 const int kMaxFilenameLen = 4096; | 221 const int kMaxFilenameLen = 4096; |
| 220 const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0); | 222 const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0); |
| 221 for (unsigned int i = 0; i < num_files; ++i) { | 223 for (unsigned int i = 0; i < num_files; ++i) { |
| 222 wchar_t filename[kMaxFilenameLen]; | 224 wchar_t filename[kMaxFilenameLen]; |
| 223 if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen)) | 225 if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen)) |
| 224 continue; | 226 continue; |
| 225 filenames->push_back(filename); | 227 filenames->push_back(filename); |
| 226 } | 228 } |
| 227 | 229 |
| 228 DragFinish(hdrop); | 230 DragFinish(hdrop); |
| 229 GlobalUnlock(medium.hGlobal); | 231 GlobalUnlock(medium.hGlobal); |
| 230 // We don't need to call ReleaseStgMedium here because as far as I can tell, | 232 // We don't need to call ReleaseStgMedium here because as far as I can tell, |
| 231 // DragFinish frees the hGlobal for us. | 233 // DragFinish frees the hGlobal for us. |
| 232 return true; | 234 return true; |
| 233 } | 235 } |
| 234 | 236 |
| 235 bool ClipboardUtil::GetPlainText(IDataObject* data_object, | 237 bool ClipboardUtil::GetPlainText(IDataObject* data_object, |
| 236 string16* plain_text) { | 238 base::string16* plain_text) { |
| 237 DCHECK(data_object && plain_text); | 239 DCHECK(data_object && plain_text); |
| 238 if (!HasPlainText(data_object)) | 240 if (!HasPlainText(data_object)) |
| 239 return false; | 241 return false; |
| 240 | 242 |
| 241 STGMEDIUM store; | 243 STGMEDIUM store; |
| 242 if (GetData(data_object, Clipboard::GetPlainTextWFormatType(), &store)) { | 244 if (GetData(data_object, Clipboard::GetPlainTextWFormatType(), &store)) { |
| 243 { | 245 { |
| 244 // Unicode text | 246 // Unicode text |
| 245 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); | 247 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
| 246 plain_text->assign(data.get()); | 248 plain_text->assign(data.get()); |
| 247 } | 249 } |
| 248 ReleaseStgMedium(&store); | 250 ReleaseStgMedium(&store); |
| 249 return true; | 251 return true; |
| 250 } | 252 } |
| 251 | 253 |
| 252 if (GetData(data_object, Clipboard::GetPlainTextFormatType(), &store)) { | 254 if (GetData(data_object, Clipboard::GetPlainTextFormatType(), &store)) { |
| 253 { | 255 { |
| 254 // ascii text | 256 // ascii text |
| 255 base::win::ScopedHGlobal<char> data(store.hGlobal); | 257 base::win::ScopedHGlobal<char> data(store.hGlobal); |
| 256 plain_text->assign(UTF8ToWide(data.get())); | 258 plain_text->assign(UTF8ToWide(data.get())); |
| 257 } | 259 } |
| 258 ReleaseStgMedium(&store); | 260 ReleaseStgMedium(&store); |
| 259 return true; | 261 return true; |
| 260 } | 262 } |
| 261 | 263 |
| 262 // If a file is dropped on the window, it does not provide either of the | 264 // If a file is dropped on the window, it does not provide either of the |
| 263 // plain text formats, so here we try to forcibly get a url. | 265 // plain text formats, so here we try to forcibly get a url. |
| 264 string16 title; | 266 base::string16 title; |
| 265 return GetUrl(data_object, plain_text, &title, false); | 267 return GetUrl(data_object, plain_text, &title, false); |
| 266 } | 268 } |
| 267 | 269 |
| 268 bool ClipboardUtil::GetHtml(IDataObject* data_object, | 270 bool ClipboardUtil::GetHtml(IDataObject* data_object, |
| 269 string16* html, std::string* base_url) { | 271 base::string16* html, std::string* base_url) { |
| 270 DCHECK(data_object && html && base_url); | 272 DCHECK(data_object && html && base_url); |
| 271 | 273 |
| 272 STGMEDIUM store; | 274 STGMEDIUM store; |
| 273 if (HasData(data_object, Clipboard::GetHtmlFormatType()) && | 275 if (HasData(data_object, Clipboard::GetHtmlFormatType()) && |
| 274 GetData(data_object, Clipboard::GetHtmlFormatType(), &store)) { | 276 GetData(data_object, Clipboard::GetHtmlFormatType(), &store)) { |
| 275 { | 277 { |
| 276 // MS CF html | 278 // MS CF html |
| 277 base::win::ScopedHGlobal<char> data(store.hGlobal); | 279 base::win::ScopedHGlobal<char> data(store.hGlobal); |
| 278 | 280 |
| 279 std::string html_utf8; | 281 std::string html_utf8; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 293 { | 295 { |
| 294 // text/html | 296 // text/html |
| 295 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); | 297 base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
| 296 html->assign(data.get()); | 298 html->assign(data.get()); |
| 297 } | 299 } |
| 298 ReleaseStgMedium(&store); | 300 ReleaseStgMedium(&store); |
| 299 return true; | 301 return true; |
| 300 } | 302 } |
| 301 | 303 |
| 302 bool ClipboardUtil::GetFileContents(IDataObject* data_object, | 304 bool ClipboardUtil::GetFileContents(IDataObject* data_object, |
| 303 string16* filename, std::string* file_contents) { | 305 base::string16* filename, std::string* file_contents) { |
| 304 DCHECK(data_object && filename && file_contents); | 306 DCHECK(data_object && filename && file_contents); |
| 305 if (!HasData(data_object, Clipboard::GetFileContentZeroFormatType()) && | 307 if (!HasData(data_object, Clipboard::GetFileContentZeroFormatType()) && |
| 306 !HasData(data_object, Clipboard::GetFileDescriptorFormatType())) | 308 !HasData(data_object, Clipboard::GetFileDescriptorFormatType())) |
| 307 return false; | 309 return false; |
| 308 | 310 |
| 309 STGMEDIUM content; | 311 STGMEDIUM content; |
| 310 // The call to GetData can be very slow depending on what is in | 312 // The call to GetData can be very slow depending on what is in |
| 311 // |data_object|. | 313 // |data_object|. |
| 312 if (GetData( | 314 if (GetData( |
| 313 data_object, Clipboard::GetFileContentZeroFormatType(), &content)) { | 315 data_object, Clipboard::GetFileContentZeroFormatType(), &content)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 327 // We expect there to be at least one file in here. | 329 // We expect there to be at least one file in here. |
| 328 DCHECK_GE(fgd->cItems, 1u); | 330 DCHECK_GE(fgd->cItems, 1u); |
| 329 filename->assign(fgd->fgd[0].cFileName); | 331 filename->assign(fgd->fgd[0].cFileName); |
| 330 } | 332 } |
| 331 ReleaseStgMedium(&description); | 333 ReleaseStgMedium(&description); |
| 332 } | 334 } |
| 333 return true; | 335 return true; |
| 334 } | 336 } |
| 335 | 337 |
| 336 bool ClipboardUtil::GetWebCustomData( | 338 bool ClipboardUtil::GetWebCustomData( |
| 337 IDataObject* data_object, std::map<string16, string16>* custom_data) { | 339 IDataObject* data_object, |
| 340 std::map<base::string16, base::string16>* custom_data) { |
| 338 DCHECK(data_object && custom_data); | 341 DCHECK(data_object && custom_data); |
| 339 | 342 |
| 340 if (!HasData(data_object, Clipboard::GetWebCustomDataFormatType())) | 343 if (!HasData(data_object, Clipboard::GetWebCustomDataFormatType())) |
| 341 return false; | 344 return false; |
| 342 | 345 |
| 343 STGMEDIUM store; | 346 STGMEDIUM store; |
| 344 if (GetData(data_object, Clipboard::GetWebCustomDataFormatType(), &store)) { | 347 if (GetData(data_object, Clipboard::GetWebCustomDataFormatType(), &store)) { |
| 345 { | 348 { |
| 346 base::win::ScopedHGlobal<char> data(store.hGlobal); | 349 base::win::ScopedHGlobal<char> data(store.hGlobal); |
| 347 ReadCustomDataIntoMap(data.get(), data.Size(), custom_data); | 350 ReadCustomDataIntoMap(data.get(), data.Size(), custom_data); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 end_fragment_start + end_fragment_str.length())); | 503 end_fragment_start + end_fragment_str.length())); |
| 501 } | 504 } |
| 502 } else { | 505 } else { |
| 503 *fragment_start = cf_html.find('>', tag_start) + 1; | 506 *fragment_start = cf_html.find('>', tag_start) + 1; |
| 504 size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos); | 507 size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos); |
| 505 *fragment_end = cf_html.rfind('<', tag_end); | 508 *fragment_end = cf_html.rfind('<', tag_end); |
| 506 } | 509 } |
| 507 } | 510 } |
| 508 | 511 |
| 509 } // namespace ui | 512 } // namespace ui |
| OLD | NEW |