Home | History | Annotate | Download | only in cocoa
      1 // Copyright (c) 2012 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.
      4 
      5 #import "chrome/browser/ui/cocoa/url_drop_target.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "chrome/browser/ui/cocoa/drag_util.h"
      9 #import "third_party/mozilla/NSPasteboard+Utils.h"
     10 #include "url/gurl.h"
     11 
     12 namespace {
     13 
     14 // Mac WebKit uses this type, declared in
     15 // WebKit/mac/History/WebURLsWithTitles.h.
     16 NSString* const kCrWebURLsWithTitlesPboardType =
     17     @"WebURLsWithTitlesPboardType";
     18 
     19 }  // namespace
     20 
     21 @interface URLDropTargetHandler(Private)
     22 
     23 // Gets the appropriate drag operation given the |NSDraggingInfo|.
     24 - (NSDragOperation)getDragOperation:(id<NSDraggingInfo>)sender;
     25 
     26 // Tell the window controller to hide the drop indicator.
     27 - (void)hideIndicator;
     28 
     29 @end  // @interface URLDropTargetHandler(Private)
     30 
     31 @implementation URLDropTargetHandler
     32 
     33 + (NSArray*)handledDragTypes {
     34   return [NSArray arrayWithObjects:kCrWebURLsWithTitlesPboardType,
     35                                    NSURLPboardType,
     36                                    NSStringPboardType,
     37                                    NSFilenamesPboardType,
     38                                    nil];
     39 }
     40 
     41 - (id)initWithView:(NSView<URLDropTarget>*)view {
     42   if ((self = [super init])) {
     43     view_ = view;
     44     [view_ registerForDraggedTypes:[URLDropTargetHandler handledDragTypes]];
     45   }
     46   return self;
     47 }
     48 
     49 // The following four methods implement parts of the |NSDraggingDestination|
     50 // protocol, which the owner should "forward" to its |URLDropTargetHandler|
     51 // (us).
     52 
     53 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
     54   if ([[view_ urlDropController] isUnsupportedDropData:sender])
     55     return NSDragOperationNone;
     56 
     57   return [self getDragOperation:sender];
     58 }
     59 
     60 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
     61   NSDragOperation dragOp = NSDragOperationNone;
     62   BOOL showIndicator = NO;
     63   // Show indicator for drag data supported for tab contents as well as for
     64   // local file drags that may not be viewable in tab contents, but should
     65   // still trigger hover tab selection.
     66   if (![[view_ urlDropController] isUnsupportedDropData:sender]) {
     67     dragOp = [self getDragOperation:sender];
     68     if (dragOp == NSDragOperationCopy)
     69       showIndicator = YES;
     70   } else if (!drag_util::GetFileURLFromDropData(sender).is_empty()) {
     71     showIndicator = YES;
     72   }
     73 
     74   if (showIndicator) {
     75     // Just tell the window controller to update the indicator.
     76     NSPoint hoverPoint = [view_ convertPoint:[sender draggingLocation]
     77                                     fromView:nil];
     78     [[view_ urlDropController] indicateDropURLsInView:view_ at:hoverPoint];
     79   }
     80   return dragOp;
     81 }
     82 
     83 - (void)draggingExited:(id<NSDraggingInfo>)sender {
     84   [self hideIndicator];
     85 }
     86 
     87 - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
     88   [self hideIndicator];
     89 
     90   NSPasteboard* pboard = [sender draggingPasteboard];
     91   NSArray* supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
     92   NSString* bestType = [pboard availableTypeFromArray:supportedTypes];
     93 
     94   NSPoint dropPoint =
     95       [view_ convertPoint:[sender draggingLocation] fromView:nil];
     96   // Tell the window controller about the dropped URL(s).
     97   if ([pboard containsURLData]) {
     98     NSArray* urls = nil;
     99     NSArray* titles;  // discarded
    100     [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
    101 
    102     if ([urls count]) {
    103       [[view_ urlDropController] dropURLs:urls inView:view_ at:dropPoint];
    104       return YES;
    105     }
    106   } else if (NSString* text = [pboard stringForType:bestType]) {
    107     // This does not include any URLs, so treat it as plain text if we can
    108     // get NSString.
    109     [[view_ urlDropController] dropText:text inView:view_ at:dropPoint];
    110     return YES;
    111   }
    112 
    113   return NO;
    114 }
    115 
    116 @end  // @implementation URLDropTargetHandler
    117 
    118 @implementation URLDropTargetHandler(Private)
    119 
    120 - (NSDragOperation)getDragOperation:(id<NSDraggingInfo>)sender {
    121   NSPasteboard* pboard = [sender draggingPasteboard];
    122   NSArray *supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
    123   NSString *bestType = [pboard availableTypeFromArray:supportedTypes];
    124   if (![pboard containsURLData] && ![pboard stringForType:bestType])
    125     return NSDragOperationNone;
    126 
    127   // Only allow the copy operation.
    128   return [sender draggingSourceOperationMask] & NSDragOperationCopy;
    129 }
    130 
    131 - (void)hideIndicator {
    132   [[view_ urlDropController] hideDropURLsIndicatorInView:view_];
    133 }
    134 
    135 @end  // @implementation URLDropTargetHandler(Private)
    136