Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / bookmarks / bookmark_bar_view_cocoa.mm
blobced2de0593a115fa5d66af3e43492d61f592d64e
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_view_cocoa.h"
7 #include "chrome/browser/profiles/profile.h"
8 #import "chrome/browser/themes/theme_properties.h"
9 #import "chrome/browser/themes/theme_service.h"
10 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h"
13 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h"
14 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
15 #import "chrome/browser/ui/cocoa/themed_window.h"
16 #import "chrome/browser/ui/cocoa/view_id_util.h"
17 #include "components/bookmarks/browser/bookmark_pasteboard_helper_mac.h"
18 #include "components/bookmarks/browser/bookmark_utils.h"
19 #include "content/public/browser/user_metrics.h"
20 #import "third_party/mozilla/NSPasteboard+Utils.h"
22 using base::UserMetricsAction;
23 using bookmarks::BookmarkModel;
24 using bookmarks::BookmarkNode;
26 @interface BookmarkBarView (Private)
27 - (void)themeDidChangeNotification:(NSNotification*)aNotification;
28 - (void)updateTheme:(ui::ThemeProvider*)themeProvider;
29 @end
31 @implementation BookmarkBarView
33 @synthesize dropIndicatorShown = dropIndicatorShown_;
34 @synthesize dropIndicatorPosition = dropIndicatorPosition_;
35 @synthesize noItemContainer = noItemContainer_;
38 - (void)dealloc {
39   [[NSNotificationCenter defaultCenter] removeObserver:self];
40   // This probably isn't strictly necessary, but can't hurt.
41   [self unregisterDraggedTypes];
42   [super dealloc];
44   // To be clear, our controller_ is an IBOutlet and owns us, so we
45   // don't deallocate it explicitly.  It is owned by the browser
46   // window controller, so gets deleted with a browser window is
47   // closed.
50 - (void)awakeFromNib {
51   NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
52   [defaultCenter addObserver:self
53                     selector:@selector(themeDidChangeNotification:)
54                         name:kBrowserThemeDidChangeNotification
55                       object:nil];
57   DCHECK(controller_) << "Expected this to be hooked up via Interface Builder";
58   NSArray* types = [NSArray arrayWithObjects:
59                     NSStringPboardType,
60                     NSHTMLPboardType,
61                     NSURLPboardType,
62                     kBookmarkButtonDragType,
63                     kBookmarkDictionaryListPboardType,
64                     nil];
65   [self registerForDraggedTypes:types];
68 // We need the theme to color the bookmark buttons properly.  But our
69 // controller desn't have access to it until it's placed in the view
70 // hierarchy.  This is the spot where we close the loop.
71 - (void)viewWillMoveToWindow:(NSWindow*)window {
72   ui::ThemeProvider* themeProvider = [window themeProvider];
73   [self updateTheme:themeProvider];
74   [controller_ updateTheme:themeProvider];
75   [super viewWillMoveToWindow:window];
78 - (void)viewDidMoveToWindow {
79   [controller_ viewDidMoveToWindow];
82 // Called after a theme change took place, possibly for a different profile.
83 - (void)themeDidChangeNotification:(NSNotification*)notification {
84   [self updateTheme:[[self window] themeProvider]];
87 // Adapt appearance to the current theme. Called after theme changes and before
88 // this is shown for the first time.
89 - (void)updateTheme:(ui::ThemeProvider*)themeProvider {
90   if (!themeProvider)
91     return;
93   NSColor* color =
94       themeProvider->GetNSColor(ThemeProperties::COLOR_BOOKMARK_TEXT);
95   [noItemTextfield_ setTextColor:color];
98 // Mouse down events on the bookmark bar should not allow dragging the parent
99 // window around.
100 - (BOOL)mouseDownCanMoveWindow {
101   return NO;
104 - (BookmarkBarTextField*)noItemTextfield {
105   return noItemTextfield_;
108 - (NSButton*)importBookmarksButton {
109   return importBookmarksButton_;
112 - (BookmarkBarController*)controller {
113   return controller_;
116 // Internal method, needs to be called whenever a change has been made to
117 // dropIndicatorShown_ or dropIndicatorPosition_ so it can get the controller
118 // to reflect the change by moving buttons around.
119 - (void)dropIndicatorChanged {
120   if (dropIndicatorShown_)
121     [controller_ setDropInsertionPos:dropIndicatorPosition_];
122   else
123     [controller_ clearDropInsertionPos];
126 // NSDraggingDestination methods
128 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
129   if (![controller_ draggingAllowed:info])
130     return NSDragOperationNone;
131   if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] ||
132       bookmarks::PasteboardContainsBookmarks(ui::CLIPBOARD_TYPE_DRAG) ||
133       [[info draggingPasteboard] containsURLData]) {
134     // We only show the drop indicator if we're not in a position to
135     // perform a hover-open since it doesn't make sense to do both.
136     BOOL showIt = [controller_ shouldShowIndicatorShownForPoint:
137                    [info draggingLocation]];
138     if (!showIt) {
139       if (dropIndicatorShown_) {
140         dropIndicatorShown_ = NO;
141         [self dropIndicatorChanged];
142       }
143     } else {
144       CGFloat x =
145       [controller_ indicatorPosForDragToPoint:[info draggingLocation]];
146       // Need an update if the indicator wasn't previously shown or if it has
147       // moved.
148       if (!dropIndicatorShown_ || dropIndicatorPosition_ != x) {
149         dropIndicatorShown_ = YES;
150         dropIndicatorPosition_ = x;
151         [self dropIndicatorChanged];
152       }
153     }
155     [controller_ draggingEntered:info];  // allow hover-open to work.
156     return [[info draggingSource] isKindOfClass: [BookmarkButton class]] ?
157         NSDragOperationMove : NSDragOperationCopy;
158   }
159   return NSDragOperationNone;
162 - (void)draggingExited:(id<NSDraggingInfo>)info {
163   [controller_ draggingExited:info];
165   // Regardless of the type of dragging which ended, we need to get rid of the
166   // drop indicator if one was shown.
167   if (dropIndicatorShown_) {
168     dropIndicatorShown_ = NO;
169     [self dropIndicatorChanged];
170   }
173 - (void)draggingEnded:(id<NSDraggingInfo>)info {
174   [controller_ draggingEnded:info];
176   [[BookmarkButton draggedButton] setHidden:NO];
177   if (dropIndicatorShown_) {
178     dropIndicatorShown_ = NO;
179     [self dropIndicatorChanged];
180   }
181   [controller_ draggingEnded:info];
184 - (BOOL)wantsPeriodicDraggingUpdates {
185   return YES;
188 - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
189   // For now it's the same as draggingEntered:.
190   return [self draggingEntered:info];
193 - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
194   return YES;
197 // Implement NSDraggingDestination protocol method
198 // performDragOperation: for URLs.
199 - (BOOL)performDragOperationForURL:(id<NSDraggingInfo>)info {
200   NSPasteboard* pboard = [info draggingPasteboard];
201   DCHECK([pboard containsURLData]);
203   NSArray* urls = nil;
204   NSArray* titles = nil;
205   [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
207   return [controller_ addURLs:urls
208                    withTitles:titles
209                            at:[info draggingLocation]];
212 // Implement NSDraggingDestination protocol method
213 // performDragOperation: for bookmark buttons.
214 - (BOOL)performDragOperationForBookmarkButton:(id<NSDraggingInfo>)info {
215   BOOL rtn = NO;
216   NSData* data = [[info draggingPasteboard]
217                   dataForType:kBookmarkButtonDragType];
218   // [info draggingSource] is nil if not the same application.
219   if (data && [info draggingSource]) {
220     BookmarkButton* button = nil;
221     [data getBytes:&button length:sizeof(button)];
223     // If we're dragging from one profile to another, disallow moving (only
224     // allow copying). Each profile has its own bookmark model, so one way to
225     // check whether we are dragging across profiles is to see if the
226     // |BookmarkNode| corresponding to |button| exists in this profile. If it
227     // does, we're dragging within a profile; otherwise, we're dragging across
228     // profiles.
229     const BookmarkModel* const model = [[self controller] bookmarkModel];
230     const BookmarkNode* const source_node = [button bookmarkNode];
231     const BookmarkNode* const target_node =
232         bookmarks::GetBookmarkNodeByID(model, source_node->id());
234     BOOL copy =
235         !([info draggingSourceOperationMask] & NSDragOperationMove) ||
236         (source_node != target_node);
237     rtn = [controller_ dragButton:button
238                                to:[info draggingLocation]
239                              copy:copy];
240     content::RecordAction(UserMetricsAction("BookmarkBar_DragEnd"));
241   }
242   return rtn;
245 - (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
246   if ([controller_ dragBookmarkData:info])
247     return YES;
248   NSPasteboard* pboard = [info draggingPasteboard];
249   if ([pboard dataForType:kBookmarkButtonDragType]) {
250     if ([self performDragOperationForBookmarkButton:info])
251       return YES;
252     // Fall through....
253   }
254   if ([pboard containsURLData]) {
255     if ([self performDragOperationForURL:info])
256       return YES;
257   }
258   return NO;
261 - (NSMenu*)menu {
262   return [[controller_ menuController] menuForBookmarkBar];
265 - (void)setController:(id)controller {
266   controller_ = controller;
269 - (ViewID)viewID {
270   return VIEW_ID_BOOKMARK_BAR;
273 @end  // @implementation BookmarkBarView
275 @implementation BookmarkBarTextField
277 - (NSMenu*)menu {
278   return [barView_ menu];
281 @end  // @implementation BookmarkBarTextField
283 @implementation BookmarkBarItemContainer
285 - (NSMenu*)menu {
286   return [barView_ menu];
289 @end  // @implementation BookmarkBarItemContainer