diff options
author | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-06 00:39:25 +0000 |
---|---|---|
committer | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-06 00:39:25 +0000 |
commit | 0fe52a020563061cc9b354f5a3892080b8500d8f (patch) | |
tree | 7f12e729cec31b944d83bbf68176f2f533f2c941 /chrome/browser/bookmarks | |
parent | c755d94a4040d5bbad69b72ad78a1251334851e6 (diff) | |
download | chromium_src-0fe52a020563061cc9b354f5a3892080b8500d8f.zip chromium_src-0fe52a020563061cc9b354f5a3892080b8500d8f.tar.gz chromium_src-0fe52a020563061cc9b354f5a3892080b8500d8f.tar.bz2 |
Implement copy/paste of bookmarks for mac
Implements Copy, paste, and can paste as extension apis for use in the extension bookmark manager.
BUG=33461
TEST=Copy and paste single and multiple bookmarks in the extension bookmark manager, and between it safari's bookmark manager and plain text fields.
Review URL: http://codereview.chromium.org/562010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38286 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/bookmarks')
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.cc | 20 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_drag_data.h | 6 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h | 20 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm | 222 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_utils.cc | 15 |
5 files changed, 265 insertions, 18 deletions
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.cc b/chrome/browser/bookmarks/bookmark_drag_data.cc index e1897b2..1b4b7de 100644 --- a/chrome/browser/bookmarks/bookmark_drag_data.cc +++ b/chrome/browser/bookmarks/bookmark_drag_data.cc @@ -9,6 +9,9 @@ #include "base/pickle.h" #include "base/string_util.h" #include "chrome/browser/bookmarks/bookmark_model.h" +#if defined(OS_MACOSX) +#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" +#endif #include "chrome/browser/profile.h" #include "chrome/common/url_constants.h" #include "chrome/browser/browser_process.h" @@ -140,6 +143,23 @@ bool BookmarkDragData::ReadFromClipboard() { return false; } + +bool BookmarkDragData::ClipboardContainsBookmarks() { + return g_browser_process->clipboard()->IsFormatAvailableByString( + BookmarkDragData::kClipboardFormatString, Clipboard::BUFFER_STANDARD); +} +#else +void BookmarkDragData::WriteToClipboard(Profile* profile) const { + bookmark_pasteboard_helper_mac::WriteToClipboard(elements); +} + +bool BookmarkDragData::ReadFromClipboard() { + return bookmark_pasteboard_helper_mac::ReadFromClipboard(elements); +} + +bool BookmarkDragData::ClipboardContainsBookmarks() { + return bookmark_pasteboard_helper_mac::ClipboardContainsBookmarks(); +} #endif // !defined(OS_MACOSX) #if defined(TOOLKIT_VIEWS) diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h index 32bf60d..c880922 100644 --- a/chrome/browser/bookmarks/bookmark_drag_data.h +++ b/chrome/browser/bookmarks/bookmark_drag_data.h @@ -83,16 +83,12 @@ struct BookmarkDragData { explicit BookmarkDragData(const BookmarkNode* node); explicit BookmarkDragData(const std::vector<const BookmarkNode*>& nodes); - // TODO(estade): Port to mac. It should be as simple as removing this ifdef - // after the relevant Clipboard functions are implemetned. -#if !defined(OS_MACOSX) // Writes elements to the clipboard. void WriteToClipboard(Profile* profile) const; // Reads bookmarks from the clipboard. Prefers data written via // WriteToClipboard but will also attempt to read a plain bookmark. bool ReadFromClipboard(); -#endif #if defined(TOOLKIT_VIEWS) // Writes elements to data. If there is only one element and it is a URL @@ -140,6 +136,8 @@ struct BookmarkDragData { // The MIME type for the clipboard format for BookmarkDragData. static const char* kClipboardFormatString; + static bool ClipboardContainsBookmarks(); + private: // Path of the profile we originated from. FilePath::StringType profile_path_; diff --git a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h new file mode 100644 index 0000000..357671e --- /dev/null +++ b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h @@ -0,0 +1,20 @@ +// Copyright (c) 2010 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. + +#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_ +#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_ + +#import "chrome/browser/bookmarks/bookmark_drag_data.h" + +namespace bookmark_pasteboard_helper_mac { + +void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements); + +bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements); + +bool ClipboardContainsBookmarks(); + +} + +#endif // CHROME_BROWSER_BOOKMARKS_BOOKMARK_PASTEBOARD_HELPER_MAC_H_ diff --git a/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm new file mode 100644 index 0000000..28dbac1 --- /dev/null +++ b/chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.mm @@ -0,0 +1,222 @@ +// Copyright (c) 2010 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. + +#import <Cocoa/Cocoa.h> + +#include "base/sys_string_conversions.h" +#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h" + +namespace bookmark_pasteboard_helper_mac { + +// Mac WebKit uses this type, declared in +// WebKit/mac/History/WebURLsWithTitles.h +static NSString* const WebURLsWithTitlesPboardType = + @"WebURLsWithTitlesPboardType"; + +static NSString* const BookmarkDictionaryListPboardType = + @"BookmarkDictionaryListPboardType"; + +// Keys for the type of node in BookmarkDictionaryListPboardType +static NSString* const WebBookmarkType = + @"WebBookmarkType"; + +static NSString* const WebBookmarkTypeList = + @"WebBookmarkTypeList"; + +static NSString* const WebBookmarkTypeLeaf = + @"WebBookmarkTypeLeaf"; + +static void ConvertPlistToElements(NSArray* input, + std::vector<BookmarkDragData::Element>& elements) { + NSUInteger len = [input count]; + for (NSUInteger i = 0; i < len; ++i) { + NSDictionary* object = [input objectAtIndex:i]; + BookmarkDragData::Element element; + BOOL is_folder = [[object objectForKey:WebBookmarkType] + isEqualToString:WebBookmarkTypeList]; + if(is_folder) { + NSString* title = [object objectForKey:@"Title"]; + element.title = base::SysNSStringToUTF16(title); + ConvertPlistToElements([object objectForKey:@"Children"], + element.children); + } else { + NSDictionary* uriDictionary = [object objectForKey:@"URIDictionary"]; + NSString* title = [uriDictionary objectForKey:@"title"]; + NSString* urlString = [object objectForKey:@"URLString"]; + element.title = base::SysNSStringToUTF16(title); + element.url = GURL(base::SysNSStringToUTF8(urlString)); + element.is_url = true; + } + elements.push_back(element); + } +} + +static bool ReadBookmarkDictionaryListPboardType(NSPasteboard* pb, + std::vector<BookmarkDragData::Element>& elements) { + NSArray* bookmarks = [pb propertyListForType: + BookmarkDictionaryListPboardType]; + if (!bookmarks) return false; + ConvertPlistToElements(bookmarks, elements); + return true; +} + +static bool ReadWebURLsWithTitlesPboardType(NSPasteboard* pb, + std::vector<BookmarkDragData::Element>& elements) { + NSArray* bookmarkPairs = + [pb propertyListForType:WebURLsWithTitlesPboardType]; + if (![bookmarkPairs isKindOfClass:[NSArray class]]) { + return false; + } + NSArray* urlsArr = [bookmarkPairs objectAtIndex:0]; + NSArray* titlesArr = [bookmarkPairs objectAtIndex:1]; + if ([urlsArr count] < 1) { + return false; + } + if ([urlsArr count] != [titlesArr count]) { + return false; + } + + int len = [titlesArr count]; + for (int i = 0; i < len; ++i) { + string16 title = base::SysNSStringToUTF16([titlesArr objectAtIndex:i]); + std::string url = base::SysNSStringToUTF8([urlsArr objectAtIndex:i]); + if (!url.empty()) { + BookmarkDragData::Element element; + element.is_url = true; + element.url = GURL(url); + element.title = title; + elements.push_back(element); + } + } + return true; +} + +static bool ReadNSURLPboardType(NSPasteboard* pb, + std::vector<BookmarkDragData::Element>& elements) { + NSURL* url = [NSURL URLFromPasteboard:pb]; + if (url == nil) { + return false; + } + std::string urlString = base::SysNSStringToUTF8([url absoluteString]); + NSString* title = [pb stringForType:@"public.url-name"]; + if (!title) + title = [pb stringForType:NSStringPboardType]; + + BookmarkDragData::Element element; + element.is_url = true; + element.url = GURL(urlString); + element.title = base::SysNSStringToUTF16(title); + elements.push_back(element); + return true; +} + +static NSArray* GetPlistForBookmarkList( + const std::vector<BookmarkDragData::Element>& elements) { + NSMutableArray* plist = [NSMutableArray array]; + for (size_t i = 0; i < elements.size(); ++i) { + BookmarkDragData::Element element = elements[i]; + if (element.is_url) { + NSString* title = base::SysUTF16ToNSString(element.title); + NSString* url = base::SysUTF8ToNSString(element.url.spec()); + NSDictionary* uriDictionary = [NSDictionary dictionaryWithObjectsAndKeys: + title, @"title", nil]; + NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys: + uriDictionary, @"URIDictionary", + url, @"URLString", + WebBookmarkTypeLeaf, WebBookmarkType, + nil]; + [plist addObject:object]; + } else { + NSString* title = base::SysUTF16ToNSString(element.title); + NSArray* children = GetPlistForBookmarkList(element.children); + NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys: + title, @"Title", + children, @"Children", + WebBookmarkTypeList, WebBookmarkType, + nil]; + [plist addObject:object]; + } + } + return plist; +} + +static void WriteBookmarkDictionaryListPboardType(NSPasteboard* pb, + const std::vector<BookmarkDragData::Element>& elements) { + NSArray* plist = GetPlistForBookmarkList(elements); + [pb setPropertyList:plist forType:BookmarkDictionaryListPboardType]; +} + +static void FillFlattenedArraysForBookmarks( + const std::vector<BookmarkDragData::Element>& elements, + NSMutableArray* titles, NSMutableArray* urls) { + for (size_t i = 0; i < elements.size(); ++i) { + BookmarkDragData::Element element = elements[i]; + if (element.is_url) { + NSString* title = base::SysUTF16ToNSString(element.title); + NSString* url = base::SysUTF8ToNSString(element.url.spec()); + [titles addObject:title]; + [urls addObject:url]; + } else { + FillFlattenedArraysForBookmarks(element.children, titles, urls); + } + } +} + +static void WriteSimplifiedBookmarkTypes(NSPasteboard* pb, + const std::vector<BookmarkDragData::Element>& elements) { + NSMutableArray* titles = [NSMutableArray array]; + NSMutableArray* urls = [NSMutableArray array]; + FillFlattenedArraysForBookmarks(elements, titles, urls); + + //Write WebURLsWithTitlesPboardType + [pb setPropertyList:[NSArray arrayWithObjects:urls, titles, nil] + forType:WebURLsWithTitlesPboardType]; + + //Write NSStringPboardType + [pb setString:[urls componentsJoinedByString:@"\n"] + forType:NSStringPboardType]; + + // Write NSURLPboardType + NSURL* url = [NSURL URLWithString:[urls objectAtIndex:0]]; + [url writeToPasteboard:pb]; + NSString* titleString = [titles objectAtIndex:0]; + [pb setString:titleString forType:@"public.url-name"]; +} + +void WriteToClipboard(const std::vector<BookmarkDragData::Element>& elements) { + if (elements.size() == 0) { + return; + } + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSArray* types = [NSArray arrayWithObjects:BookmarkDictionaryListPboardType, + WebURLsWithTitlesPboardType, + NSStringPboardType, + NSURLPboardType, + @"public.url-name", + nil]; + [pb declareTypes:types owner:nil]; + WriteBookmarkDictionaryListPboardType(pb, elements); + WriteSimplifiedBookmarkTypes(pb, elements); +} + +bool ReadFromClipboard(std::vector<BookmarkDragData::Element>& elements) { + elements.clear(); + + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + return (ReadBookmarkDictionaryListPboardType(pb, elements) || + ReadWebURLsWithTitlesPboardType(pb, elements) || + ReadNSURLPboardType(pb, elements)); +} + +bool ClipboardContainsBookmarks() { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSArray* availableTypes = [NSArray arrayWithObjects: + BookmarkDictionaryListPboardType, + WebURLsWithTitlesPboardType, + NSURLPboardType, + nil]; + return [pb availableTypeFromArray:availableTypes] != nil; +} + +} diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc index 816d6d8..a172312 100644 --- a/chrome/browser/bookmarks/bookmark_utils.cc +++ b/chrome/browser/bookmarks/bookmark_utils.cc @@ -355,8 +355,6 @@ void OpenAll(gfx::NativeWindow parent, void CopyToClipboard(BookmarkModel* model, const std::vector<const BookmarkNode*>& nodes, bool remove_nodes) { -// Not implemented on mac yet. -#if !defined(OS_MACOSX) if (nodes.empty()) return; @@ -368,14 +366,11 @@ void CopyToClipboard(BookmarkModel* model, nodes[i]->GetParent()->IndexOfChild(nodes[i])); } } -#endif } void PasteFromClipboard(BookmarkModel* model, const BookmarkNode* parent, int index) { -// Not implemented on mac yet. -#if !defined(OS_MACOSX) if (!parent) return; @@ -386,20 +381,12 @@ void PasteFromClipboard(BookmarkModel* model, if (index == -1) index = parent->GetChildCount(); bookmark_utils::CloneDragData(model, bookmark_data.elements, parent, index); -#endif } bool CanPasteFromClipboard(const BookmarkNode* node) { if (!node) return false; - -#if defined(OS_MACOSX) - NOTIMPLEMENTED(); - return false; -#else - return g_browser_process->clipboard()->IsFormatAvailableByString( - BookmarkDragData::kClipboardFormatString, Clipboard::BUFFER_STANDARD); -#endif + return BookmarkDragData::ClipboardContainsBookmarks(); } std::string GetNameForURL(const GURL& url) { |