| 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 |