Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / drag_util.mm
blob77014dfee7ed3f3209e65edb1438fe750c92e2bf
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/drag_util.h"
7 #include <cmath>
9 #include "base/files/file_path.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "components/mime_util/mime_util.h"
14 #include "content/public/browser/plugin_service.h"
15 #include "content/public/common/webplugininfo.h"
16 #include "ipc/ipc_message.h"
17 #include "net/base/filename_util.h"
18 #include "net/base/mime_util.h"
19 #import "third_party/mozilla/NSPasteboard+Utils.h"
20 #import "ui/base/dragdrop/cocoa_dnd_util.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
23 #include "ui/resources/grit/ui_resources.h"
24 #include "url/gurl.h"
25 #include "url/url_constants.h"
27 using content::PluginService;
29 namespace drag_util {
31 namespace {
33 BOOL IsSupportedFileURL(Profile* profile, const GURL& url) {
34   base::FilePath full_path;
35   net::FileURLToFilePath(url, &full_path);
37   std::string mime_type;
38   net::GetMimeTypeFromFile(full_path, &mime_type);
40   // This logic mirrors |BufferedResourceHandler::ShouldDownload()|.
41   // TODO(asvitkine): Refactor this out to a common location instead of
42   //                  duplicating code.
43   if (mime_util::IsSupportedMimeType(mime_type))
44     return YES;
46   // Check whether there is a plugin that supports the mime type. (e.g. PDF)
47   // TODO(bauerb): This possibly uses stale information, but it's guaranteed not
48   // to do disk access.
49   bool allow_wildcard = false;
50   content::WebPluginInfo plugin;
51   return PluginService::GetInstance()->GetPluginInfo(
52       -1,                // process ID
53       MSG_ROUTING_NONE,  // routing ID
54       profile->GetResourceContext(),
55       url, GURL(), mime_type, allow_wildcard,
56       NULL, &plugin, NULL);
59 // Draws string |title| within box |frame|, positioning it at the origin.
60 // Truncates text with fading if it is too long to fit horizontally.
61 // Based on code from GradientButtonCell but simplified where possible.
62 void DrawTruncatedTitle(NSAttributedString* title, NSRect frame) {
63   NSSize size = [title size];
64   if (std::floor(size.width) <= NSWidth(frame)) {
65     [title drawAtPoint:frame.origin];
66     return;
67   }
69   // Gradient is about twice our line height long.
70   CGFloat gradient_width = std::min(size.height * 2, NSWidth(frame) / 4);
71   NSRect solid_part, gradient_part;
72   NSDivideRect(frame, &gradient_part, &solid_part, gradient_width, NSMaxXEdge);
73   CGContextRef context = static_cast<CGContextRef>(
74       [[NSGraphicsContext currentContext] graphicsPort]);
75   CGContextBeginTransparencyLayerWithRect(context, NSRectToCGRect(frame), 0);
76   { // Draw text clipped to frame.
77     gfx::ScopedNSGraphicsContextSaveGState scoped_state;
78     [NSBezierPath clipRect:frame];
79     [title drawAtPoint:frame.origin];
80   }
82   NSColor* color = [NSColor blackColor];
83   NSColor* alpha_color = [color colorWithAlphaComponent:0.0];
84   base::scoped_nsobject<NSGradient> mask(
85       [[NSGradient alloc] initWithStartingColor:color endingColor:alpha_color]);
86   // Draw the gradient mask.
87   CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
88   [mask drawFromPoint:NSMakePoint(NSMaxX(frame) - gradient_width,
89                                   NSMinY(frame))
90               toPoint:NSMakePoint(NSMaxX(frame),
91                                   NSMinY(frame))
92               options:NSGradientDrawsBeforeStartingLocation];
93   CGContextEndTransparencyLayer(context);
96 }  // namespace
98 GURL GetFileURLFromDropData(id<NSDraggingInfo> info) {
99   if ([[info draggingPasteboard] containsURLData]) {
100     GURL url;
101     ui::PopulateURLAndTitleFromPasteboard(&url,
102                                           NULL,
103                                           [info draggingPasteboard],
104                                           YES);
106     if (url.SchemeIs(url::kFileScheme))
107       return url;
108   }
109   return GURL();
112 BOOL IsUnsupportedDropData(Profile* profile, id<NSDraggingInfo> info) {
113   GURL url = GetFileURLFromDropData(info);
114   if (!url.is_empty()) {
115     // If dragging a file, only allow dropping supported file types (that the
116     // web view can display).
117     return !IsSupportedFileURL(profile, url);
118   }
119   return NO;
122 NSImage* DragImageForBookmark(NSImage* favicon,
123                               const base::string16& title,
124                               CGFloat title_width) {
125   // If no favicon, use a default.
126   if (!favicon) {
127     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
128     favicon = rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).ToNSImage();
129   }
131   // If no title, just use icon.
132   if (title.empty())
133     return favicon;
134   NSString* ns_title = base::SysUTF16ToNSString(title);
136   // Set the look of the title.
137   NSDictionary* attrs =
138       [NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:
139                                            [NSFont smallSystemFontSize]]
140                                   forKey:NSFontAttributeName];
141   base::scoped_nsobject<NSAttributedString> rich_title(
142       [[NSAttributedString alloc] initWithString:ns_title attributes:attrs]);
144   // Set up sizes and locations for rendering.
145   const CGFloat kIconMargin = 2.0;  // Gap between icon and text.
146   CGFloat text_left = [favicon size].width + kIconMargin;
147   NSSize drag_image_size = [favicon size];
148   NSSize text_size = [rich_title size];
149   CGFloat max_text_width = title_width - text_left;
150   text_size.width = std::min(text_size.width, max_text_width);
151   drag_image_size.width = text_left + text_size.width;
153   // Render the drag image.
154   NSImage* drag_image =
155       [[[NSImage alloc] initWithSize:drag_image_size] autorelease];
156   [drag_image lockFocus];
157   [favicon drawAtPoint:NSZeroPoint
158               fromRect:NSZeroRect
159              operation:NSCompositeSourceOver
160               fraction:0.7];
161   NSRect target_text_rect = NSMakeRect(text_left, 0,
162                                        text_size.width, drag_image_size.height);
163   DrawTruncatedTitle(rich_title, target_text_rect);
164   [drag_image unlockFocus];
166   return drag_image;
169 }  // namespace drag_util