diff options
author | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-12 16:25:23 +0000 |
---|---|---|
committer | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-12 16:25:23 +0000 |
commit | 2b05317b8aa8edb15c794f5d389e71b1a50c331d (patch) | |
tree | 1bddb2c1799823c7b68ca0a2c57eabc19eed2733 | |
parent | b6e09acf8ced26198871626c76bb5a3741cc51f1 (diff) | |
download | chromium_src-2b05317b8aa8edb15c794f5d389e71b1a50c331d.zip chromium_src-2b05317b8aa8edb15c794f5d389e71b1a50c331d.tar.gz chromium_src-2b05317b8aa8edb15c794f5d389e71b1a50c331d.tar.bz2 |
Basic implementation of the clipboard on the Mac.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@717 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/build/base.vcproj | 2 | ||||
-rw-r--r-- | base/clipboard.h | 44 | ||||
-rw-r--r-- | base/clipboard_mac.mm | 202 | ||||
-rw-r--r-- | base/clipboard_win.cc (renamed from base/clipboard.cc) | 22 |
4 files changed, 243 insertions, 27 deletions
diff --git a/base/build/base.vcproj b/base/build/base.vcproj index 7f362aa..038eadf 100644 --- a/base/build/base.vcproj +++ b/base/build/base.vcproj @@ -210,7 +210,7 @@ > </File> <File - RelativePath="..\clipboard.cc" + RelativePath="..\clipboard_win.cc" > </File> <File diff --git a/base/clipboard.h b/base/clipboard.h index 3599241..047ba4c 100644 --- a/base/clipboard.h +++ b/base/clipboard.h @@ -27,8 +27,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef BASE_CLIPBOARD_H__ -#define BASE_CLIPBOARD_H__ +#ifndef BASE_CLIPBOARD_H_ +#define BASE_CLIPBOARD_H_ #include <string> #include <vector> @@ -37,56 +37,68 @@ #include "base/gfx/size.h" #include "base/shared_memory.h" +#if defined(OS_MACOSX) +@class NSString; +#endif + class Clipboard { public: +#if defined(OS_WIN) + typedef unsigned int FormatType; +#elif defined(OS_MACOSX) + typedef NSString *FormatType; +#endif + Clipboard(); ~Clipboard(); // Clears the clipboard. It is usually a good idea to clear the clipboard // before writing content to the clipboard. - void Clear() const; + void Clear(); // Adds UNICODE and ASCII text to the clipboard. - void WriteText(const std::wstring& text) const; + void WriteText(const std::wstring& text); // Adds HTML to the clipboard. The url parameter is optional, but especially // useful if the HTML fragment contains relative links - void WriteHTML(const std::wstring& markup, const std::string& src_url) const; + void WriteHTML(const std::wstring& markup, const std::string& src_url); // Adds a bookmark to the clipboard - void WriteBookmark(const std::wstring& title, const std::string& url) const; + void WriteBookmark(const std::wstring& title, const std::string& url); // Adds both a bookmark and an HTML hyperlink to the clipboard. It is a // convenience wrapper around WriteBookmark and WriteHTML. - void WriteHyperlink(const std::wstring& title, const std::string& url) const; + void WriteHyperlink(const std::wstring& title, const std::string& url); +#if defined(OS_WIN) // Adds a bitmap to the clipboard // This is the slowest way to copy a bitmap to the clipboard as we must first // memcpy the pixels into GDI and the blit the bitmap to the clipboard. // Pixel format is assumed to be 32-bit BI_RGB. - void WriteBitmap(const void* pixels, const gfx::Size& size) const; + void WriteBitmap(const void* pixels, const gfx::Size& size); // Adds a bitmap to the clipboard // This function requires read and write access to the bitmap, but does not // actually modify the shared memory region. // Pixel format is assumed to be 32-bit BI_RGB. void WriteBitmapFromSharedMemory(const SharedMemory& bitmap, - const gfx::Size& size) const; + const gfx::Size& size); // Adds a bitmap to the clipboard // This is the fastest way to copy a bitmap to the clipboard. The HBITMAP // may either be device-dependent or device-independent. - void WriteBitmapFromHandle(HBITMAP hbitmap, const gfx::Size& size) const; + void WriteBitmapFromHandle(HBITMAP hbitmap, const gfx::Size& size); // Used by WebKit to determine whether WebKit wrote the clipboard last - void WriteWebSmartPaste() const; + void WriteWebSmartPaste(); +#endif // Adds a file or group of files to the clipboard. - void WriteFile(const std::wstring& file) const; - void WriteFiles(const std::vector<std::wstring>& files) const; + void WriteFile(const std::wstring& file); + void WriteFiles(const std::vector<std::wstring>& files); // Tests whether the clipboard contains a certain format - bool IsFormatAvailable(unsigned int format) const; + bool IsFormatAvailable(FormatType format) const; // Reads UNICODE text from the clipboard, if available. void ReadText(std::wstring* result) const; @@ -106,6 +118,7 @@ class Clipboard { void ReadFiles(std::vector<std::wstring>* files) const; private: +#if defined(OS_WIN) static void MarkupToHTMLClipboardFormat(const std::wstring& markup, const std::string& src_url, std::string* html_fragment); @@ -119,8 +132,9 @@ class Clipboard { std::string* url); HWND clipboard_owner_; +#endif DISALLOW_EVIL_CONSTRUCTORS(Clipboard); }; -#endif // BASE_CLIPBOARD_H__ +#endif // BASE_CLIPBOARD_H_ diff --git a/base/clipboard_mac.mm b/base/clipboard_mac.mm new file mode 100644 index 0000000..380082e --- /dev/null +++ b/base/clipboard_mac.mm @@ -0,0 +1,202 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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. + +#include "base/clipboard.h" + +#import <Cocoa/Cocoa.h> + +#include "base/logging.h" +#include "base/string_util.h" + +namespace { + +// Would be nice if this were in UTCoreTypes.h, but it isn't +const NSString* kUTTypeURLName = @"public.url-name"; + +NSString* nsStringForWString(const std::wstring& string) { + std::string16 text16 = WideToUTF16(string); + return [NSString stringWithCharacters:text16.c_str() length:text16.length()]; +} + +} + +Clipboard::Clipboard() { +} + +Clipboard::~Clipboard() { +} + +void Clipboard::Clear() { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray array] owner:nil]; +} + +void Clipboard::WriteText(const std::wstring& text) { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; + [pb setString:nsStringForWString(text) forType:NSStringPboardType]; + +} + +void Clipboard::WriteHTML(const std::wstring& markup, + const std::string& src_url) { + // TODO(avi): src_url? + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; + [pb setString:nsStringForWString(markup) forType:NSHTMLPboardType]; +} + +void Clipboard::WriteBookmark(const std::wstring& title, + const std::string& url) { + WriteHyperlink(title, url); +} + +void Clipboard::WriteHyperlink(const std::wstring& title, + const std::string& url) { + NSURL* nsurl = [NSURL URLWithString: + [NSString stringWithUTF8String:url.c_str()]]; + NSString* nstitle = nsStringForWString(title); + + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + // passing UTIs into the pasteboard methods is valid >= 10.5 + [pb declareTypes:[NSArray arrayWithObjects:NSURLPboardType, + kUTTypeURLName, nil] + owner:nil]; + [nsurl writeToPasteboard:pb]; + [pb setString:nstitle forType:kUTTypeURLName]; +} + +void Clipboard::WriteFile(const std::wstring& file) { + std::vector<std::wstring> files; + files.push_back(file); + WriteFiles(files); +} + +void Clipboard::WriteFiles(const std::vector<std::wstring>& files) { + NSMutableArray* fileList = [NSMutableArray arrayWithCapacity:files.size()]; + for (unsigned int i = 0; i < files.size(); ++i) { + [fileList addObject:nsStringForWString(files[i])]; + } + + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; + [pb setPropertyList:fileList forType:NSFilenamesPboardType]; +} + +bool Clipboard::IsFormatAvailable(NSString* format) const { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSArray* types = [pb types]; + + return [types containsObject:format]; +} + +void Clipboard::ReadText(std::wstring* result) const { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* contents = [pb stringForType:NSStringPboardType]; + + UTF8ToWide([contents UTF8String], + [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], + result); +} + +void Clipboard::ReadAsciiText(std::string* result) const { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* contents = [pb stringForType:NSStringPboardType]; + + *result = std::string([contents UTF8String]); +} + +void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const { + if (markup) { + markup->clear(); + + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* contents = [pb stringForType:NSStringPboardType]; + + UTF8ToWide([contents UTF8String], + [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], + markup); + } + +// TODO(avi): src_url? + if (src_url) + src_url->clear(); +} + +void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + + if (title) { + title->clear(); + + NSString* contents = [pb stringForType:kUTTypeURLName]; + UTF8ToWide([contents UTF8String], + [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], + title); + } + + if (url) { + url->clear(); + + NSURL* nsurl = [NSURL URLFromPasteboard:pb]; + *url = std::string([[nsurl absoluteString] UTF8String]); + } +} + +void Clipboard::ReadFile(std::wstring* file) const { + if (!file) { + NOTREACHED(); + return; + } + + file->clear(); + std::vector<std::wstring> files; + ReadFiles(&files); + + // Take the first file, if available. + if (!files.empty()) + file->assign(files[0]); +} + +void Clipboard::ReadFiles(std::vector<std::wstring>* files) const { + if (!files) { + NOTREACHED(); + return; + } + + files->clear(); + + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSArray* fileList = [pb propertyListForType:NSFilenamesPboardType]; + + for (unsigned int i = 0; i < [fileList count]; ++i) { + std::wstring file = UTF8ToWide([[fileList objectAtIndex:i] UTF8String]); + files->push_back(file); + } +} diff --git a/base/clipboard.cc b/base/clipboard_win.cc index b85ec00..b5b5bf2 100644 --- a/base/clipboard.cc +++ b/base/clipboard_win.cc @@ -174,7 +174,7 @@ Clipboard::~Clipboard() { clipboard_owner_ = NULL; } -void Clipboard::Clear() const { +void Clipboard::Clear() { // Acquire the clipboard. ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) @@ -183,7 +183,7 @@ void Clipboard::Clear() const { ::EmptyClipboard(); } -void Clipboard::WriteText(const std::wstring& text) const { +void Clipboard::WriteText(const std::wstring& text) { ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) return; @@ -194,7 +194,7 @@ void Clipboard::WriteText(const std::wstring& text) const { } void Clipboard::WriteHTML(const std::wstring& markup, - const std::string& url) const { + const std::string& url) { // Acquire the clipboard. ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) @@ -210,7 +210,7 @@ void Clipboard::WriteHTML(const std::wstring& markup, } void Clipboard::WriteBookmark(const std::wstring& title, - const std::string& url) const { + const std::string& url) { // Acquire the clipboard. ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) @@ -227,7 +227,7 @@ void Clipboard::WriteBookmark(const std::wstring& title, } void Clipboard::WriteHyperlink(const std::wstring& title, - const std::string& url) const { + const std::string& url) { // Write as a bookmark. WriteBookmark(title, url); @@ -242,7 +242,7 @@ void Clipboard::WriteHyperlink(const std::wstring& title, WriteHTML(link, std::string()); } -void Clipboard::WriteWebSmartPaste() const { +void Clipboard::WriteWebSmartPaste() { // Acquire the clipboard. ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) @@ -251,7 +251,7 @@ void Clipboard::WriteWebSmartPaste() const { SetClipboardData(ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat, NULL); } -void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) const { +void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) { HDC dc = ::GetDC(NULL); // This doesn't actually cost us a memcpy when the bitmap comes from the @@ -287,7 +287,7 @@ void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) const { } void Clipboard::WriteBitmapFromSharedMemory(const SharedMemory& bitmap, - const gfx::Size& size) const { + const gfx::Size& size) { // TODO(darin): share data in gfx/bitmap_header.cc somehow BITMAPINFO bm_info = {0}; bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -314,7 +314,7 @@ void Clipboard::WriteBitmapFromSharedMemory(const SharedMemory& bitmap, } void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, - const gfx::Size& size) const { + const gfx::Size& size) { // Acquire the clipboard. ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) @@ -363,13 +363,13 @@ void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, // Write a file or set of files to the clipboard in HDROP format. When the user // invokes a paste command (in a Windows explorer shell, for example), the files // will be copied to the paste location. -void Clipboard::WriteFile(const std::wstring& file) const { +void Clipboard::WriteFile(const std::wstring& file) { std::vector<std::wstring> files; files.push_back(file); WriteFiles(files); } -void Clipboard::WriteFiles(const std::vector<std::wstring>& files) const { +void Clipboard::WriteFiles(const std::vector<std::wstring>& files) { ClipboardLock lock; if (!lock.Acquire(clipboard_owner_)) return; |