Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / bookmarks / bookmark_bar_folder_view.mm
blob3a62c85c4c8c31cf51c31059b55920a087f4f986
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/bookmarks/bookmark_bar_folder_view.h"
7 #include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
8 #include "chrome/browser/profiles/profile.h"
9 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
10 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h"
11 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
12 #include "content/public/browser/user_metrics.h"
14 using base::UserMetricsAction;
16 #import "third_party/mozilla/NSPasteboard+Utils.h"
18 @interface BookmarkBarFolderView()
20 @property(readonly, nonatomic) id<BookmarkButtonControllerProtocol> controller;
22 - (void)setDropIndicatorShown:(BOOL)flag;
24 @end
26 @implementation BookmarkBarFolderView
28 - (void)awakeFromNib {
29   NSArray* types = [NSArray arrayWithObjects:
30                     NSStringPboardType,
31                     NSHTMLPboardType,
32                     NSURLPboardType,
33                     kBookmarkButtonDragType,
34                     kBookmarkDictionaryListPboardType,
35                     nil];
36   [self registerForDraggedTypes:types];
39 - (void)dealloc {
40   [self unregisterDraggedTypes];
41   [super dealloc];
44 - (id<BookmarkButtonControllerProtocol>)controller {
45   // When needed for testing, set the local data member |controller_| to
46   // the test controller.
47   return controller_ ? controller_ : [[self window] windowController];
50 // Virtually identical to [BookmarkBarView draggingEntered:].
51 // TODO(jrg): find a way to share code.  Lack of multiple inheritance
52 // makes things more of a pain but there should be no excuse for laziness.
53 // http://crbug.com/35966
54 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
55   inDrag_ = YES;
56   if (![[self controller] draggingAllowed:info])
57     return NSDragOperationNone;
58   if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] ||
59       PasteboardContainsBookmarks(ui::CLIPBOARD_TYPE_DRAG) ||
60       [[info draggingPasteboard] containsURLData]) {
61     // Find the position of the drop indicator.
62     BOOL showIt = [[self controller]
63                    shouldShowIndicatorShownForPoint:[info draggingLocation]];
64     if (!showIt) {
65       [self setDropIndicatorShown:NO];
66     } else {
67       [self setDropIndicatorShown:YES];
69       CGFloat y = [[self controller]
70           indicatorPosForDragToPoint:[info draggingLocation]];
71       NSRect frame = [dropIndicator_ frame];
72       if (NSMinY(frame) != y) {
73         frame.origin.y = y;
74         [dropIndicator_ setFrame:frame];
75       }
76     }
78     [[self controller] draggingEntered:info];  // allow hover-open to work
79     return [info draggingSource] ? NSDragOperationMove : NSDragOperationCopy;
80   }
81   return NSDragOperationNone;
84 - (void)draggingExited:(id<NSDraggingInfo>)info {
85   [[self controller] draggingExited:info];
87   // Regardless of the type of dragging which ended, we need to get rid of the
88   // drop indicator if one was shown.
89   [self setDropIndicatorShown:NO];
92 - (void)draggingEnded:(id<NSDraggingInfo>)info {
93   // Awkwardness since views open and close out from under us.
94   if (inDrag_) {
95     inDrag_ = NO;
96   }
98   [self draggingExited:info];
101 - (BOOL)wantsPeriodicDraggingUpdates {
102   // TODO(jrg): The controller should slide the existing bookmark buttons
103   // interactively to the side to make room for the about-to-be-dropped
104   // bookmark.
105   // http://crbug.com/35968
107   // The bookmark_bar_folder_hover_state expects continuous callbacks.
108   return YES;
111 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
112   // For now it's the same as draggingEntered:.
113   // TODO(jrg): once we return YES for wantsPeriodicDraggingUpdates,
114   // this should ping the [self controller] to perform animations.
115   // http://crbug.com/35968
116   return [self draggingEntered:info];
119 - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
120   return YES;
123 // This code is practically identical to the same function in BookmarkBarView
124 // with the only difference being how the controller is retrieved.
125 // TODO(mrossetti,jrg): http://crbug.com/35966
126 // Implement NSDraggingDestination protocol method
127 // performDragOperation: for URLs.
128 - (BOOL)performDragOperationForURL:(id<NSDraggingInfo>)info {
129   NSPasteboard* pboard = [info draggingPasteboard];
130   DCHECK([pboard containsURLData]);
132   NSArray* urls = nil;
133   NSArray* titles = nil;
134   [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
136   return [[self controller] addURLs:urls
137                          withTitles:titles
138                                  at:[info draggingLocation]];
141 // This code is practically identical to the same function in BookmarkBarView
142 // with the only difference being how the controller is retrieved.
143 // http://crbug.com/35966
144 // Implement NSDraggingDestination protocol method
145 // performDragOperation: for bookmark buttons.
146 - (BOOL)performDragOperationForBookmarkButton:(id<NSDraggingInfo>)info {
147   BOOL doDrag = NO;
148   NSData* data = [[info draggingPasteboard]
149                    dataForType:kBookmarkButtonDragType];
150   // [info draggingSource] is nil if not the same application.
151   if (data && [info draggingSource]) {
152     BookmarkButton* button = nil;
153     [data getBytes:&button length:sizeof(button)];
155     // If we're dragging from one profile to another, disallow moving (only
156     // allow copying). Each profile has its own bookmark model, so one way to
157     // check whether we are dragging across profiles is to see if the
158     // |BookmarkNode| corresponding to |button| exists in this profile. If it
159     // does, we're dragging within a profile; otherwise, we're dragging across
160     // profiles.
161     const BookmarkModel* const model = [[self controller] bookmarkModel];
162     const BookmarkNode* const source_node = [button bookmarkNode];
163     const BookmarkNode* const target_node =
164         model->GetNodeByID(source_node->id());
166     BOOL copy =
167         !([info draggingSourceOperationMask] & NSDragOperationMove) ||
168         (source_node != target_node);
169     doDrag = [[self controller] dragButton:button
170                                         to:[info draggingLocation]
171                                       copy:copy];
172     content::RecordAction(UserMetricsAction("BookmarkBarFolder_DragEnd"));
173   }
174   return doDrag;
177 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
178   if ([[self controller] dragBookmarkData:info])
179     return YES;
180   NSPasteboard* pboard = [info draggingPasteboard];
181   if ([pboard dataForType:kBookmarkButtonDragType] &&
182       [self performDragOperationForBookmarkButton:info])
183     return YES;
184   if ([pboard containsURLData] && [self performDragOperationForURL:info])
185     return YES;
186   return NO;
189 - (void)setDropIndicatorShown:(BOOL)flag {
190   if (dropIndicatorShown_ == flag)
191     return;
193   dropIndicatorShown_ = flag;
194   if (dropIndicatorShown_) {
195     NSRect frame = NSInsetRect([self bounds], 4, 0);
196     frame.size.height = 1;
197     dropIndicator_.reset([[NSBox alloc] initWithFrame:frame]);
198     [dropIndicator_ setBoxType:NSBoxSeparator];
199     [dropIndicator_ setBorderType:NSLineBorder];
200     [dropIndicator_ setAlphaValue:0.85];
201     [self addSubview:dropIndicator_];
202   } else {
203     [dropIndicator_ removeFromSuperview];
204     dropIndicator_.reset();
205   }
208 @end