OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 // Many of these functions are based on those found in | 5 // Many of these functions are based on those found in |
6 // webkit/port/platform/PasteboardWin.cpp | 6 // webkit/port/platform/PasteboardWin.cpp |
7 | 7 |
8 #include "base/clipboard.h" | 8 #include "base/clipboard.h" |
9 | 9 |
10 #include <shlobj.h> | 10 #include <shlobj.h> |
11 #include <shellapi.h> | 11 #include <shellapi.h> |
12 | 12 |
13 #include "base/clipboard_util.h" | 13 #include "base/clipboard_util.h" |
| 14 #include "base/lock.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/shared_memory.h" | 17 #include "base/shared_memory.h" |
17 #include "base/string_util.h" | 18 #include "base/string_util.h" |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // A scoper to manage acquiring and automatically releasing the clipboard. | 22 // A scoper to manage acquiring and automatically releasing the clipboard. |
22 class ScopedClipboard { | 23 class ScopedClipboard { |
23 public: | 24 public: |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 if (iter->first == CBF_SMBITMAP) | 163 if (iter->first == CBF_SMBITMAP) |
163 WriteBitmapFromSharedMemory(&(iter->second[0].front()), | 164 WriteBitmapFromSharedMemory(&(iter->second[0].front()), |
164 &(iter->second[1].front()), | 165 &(iter->second[1].front()), |
165 process); | 166 process); |
166 else | 167 else |
167 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 168 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
168 } | 169 } |
169 } | 170 } |
170 | 171 |
171 void Clipboard::WriteText(const char* text_data, size_t text_len) { | 172 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
172 std::wstring text; | 173 string16 text; |
173 UTF8ToWide(text_data, text_len, &text); | 174 UTF8ToUTF16(text_data, text_len, &text); |
174 HGLOBAL glob = CreateGlobalData(text); | 175 HGLOBAL glob = CreateGlobalData(text); |
175 | 176 |
176 WriteToClipboard(CF_UNICODETEXT, glob); | 177 WriteToClipboard(CF_UNICODETEXT, glob); |
177 } | 178 } |
178 | 179 |
179 void Clipboard::WriteHTML(const char* markup_data, | 180 void Clipboard::WriteHTML(const char* markup_data, |
180 size_t markup_len, | 181 size_t markup_len, |
181 const char* url_data, | 182 const char* url_data, |
182 size_t url_len) { | 183 size_t url_len) { |
183 std::string markup(markup_data, markup_len); | 184 std::string markup(markup_data, markup_len); |
184 std::string url; | 185 std::string url; |
185 | 186 |
186 if (url_len > 0) | 187 if (url_len > 0) |
187 url.assign(url_data, url_len); | 188 url.assign(url_data, url_len); |
188 | 189 |
189 std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); | 190 std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); |
190 HGLOBAL glob = CreateGlobalData(html_fragment); | 191 HGLOBAL glob = CreateGlobalData(html_fragment); |
191 | 192 |
192 WriteToClipboard(GetHtmlFormatType(), glob); | 193 WriteToClipboard(GetHtmlFormatType(), glob); |
193 } | 194 } |
194 | 195 |
195 void Clipboard::WriteBookmark(const char* title_data, | 196 void Clipboard::WriteBookmark(const char* title_data, |
196 size_t title_len, | 197 size_t title_len, |
197 const char* url_data, | 198 const char* url_data, |
198 size_t url_len) { | 199 size_t url_len) { |
199 std::string bookmark(title_data, title_len); | 200 std::string bookmark(title_data, title_len); |
200 bookmark.append(1, L'\n'); | 201 bookmark.append(1, L'\n'); |
201 bookmark.append(url_data, url_len); | 202 bookmark.append(url_data, url_len); |
202 | 203 |
203 std::wstring wide_bookmark = UTF8ToWide(bookmark); | 204 string16 wide_bookmark = UTF8ToWide(bookmark); |
204 HGLOBAL glob = CreateGlobalData(wide_bookmark); | 205 HGLOBAL glob = CreateGlobalData(wide_bookmark); |
205 | 206 |
206 WriteToClipboard(GetUrlWFormatType(), glob); | 207 WriteToClipboard(GetUrlWFormatType(), glob); |
207 } | 208 } |
208 | 209 |
209 void Clipboard::WriteHyperlink(const char* title_data, | 210 void Clipboard::WriteHyperlink(const char* title_data, |
210 size_t title_len, | 211 size_t title_len, |
211 const char* url_data, | 212 const char* url_data, |
212 size_t url_len) { | 213 size_t url_len) { |
213 // Store as a bookmark. | 214 // Store as a bookmark. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 ::DeleteDC(source_dc); | 344 ::DeleteDC(source_dc); |
344 ::ReleaseDC(NULL, dc); | 345 ::ReleaseDC(NULL, dc); |
345 | 346 |
346 WriteToClipboard(CF_BITMAP, hbitmap); | 347 WriteToClipboard(CF_BITMAP, hbitmap); |
347 } | 348 } |
348 | 349 |
349 // Write a file or set of files to the clipboard in HDROP format. When the user | 350 // Write a file or set of files to the clipboard in HDROP format. When the user |
350 // invokes a paste command (in a Windows explorer shell, for example), the files | 351 // invokes a paste command (in a Windows explorer shell, for example), the files |
351 // will be copied to the paste location. | 352 // will be copied to the paste location. |
352 void Clipboard::WriteFiles(const char* file_data, size_t file_len) { | 353 void Clipboard::WriteFiles(const char* file_data, size_t file_len) { |
353 std::wstring filenames(UTF8ToWide(std::string(file_data, file_len))); | |
354 // Calculate the amount of space we'll need store the strings and | 354 // Calculate the amount of space we'll need store the strings and |
355 // a DROPFILES struct. | 355 // a DROPFILES struct. |
356 size_t bytes = sizeof(DROPFILES) + filenames.length() * sizeof(wchar_t); | 356 size_t bytes = sizeof(DROPFILES) + file_len; |
357 | 357 |
358 HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); | 358 HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); |
359 if (!hdata) | 359 if (!hdata) |
360 return; | 360 return; |
361 | 361 |
362 char* data = static_cast<char*>(::GlobalLock(hdata)); | 362 char* data = static_cast<char*>(::GlobalLock(hdata)); |
363 DROPFILES* drop_files = reinterpret_cast<DROPFILES*>(data); | 363 DROPFILES* drop_files = reinterpret_cast<DROPFILES*>(data); |
364 drop_files->pFiles = sizeof(DROPFILES); | 364 drop_files->pFiles = sizeof(DROPFILES); |
365 drop_files->fWide = TRUE; | 365 drop_files->fWide = TRUE; |
366 | 366 |
367 memcpy(data + sizeof DROPFILES, filenames.c_str(), | 367 memcpy(data + sizeof(DROPFILES), file_data, file_len); |
368 filenames.length() * sizeof(wchar_t)); | |
369 | 368 |
370 ::GlobalUnlock(hdata); | 369 ::GlobalUnlock(hdata); |
371 WriteToClipboard(CF_HDROP, hdata); | 370 WriteToClipboard(CF_HDROP, hdata); |
372 } | 371 } |
373 | 372 |
374 void Clipboard::WriteToClipboard(FormatType format, HANDLE handle) { | 373 void Clipboard::WriteToClipboard(FormatType format, HANDLE handle) { |
375 DCHECK(clipboard_owner_); | 374 DCHECK(clipboard_owner_); |
376 if (handle && !::SetClipboardData(format, handle)) { | 375 if (handle && !::SetClipboardData(format, handle)) { |
377 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); | 376 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); |
378 FreeData(format, handle); | 377 FreeData(format, handle); |
379 } | 378 } |
380 } | 379 } |
381 | 380 |
382 bool Clipboard::IsFormatAvailable(unsigned int format) const { | 381 bool Clipboard::IsFormatAvailable(unsigned int format) const { |
383 return ::IsClipboardFormatAvailable(format) != FALSE; | 382 return ::IsClipboardFormatAvailable(format) != FALSE; |
384 } | 383 } |
385 | 384 |
386 void Clipboard::ReadText(std::wstring* result) const { | 385 void Clipboard::ReadText(string16* result) const { |
387 if (!result) { | 386 if (!result) { |
388 NOTREACHED(); | 387 NOTREACHED(); |
389 return; | 388 return; |
390 } | 389 } |
391 | 390 |
392 result->clear(); | 391 result->clear(); |
393 | 392 |
394 // Acquire the clipboard. | 393 // Acquire the clipboard. |
395 ScopedClipboard clipboard; | 394 ScopedClipboard clipboard; |
396 if (!clipboard.Acquire(GetClipboardWindow())) | 395 if (!clipboard.Acquire(GetClipboardWindow())) |
397 return; | 396 return; |
398 | 397 |
399 HANDLE data = ::GetClipboardData(CF_UNICODETEXT); | 398 HANDLE data = ::GetClipboardData(CF_UNICODETEXT); |
400 if (!data) | 399 if (!data) |
401 return; | 400 return; |
402 | 401 |
403 result->assign(static_cast<const wchar_t*>(::GlobalLock(data))); | 402 result->assign(static_cast<const char16*>(::GlobalLock(data))); |
404 ::GlobalUnlock(data); | 403 ::GlobalUnlock(data); |
405 } | 404 } |
406 | 405 |
407 void Clipboard::ReadAsciiText(std::string* result) const { | 406 void Clipboard::ReadAsciiText(std::string* result) const { |
408 if (!result) { | 407 if (!result) { |
409 NOTREACHED(); | 408 NOTREACHED(); |
410 return; | 409 return; |
411 } | 410 } |
412 | 411 |
413 result->clear(); | 412 result->clear(); |
414 | 413 |
415 // Acquire the clipboard. | 414 // Acquire the clipboard. |
416 ScopedClipboard clipboard; | 415 ScopedClipboard clipboard; |
417 if (!clipboard.Acquire(GetClipboardWindow())) | 416 if (!clipboard.Acquire(GetClipboardWindow())) |
418 return; | 417 return; |
419 | 418 |
420 HANDLE data = ::GetClipboardData(CF_TEXT); | 419 HANDLE data = ::GetClipboardData(CF_TEXT); |
421 if (!data) | 420 if (!data) |
422 return; | 421 return; |
423 | 422 |
424 result->assign(static_cast<const char*>(::GlobalLock(data))); | 423 result->assign(static_cast<const char*>(::GlobalLock(data))); |
425 ::GlobalUnlock(data); | 424 ::GlobalUnlock(data); |
426 } | 425 } |
427 | 426 |
428 void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const { | 427 void Clipboard::ReadHTML(string16* markup, std::string* src_url) const { |
429 if (markup) | 428 if (markup) |
430 markup->clear(); | 429 markup->clear(); |
431 | 430 |
432 if (src_url) | 431 if (src_url) |
433 src_url->clear(); | 432 src_url->clear(); |
434 | 433 |
435 // Acquire the clipboard. | 434 // Acquire the clipboard. |
436 ScopedClipboard clipboard; | 435 ScopedClipboard clipboard; |
437 if (!clipboard.Acquire(GetClipboardWindow())) | 436 if (!clipboard.Acquire(GetClipboardWindow())) |
438 return; | 437 return; |
439 | 438 |
440 HANDLE data = ::GetClipboardData(GetHtmlFormatType()); | 439 HANDLE data = ::GetClipboardData(GetHtmlFormatType()); |
441 if (!data) | 440 if (!data) |
442 return; | 441 return; |
443 | 442 |
444 std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); | 443 std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); |
445 ::GlobalUnlock(data); | 444 ::GlobalUnlock(data); |
446 | 445 |
447 std::string markup_utf8; | 446 std::string markup_utf8; |
448 ClipboardUtil::CFHtmlToHtml(html_fragment, &markup_utf8, src_url); | 447 ClipboardUtil::CFHtmlToHtml(html_fragment, &markup_utf8, src_url); |
449 markup->assign(UTF8ToWide(markup_utf8)); | 448 markup->assign(UTF8ToWide(markup_utf8)); |
450 } | 449 } |
451 | 450 |
452 void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { | 451 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
453 if (title) | 452 if (title) |
454 title->clear(); | 453 title->clear(); |
455 | 454 |
456 if (url) | 455 if (url) |
457 url->clear(); | 456 url->clear(); |
458 | 457 |
459 // Acquire the clipboard. | 458 // Acquire the clipboard. |
460 ScopedClipboard clipboard; | 459 ScopedClipboard clipboard; |
461 if (!clipboard.Acquire(GetClipboardWindow())) | 460 if (!clipboard.Acquire(GetClipboardWindow())) |
462 return; | 461 return; |
463 | 462 |
464 HANDLE data = ::GetClipboardData(GetUrlWFormatType()); | 463 HANDLE data = ::GetClipboardData(GetUrlWFormatType()); |
465 if (!data) | 464 if (!data) |
466 return; | 465 return; |
467 | 466 |
468 std::wstring bookmark(static_cast<const wchar_t*>(::GlobalLock(data))); | 467 string16 bookmark(static_cast<const char16*>(::GlobalLock(data))); |
469 ::GlobalUnlock(data); | 468 ::GlobalUnlock(data); |
470 | 469 |
471 ParseBookmarkClipboardFormat(bookmark, title, url); | 470 ParseBookmarkClipboardFormat(bookmark, title, url); |
472 } | 471 } |
473 | 472 |
474 // Read a file in HDROP format from the clipboard. | 473 // Read a file in HDROP format from the clipboard. |
475 void Clipboard::ReadFile(std::wstring* file) const { | 474 void Clipboard::ReadFile(FilePath* file) const { |
476 if (!file) { | 475 if (!file) { |
477 NOTREACHED(); | 476 NOTREACHED(); |
478 return; | 477 return; |
479 } | 478 } |
480 | 479 |
481 file->clear(); | 480 file->clear(); |
482 std::vector<std::wstring> files; | 481 std::vector<FilePath> files; |
483 ReadFiles(&files); | 482 ReadFiles(&files); |
484 | 483 |
485 // Take the first file, if available. | 484 // Take the first file, if available. |
486 if (!files.empty()) | 485 if (!files.empty()) |
487 file->assign(files[0]); | 486 file->assign(files[0]); |
488 } | 487 } |
489 | 488 |
490 // Read a set of files in HDROP format from the clipboard. | 489 // Read a set of files in HDROP format from the clipboard. |
491 void Clipboard::ReadFiles(std::vector<std::wstring>* files) const { | 490 void Clipboard::ReadFiles(std::vector<FilePath>* files) const { |
492 if (!files) { | 491 if (!files) { |
493 NOTREACHED(); | 492 NOTREACHED(); |
494 return; | 493 return; |
495 } | 494 } |
496 | 495 |
497 files->clear(); | 496 files->clear(); |
498 | 497 |
499 ScopedClipboard clipboard; | 498 ScopedClipboard clipboard; |
500 if (!clipboard.Acquire(GetClipboardWindow())) | 499 if (!clipboard.Acquire(GetClipboardWindow())) |
501 return; | 500 return; |
502 | 501 |
503 HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP)); | 502 HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP)); |
504 if (!drop) | 503 if (!drop) |
505 return; | 504 return; |
506 | 505 |
507 // Count of files in the HDROP. | 506 // Count of files in the HDROP. |
508 int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0); | 507 int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0); |
509 | 508 |
510 if (count) { | 509 if (count) { |
511 for (int i = 0; i < count; ++i) { | 510 for (int i = 0; i < count; ++i) { |
512 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; | 511 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; |
513 std::wstring file; | 512 string16 file; |
514 ::DragQueryFile(drop, i, WriteInto(&file, size), size); | 513 ::DragQueryFile(drop, i, WriteInto(&file, size), size); |
515 files->push_back(file); | 514 files->push_back(file); |
516 } | 515 } |
517 } | 516 } |
518 } | 517 } |
519 | 518 |
520 // static | 519 // static |
521 void Clipboard::ParseBookmarkClipboardFormat(const std::wstring& bookmark, | 520 void Clipboard::ParseBookmarkClipboardFormat(const string16& bookmark, |
522 std::wstring* title, | 521 string16* title, |
523 std::string* url) { | 522 string16* url) { |
524 const wchar_t* const kDelim = L"\r\n"; | 523 const string16 kDelim = ASCIIToUTF16("\r\n"); |
525 | 524 |
526 const size_t title_end = bookmark.find_first_of(kDelim); | 525 const size_t title_end = bookmark.find_first_of(kDelim); |
527 if (title) | 526 if (title) |
528 title->assign(bookmark.substr(0, title_end)); | 527 title->assign(bookmark.substr(0, title_end)); |
529 | 528 |
530 if (url) { | 529 if (url) { |
531 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); | 530 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); |
532 if (url_start != std::wstring::npos) | 531 if (url_start != string16::npos) |
533 *url = WideToUTF8(bookmark.substr(url_start, std::wstring::npos)); | 532 *url = UTF16ToUTF8(bookmark.substr(url_start, string16::npos)); |
534 } | 533 } |
535 } | 534 } |
536 | 535 |
537 // static | 536 // static |
538 Clipboard::FormatType Clipboard::GetUrlFormatType() { | 537 Clipboard::FormatType Clipboard::GetUrlFormatType() { |
539 return ClipboardUtil::GetUrlFormat()->cfFormat; | 538 return ClipboardUtil::GetUrlFormat()->cfFormat; |
540 } | 539 } |
541 | 540 |
542 // static | 541 // static |
543 Clipboard::FormatType Clipboard::GetUrlWFormatType() { | 542 Clipboard::FormatType Clipboard::GetUrlWFormatType() { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 HWND Clipboard::GetClipboardWindow() const { | 640 HWND Clipboard::GetClipboardWindow() const { |
642 if (!clipboard_owner_ && create_window_) { | 641 if (!clipboard_owner_ && create_window_) { |
643 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", | 642 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", |
644 L"ClipboardOwnerWindow", | 643 L"ClipboardOwnerWindow", |
645 0, 0, 0, 0, 0, | 644 0, 0, 0, 0, 0, |
646 HWND_MESSAGE, | 645 HWND_MESSAGE, |
647 0, 0, 0); | 646 0, 0, 0); |
648 } | 647 } |
649 return clipboard_owner_; | 648 return clipboard_owner_; |
650 } | 649 } |
OLD | NEW |