| Index: ui/base/clipboard/clipboard_util_win.cc
|
| diff --git a/ui/base/clipboard/clipboard_util_win.cc b/ui/base/clipboard/clipboard_util_win.cc
|
| deleted file mode 100644
|
| index 687f0ff0020ee6e86497af7ace3bc4b4e76e1c74..0000000000000000000000000000000000000000
|
| --- a/ui/base/clipboard/clipboard_util_win.cc
|
| +++ /dev/null
|
| @@ -1,502 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "ui/base/clipboard/clipboard_util_win.h"
|
| -
|
| -#include <shellapi.h>
|
| -#include <shlwapi.h>
|
| -#include <wininet.h> // For INTERNET_MAX_URL_LENGTH.
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/logging.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/win/scoped_hglobal.h"
|
| -#include "net/base/filename_util.h"
|
| -#include "ui/base/clipboard/clipboard.h"
|
| -#include "ui/base/clipboard/custom_data_helper.h"
|
| -#include "url/gurl.h"
|
| -
|
| -namespace ui {
|
| -
|
| -namespace {
|
| -
|
| -bool HasData(IDataObject* data_object, const Clipboard::FormatType& format) {
|
| - FORMATETC format_etc = format.ToFormatEtc();
|
| - return SUCCEEDED(data_object->QueryGetData(&format_etc));
|
| -}
|
| -
|
| -bool GetData(IDataObject* data_object,
|
| - const Clipboard::FormatType& format,
|
| - STGMEDIUM* medium) {
|
| - FORMATETC format_etc = format.ToFormatEtc();
|
| - return SUCCEEDED(data_object->GetData(&format_etc, medium));
|
| -}
|
| -
|
| -bool GetUrlFromHDrop(IDataObject* data_object,
|
| - GURL* url,
|
| - base::string16* title) {
|
| - DCHECK(data_object && url && title);
|
| -
|
| - bool success = false;
|
| - STGMEDIUM medium;
|
| - if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium))
|
| - return false;
|
| -
|
| - {
|
| - base::win::ScopedHGlobal<HDROP> hdrop(medium.hGlobal);
|
| -
|
| - if (!hdrop.get())
|
| - return false;
|
| -
|
| - wchar_t filename[MAX_PATH];
|
| - if (DragQueryFileW(hdrop.get(), 0, filename, arraysize(filename))) {
|
| - wchar_t url_buffer[INTERNET_MAX_URL_LENGTH];
|
| - if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") &&
|
| - GetPrivateProfileStringW(L"InternetShortcut",
|
| - L"url",
|
| - 0,
|
| - url_buffer,
|
| - arraysize(url_buffer),
|
| - filename)) {
|
| - *url = GURL(url_buffer);
|
| - PathRemoveExtension(filename);
|
| - title->assign(PathFindFileName(filename));
|
| - success = url->is_valid();
|
| - }
|
| - }
|
| - }
|
| -
|
| - ReleaseStgMedium(&medium);
|
| - return success;
|
| -}
|
| -
|
| -void SplitUrlAndTitle(const base::string16& str,
|
| - GURL* url,
|
| - base::string16* title) {
|
| - DCHECK(url && title);
|
| - size_t newline_pos = str.find('\n');
|
| - if (newline_pos != base::string16::npos) {
|
| - *url = GURL(base::string16(str, 0, newline_pos));
|
| - title->assign(str, newline_pos + 1, base::string16::npos);
|
| - } else {
|
| - *url = GURL(str);
|
| - title->assign(str);
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -bool ClipboardUtil::HasUrl(IDataObject* data_object, bool convert_filenames) {
|
| - DCHECK(data_object);
|
| - return HasData(data_object, Clipboard::GetMozUrlFormatType()) ||
|
| - HasData(data_object, Clipboard::GetUrlWFormatType()) ||
|
| - HasData(data_object, Clipboard::GetUrlFormatType()) ||
|
| - (convert_filenames && HasFilenames(data_object));
|
| -}
|
| -
|
| -bool ClipboardUtil::HasFilenames(IDataObject* data_object) {
|
| - DCHECK(data_object);
|
| - return HasData(data_object, Clipboard::GetCFHDropFormatType()) ||
|
| - HasData(data_object, Clipboard::GetFilenameWFormatType()) ||
|
| - HasData(data_object, Clipboard::GetFilenameFormatType());
|
| -}
|
| -
|
| -bool ClipboardUtil::HasFileContents(IDataObject* data_object) {
|
| - DCHECK(data_object);
|
| - return HasData(data_object, Clipboard::GetFileContentZeroFormatType());
|
| -}
|
| -
|
| -bool ClipboardUtil::HasHtml(IDataObject* data_object) {
|
| - DCHECK(data_object);
|
| - return HasData(data_object, Clipboard::GetHtmlFormatType()) ||
|
| - HasData(data_object, Clipboard::GetTextHtmlFormatType());
|
| -}
|
| -
|
| -bool ClipboardUtil::HasPlainText(IDataObject* data_object) {
|
| - DCHECK(data_object);
|
| - return HasData(data_object, Clipboard::GetPlainTextWFormatType()) ||
|
| - HasData(data_object, Clipboard::GetPlainTextFormatType());
|
| -}
|
| -
|
| -bool ClipboardUtil::GetUrl(IDataObject* data_object,
|
| - GURL* url,
|
| - base::string16* title,
|
| - bool convert_filenames) {
|
| - DCHECK(data_object && url && title);
|
| - if (!HasUrl(data_object, convert_filenames))
|
| - return false;
|
| -
|
| - // Try to extract a URL from |data_object| in a variety of formats.
|
| - STGMEDIUM store;
|
| - if (GetUrlFromHDrop(data_object, url, title))
|
| - return true;
|
| -
|
| - if (GetData(data_object, Clipboard::GetMozUrlFormatType(), &store) ||
|
| - GetData(data_object, Clipboard::GetUrlWFormatType(), &store)) {
|
| - {
|
| - // Mozilla URL format or unicode URL
|
| - base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal);
|
| - SplitUrlAndTitle(data.get(), url, title);
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return url->is_valid();
|
| - }
|
| -
|
| - if (GetData(data_object, Clipboard::GetUrlFormatType(), &store)) {
|
| - {
|
| - // URL using ascii
|
| - base::win::ScopedHGlobal<char*> data(store.hGlobal);
|
| - SplitUrlAndTitle(base::UTF8ToWide(data.get()), url, title);
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return url->is_valid();
|
| - }
|
| -
|
| - if (convert_filenames) {
|
| - std::vector<base::string16> filenames;
|
| - if (!GetFilenames(data_object, &filenames))
|
| - return false;
|
| - DCHECK_GT(filenames.size(), 0U);
|
| - *url = net::FilePathToFileURL(base::FilePath(filenames[0]));
|
| - return url->is_valid();
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -bool ClipboardUtil::GetFilenames(IDataObject* data_object,
|
| - std::vector<base::string16>* filenames) {
|
| - DCHECK(data_object && filenames);
|
| - if (!HasFilenames(data_object))
|
| - return false;
|
| -
|
| - STGMEDIUM medium;
|
| - if (GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) {
|
| - {
|
| - base::win::ScopedHGlobal<HDROP> hdrop(medium.hGlobal);
|
| - if (!hdrop.get())
|
| - return false;
|
| -
|
| - const int kMaxFilenameLen = 4096;
|
| - const unsigned num_files = DragQueryFileW(hdrop.get(), 0xffffffff, 0, 0);
|
| - for (unsigned int i = 0; i < num_files; ++i) {
|
| - wchar_t filename[kMaxFilenameLen];
|
| - if (!DragQueryFileW(hdrop.get(), i, filename, kMaxFilenameLen))
|
| - continue;
|
| - filenames->push_back(filename);
|
| - }
|
| - }
|
| - ReleaseStgMedium(&medium);
|
| - return true;
|
| - }
|
| -
|
| - if (GetData(data_object, Clipboard::GetFilenameWFormatType(), &medium)) {
|
| - {
|
| - // filename using unicode
|
| - base::win::ScopedHGlobal<wchar_t*> data(medium.hGlobal);
|
| - if (data.get() && data.get()[0])
|
| - filenames->push_back(data.get());
|
| - }
|
| - ReleaseStgMedium(&medium);
|
| - return true;
|
| - }
|
| -
|
| - if (GetData(data_object, Clipboard::GetFilenameFormatType(), &medium)) {
|
| - {
|
| - // filename using ascii
|
| - base::win::ScopedHGlobal<char*> data(medium.hGlobal);
|
| - if (data.get() && data.get()[0])
|
| - filenames->push_back(base::SysNativeMBToWide(data.get()));
|
| - }
|
| - ReleaseStgMedium(&medium);
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -bool ClipboardUtil::GetPlainText(IDataObject* data_object,
|
| - base::string16* plain_text) {
|
| - DCHECK(data_object && plain_text);
|
| - if (!HasPlainText(data_object))
|
| - return false;
|
| -
|
| - STGMEDIUM store;
|
| - if (GetData(data_object, Clipboard::GetPlainTextWFormatType(), &store)) {
|
| - {
|
| - // Unicode text
|
| - base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal);
|
| - plain_text->assign(data.get());
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return true;
|
| - }
|
| -
|
| - if (GetData(data_object, Clipboard::GetPlainTextFormatType(), &store)) {
|
| - {
|
| - // ascii text
|
| - base::win::ScopedHGlobal<char*> data(store.hGlobal);
|
| - plain_text->assign(base::UTF8ToWide(data.get()));
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return true;
|
| - }
|
| -
|
| - // If a file is dropped on the window, it does not provide either of the
|
| - // plain text formats, so here we try to forcibly get a url.
|
| - GURL url;
|
| - base::string16 title;
|
| - if (GetUrl(data_object, &url, &title, false)) {
|
| - *plain_text = base::UTF8ToUTF16(url.spec());
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool ClipboardUtil::GetHtml(IDataObject* data_object,
|
| - base::string16* html, std::string* base_url) {
|
| - DCHECK(data_object && html && base_url);
|
| -
|
| - STGMEDIUM store;
|
| - if (HasData(data_object, Clipboard::GetHtmlFormatType()) &&
|
| - GetData(data_object, Clipboard::GetHtmlFormatType(), &store)) {
|
| - {
|
| - // MS CF html
|
| - base::win::ScopedHGlobal<char*> data(store.hGlobal);
|
| -
|
| - std::string html_utf8;
|
| - CFHtmlToHtml(std::string(data.get(), data.Size()), &html_utf8, base_url);
|
| - html->assign(base::UTF8ToWide(html_utf8));
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return true;
|
| - }
|
| -
|
| - if (!HasData(data_object, Clipboard::GetTextHtmlFormatType()))
|
| - return false;
|
| -
|
| - if (!GetData(data_object, Clipboard::GetTextHtmlFormatType(), &store))
|
| - return false;
|
| -
|
| - {
|
| - // text/html
|
| - base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal);
|
| - html->assign(data.get());
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return true;
|
| -}
|
| -
|
| -bool ClipboardUtil::GetFileContents(IDataObject* data_object,
|
| - base::string16* filename, std::string* file_contents) {
|
| - DCHECK(data_object && filename && file_contents);
|
| - if (!HasData(data_object, Clipboard::GetFileContentZeroFormatType()) &&
|
| - !HasData(data_object, Clipboard::GetFileDescriptorFormatType()))
|
| - return false;
|
| -
|
| - STGMEDIUM content;
|
| - // The call to GetData can be very slow depending on what is in
|
| - // |data_object|.
|
| - if (GetData(
|
| - data_object, Clipboard::GetFileContentZeroFormatType(), &content)) {
|
| - if (TYMED_HGLOBAL == content.tymed) {
|
| - base::win::ScopedHGlobal<char*> data(content.hGlobal);
|
| - file_contents->assign(data.get(), data.Size());
|
| - }
|
| - ReleaseStgMedium(&content);
|
| - }
|
| -
|
| - STGMEDIUM description;
|
| - if (GetData(data_object,
|
| - Clipboard::GetFileDescriptorFormatType(),
|
| - &description)) {
|
| - {
|
| - base::win::ScopedHGlobal<FILEGROUPDESCRIPTOR*> fgd(description.hGlobal);
|
| - // We expect there to be at least one file in here.
|
| - DCHECK_GE(fgd->cItems, 1u);
|
| - filename->assign(fgd->fgd[0].cFileName);
|
| - }
|
| - ReleaseStgMedium(&description);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool ClipboardUtil::GetWebCustomData(
|
| - IDataObject* data_object,
|
| - std::map<base::string16, base::string16>* custom_data) {
|
| - DCHECK(data_object && custom_data);
|
| -
|
| - if (!HasData(data_object, Clipboard::GetWebCustomDataFormatType()))
|
| - return false;
|
| -
|
| - STGMEDIUM store;
|
| - if (GetData(data_object, Clipboard::GetWebCustomDataFormatType(), &store)) {
|
| - {
|
| - base::win::ScopedHGlobal<char*> data(store.hGlobal);
|
| - ReadCustomDataIntoMap(data.get(), data.Size(), custom_data);
|
| - }
|
| - ReleaseStgMedium(&store);
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -
|
| -// HtmlToCFHtml and CFHtmlToHtml are based on similar methods in
|
| -// WebCore/platform/win/ClipboardUtilitiesWin.cpp.
|
| -/*
|
| - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions
|
| - * are met:
|
| - * 1. Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * 2. Redistributions in binary form must reproduce the above copyright
|
| - * notice, this list of conditions and the following disclaimer in the
|
| - * documentation and/or other materials provided with the distribution.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
| - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
| - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
| - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
| - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
| - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
| - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -// Helper method for converting from text/html to MS CF_HTML.
|
| -// Documentation for the CF_HTML format is available at
|
| -// http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx
|
| -std::string ClipboardUtil::HtmlToCFHtml(const std::string& html,
|
| - const std::string& base_url) {
|
| - if (html.empty())
|
| - return std::string();
|
| -
|
| - #define MAX_DIGITS 10
|
| - #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits)
|
| - #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u"
|
| - #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS)
|
| -
|
| - static const char* header = "Version:0.9\r\n"
|
| - "StartHTML:" NUMBER_FORMAT "\r\n"
|
| - "EndHTML:" NUMBER_FORMAT "\r\n"
|
| - "StartFragment:" NUMBER_FORMAT "\r\n"
|
| - "EndFragment:" NUMBER_FORMAT "\r\n";
|
| - static const char* source_url_prefix = "SourceURL:";
|
| -
|
| - static const char* start_markup =
|
| - "<html>\r\n<body>\r\n<!--StartFragment-->";
|
| - static const char* end_markup =
|
| - "<!--EndFragment-->\r\n</body>\r\n</html>";
|
| -
|
| - // Calculate offsets
|
| - size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 +
|
| - MAX_DIGITS * 4;
|
| - if (!base_url.empty()) {
|
| - start_html_offset += strlen(source_url_prefix) +
|
| - base_url.length() + 2; // Add 2 for \r\n.
|
| - }
|
| - size_t start_fragment_offset = start_html_offset + strlen(start_markup);
|
| - size_t end_fragment_offset = start_fragment_offset + html.length();
|
| - size_t end_html_offset = end_fragment_offset + strlen(end_markup);
|
| -
|
| - std::string result = base::StringPrintf(header,
|
| - start_html_offset,
|
| - end_html_offset,
|
| - start_fragment_offset,
|
| - end_fragment_offset);
|
| - if (!base_url.empty()) {
|
| - result.append(source_url_prefix);
|
| - result.append(base_url);
|
| - result.append("\r\n");
|
| - }
|
| - result.append(start_markup);
|
| - result.append(html);
|
| - result.append(end_markup);
|
| -
|
| - #undef MAX_DIGITS
|
| - #undef MAKE_NUMBER_FORMAT_1
|
| - #undef MAKE_NUMBER_FORMAT_2
|
| - #undef NUMBER_FORMAT
|
| -
|
| - return result;
|
| -}
|
| -
|
| -// Helper method for converting from MS CF_HTML to text/html.
|
| -void ClipboardUtil::CFHtmlToHtml(const std::string& cf_html,
|
| - std::string* html,
|
| - std::string* base_url) {
|
| - size_t fragment_start = std::string::npos;
|
| - size_t fragment_end = std::string::npos;
|
| -
|
| - ClipboardUtil::CFHtmlExtractMetadata(
|
| - cf_html, base_url, NULL, &fragment_start, &fragment_end);
|
| -
|
| - if (html &&
|
| - fragment_start != std::string::npos &&
|
| - fragment_end != std::string::npos) {
|
| - *html = cf_html.substr(fragment_start, fragment_end - fragment_start);
|
| - base::TrimWhitespace(*html, base::TRIM_ALL, html);
|
| - }
|
| -}
|
| -
|
| -void ClipboardUtil::CFHtmlExtractMetadata(const std::string& cf_html,
|
| - std::string* base_url,
|
| - size_t* html_start,
|
| - size_t* fragment_start,
|
| - size_t* fragment_end) {
|
| - // Obtain base_url if present.
|
| - if (base_url) {
|
| - static std::string src_url_str("SourceURL:");
|
| - size_t line_start = cf_html.find(src_url_str);
|
| - if (line_start != std::string::npos) {
|
| - size_t src_end = cf_html.find("\n", line_start);
|
| - size_t src_start = line_start + src_url_str.length();
|
| - if (src_end != std::string::npos && src_start != std::string::npos) {
|
| - *base_url = cf_html.substr(src_start, src_end - src_start);
|
| - base::TrimWhitespace(*base_url, base::TRIM_ALL, base_url);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Find the markup between "<!--StartFragment-->" and "<!--EndFragment-->".
|
| - // If the comments cannot be found, like copying from OpenOffice Writer,
|
| - // we simply fall back to using StartFragment/EndFragment bytecount values
|
| - // to determine the fragment indexes.
|
| - std::string cf_html_lower = base::StringToLowerASCII(cf_html);
|
| - size_t markup_start = cf_html_lower.find("<html", 0);
|
| - if (html_start) {
|
| - *html_start = markup_start;
|
| - }
|
| - size_t tag_start = cf_html.find("<!--StartFragment", markup_start);
|
| - if (tag_start == std::string::npos) {
|
| - static std::string start_fragment_str("StartFragment:");
|
| - size_t start_fragment_start = cf_html.find(start_fragment_str);
|
| - if (start_fragment_start != std::string::npos) {
|
| - *fragment_start = static_cast<size_t>(atoi(cf_html.c_str() +
|
| - start_fragment_start + start_fragment_str.length()));
|
| - }
|
| -
|
| - static std::string end_fragment_str("EndFragment:");
|
| - size_t end_fragment_start = cf_html.find(end_fragment_str);
|
| - if (end_fragment_start != std::string::npos) {
|
| - *fragment_end = static_cast<size_t>(atoi(cf_html.c_str() +
|
| - end_fragment_start + end_fragment_str.length()));
|
| - }
|
| - } else {
|
| - *fragment_start = cf_html.find('>', tag_start) + 1;
|
| - size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos);
|
| - *fragment_end = cf_html.rfind('<', tag_end);
|
| - }
|
| -}
|
| -
|
| -} // namespace ui
|
|
|