summaryrefslogtreecommitdiffstats
path: root/base/clipboard_mac.mm
blob: e04849c015d0beee2e85bf518fc0d18625a5f31f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright (c) 2006-2008 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 "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()];
}

}  // namespace

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);
  }
}