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