| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h" | 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
| 8 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
| 9 #include "chrome/browser/bookmarks/bookmark_model.h" | 9 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 10 #include "chrome/browser/bookmarks/bookmark_utils.h" | 10 #include "chrome/browser/bookmarks/bookmark_utils.h" |
| 11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" | 11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" |
| 12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_cell_single_line.h" | 12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_cell_single_line.h" |
| 13 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 13 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 14 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 14 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 15 #include "content/browser/user_metrics.h" | |
| 16 #include "content/public/browser/notification_observer.h" | 15 #include "content/public/browser/notification_observer.h" |
| 17 #include "content/public/browser/notification_registrar.h" | 16 #include "content/public/browser/notification_registrar.h" |
| 18 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
| 18 #include "content/public/browser/user_metrics.h" |
| 19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util_mac.h" | 20 #include "ui/base/l10n/l10n_util_mac.h" |
| 21 | 21 |
| 22 using content::UserMetricsAction; |
| 23 |
| 22 | 24 |
| 23 // Simple class to watch for tab creation/destruction and close the bubble. | 25 // Simple class to watch for tab creation/destruction and close the bubble. |
| 24 // Bridge between Chrome-style notifications and ObjC-style notifications. | 26 // Bridge between Chrome-style notifications and ObjC-style notifications. |
| 25 class BookmarkBubbleNotificationBridge : public content::NotificationObserver { | 27 class BookmarkBubbleNotificationBridge : public content::NotificationObserver { |
| 26 public: | 28 public: |
| 27 BookmarkBubbleNotificationBridge(BookmarkBubbleController* controller, | 29 BookmarkBubbleNotificationBridge(BookmarkBubbleController* controller, |
| 28 SEL selector); | 30 SEL selector); |
| 29 virtual ~BookmarkBubbleNotificationBridge() {} | 31 virtual ~BookmarkBubbleNotificationBridge() {} |
| 30 void Observe(int type, | 32 void Observe(int type, |
| 31 const content::NotificationSource& source, | 33 const content::NotificationSource& source, |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 } | 259 } |
| 258 | 260 |
| 259 // Shows the bookmark editor sheet for more advanced editing. | 261 // Shows the bookmark editor sheet for more advanced editing. |
| 260 - (void)showEditor { | 262 - (void)showEditor { |
| 261 [self ok:self]; | 263 [self ok:self]; |
| 262 // Send the action up through the responder chain. | 264 // Send the action up through the responder chain. |
| 263 [NSApp sendAction:@selector(editBookmarkNode:) to:nil from:self]; | 265 [NSApp sendAction:@selector(editBookmarkNode:) to:nil from:self]; |
| 264 } | 266 } |
| 265 | 267 |
| 266 - (IBAction)edit:(id)sender { | 268 - (IBAction)edit:(id)sender { |
| 267 UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Edit")); | 269 content::RecordAction(UserMetricsAction("BookmarkBubble_Edit")); |
| 268 [self showEditor]; | 270 [self showEditor]; |
| 269 } | 271 } |
| 270 | 272 |
| 271 - (IBAction)ok:(id)sender { | 273 - (IBAction)ok:(id)sender { |
| 272 [self stopPulsingBookmarkButton]; // before parent changes | 274 [self stopPulsingBookmarkButton]; // before parent changes |
| 273 [self updateBookmarkNode]; | 275 [self updateBookmarkNode]; |
| 274 [self close]; | 276 [self close]; |
| 275 } | 277 } |
| 276 | 278 |
| 277 // By implementing this, ESC causes the window to go away. If clicking the | 279 // By implementing this, ESC causes the window to go away. If clicking the |
| 278 // star was what prompted this bubble to appear (i.e., not already bookmarked), | 280 // star was what prompted this bubble to appear (i.e., not already bookmarked), |
| 279 // remove the bookmark. | 281 // remove the bookmark. |
| 280 - (IBAction)cancel:(id)sender { | 282 - (IBAction)cancel:(id)sender { |
| 281 if (!alreadyBookmarked_) { | 283 if (!alreadyBookmarked_) { |
| 282 // |-remove:| calls |-close| so don't do it. | 284 // |-remove:| calls |-close| so don't do it. |
| 283 [self remove:sender]; | 285 [self remove:sender]; |
| 284 } else { | 286 } else { |
| 285 [self ok:sender]; | 287 [self ok:sender]; |
| 286 } | 288 } |
| 287 } | 289 } |
| 288 | 290 |
| 289 - (IBAction)remove:(id)sender { | 291 - (IBAction)remove:(id)sender { |
| 290 [self stopPulsingBookmarkButton]; | 292 [self stopPulsingBookmarkButton]; |
| 291 bookmark_utils::RemoveAllBookmarks(model_, node_->url()); | 293 bookmark_utils::RemoveAllBookmarks(model_, node_->url()); |
| 292 UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Unstar")); | 294 content::RecordAction(UserMetricsAction("BookmarkBubble_Unstar")); |
| 293 node_ = NULL; // no longer valid | 295 node_ = NULL; // no longer valid |
| 294 [self ok:sender]; | 296 [self ok:sender]; |
| 295 } | 297 } |
| 296 | 298 |
| 297 // The controller is the target of the pop up button box action so it can | 299 // The controller is the target of the pop up button box action so it can |
| 298 // handle when "choose another folder" was picked. | 300 // handle when "choose another folder" was picked. |
| 299 - (IBAction)folderChanged:(id)sender { | 301 - (IBAction)folderChanged:(id)sender { |
| 300 DCHECK([sender isEqual:folderPopUpButton_]); | 302 DCHECK([sender isEqual:folderPopUpButton_]); |
| 301 // It is possible that due to model change our parent window has been closed | 303 // It is possible that due to model change our parent window has been closed |
| 302 // but the popup is still showing and able to notify the controller of a | 304 // but the popup is still showing and able to notify the controller of a |
| 303 // folder change. We ignore the sender in this case. | 305 // folder change. We ignore the sender in this case. |
| 304 if (!parentWindow_) | 306 if (!parentWindow_) |
| 305 return; | 307 return; |
| 306 NSMenuItem* selected = [folderPopUpButton_ selectedItem]; | 308 NSMenuItem* selected = [folderPopUpButton_ selectedItem]; |
| 307 ChooseAnotherFolder* chooseItem = [[self class] chooseAnotherFolderObject]; | 309 ChooseAnotherFolder* chooseItem = [[self class] chooseAnotherFolderObject]; |
| 308 if ([[selected representedObject] isEqual:chooseItem]) { | 310 if ([[selected representedObject] isEqual:chooseItem]) { |
| 309 UserMetrics::RecordAction( | 311 content::RecordAction( |
| 310 UserMetricsAction("BookmarkBubble_EditFromCombobox")); | 312 UserMetricsAction("BookmarkBubble_EditFromCombobox")); |
| 311 [self showEditor]; | 313 [self showEditor]; |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 // The controller is the delegate of the window so it receives did resign key | 317 // The controller is the delegate of the window so it receives did resign key |
| 316 // notifications. When key is resigned mirror Windows behavior and close the | 318 // notifications. When key is resigned mirror Windows behavior and close the |
| 317 // window. | 319 // window. |
| 318 - (void)windowDidResignKey:(NSNotification*)notification { | 320 - (void)windowDidResignKey:(NSNotification*)notification { |
| 319 NSWindow* window = [self window]; | 321 NSWindow* window = [self window]; |
| 320 DCHECK_EQ([notification object], window); | 322 DCHECK_EQ([notification object], window); |
| 321 if ([window isVisible]) { | 323 if ([window isVisible]) { |
| 322 // If the window isn't visible, it is already closed, and this notification | 324 // If the window isn't visible, it is already closed, and this notification |
| 323 // has been sent as part of the closing operation, so no need to close. | 325 // has been sent as part of the closing operation, so no need to close. |
| 324 [self ok:self]; | 326 [self ok:self]; |
| 325 } | 327 } |
| 326 } | 328 } |
| 327 | 329 |
| 328 // Look at the dialog; if the user has changed anything, update the | 330 // Look at the dialog; if the user has changed anything, update the |
| 329 // bookmark node to reflect this. | 331 // bookmark node to reflect this. |
| 330 - (void)updateBookmarkNode { | 332 - (void)updateBookmarkNode { |
| 331 if (!node_) return; | 333 if (!node_) return; |
| 332 | 334 |
| 333 // First the title... | 335 // First the title... |
| 334 NSString* oldTitle = base::SysUTF16ToNSString(node_->GetTitle()); | 336 NSString* oldTitle = base::SysUTF16ToNSString(node_->GetTitle()); |
| 335 NSString* newTitle = [nameTextField_ stringValue]; | 337 NSString* newTitle = [nameTextField_ stringValue]; |
| 336 if (![oldTitle isEqual:newTitle]) { | 338 if (![oldTitle isEqual:newTitle]) { |
| 337 model_->SetTitle(node_, base::SysNSStringToUTF16(newTitle)); | 339 model_->SetTitle(node_, base::SysNSStringToUTF16(newTitle)); |
| 338 UserMetrics::RecordAction( | 340 content::RecordAction( |
| 339 UserMetricsAction("BookmarkBubble_ChangeTitleInBubble")); | 341 UserMetricsAction("BookmarkBubble_ChangeTitleInBubble")); |
| 340 } | 342 } |
| 341 // Then the parent folder. | 343 // Then the parent folder. |
| 342 const BookmarkNode* oldParent = node_->parent(); | 344 const BookmarkNode* oldParent = node_->parent(); |
| 343 NSMenuItem* selectedItem = [folderPopUpButton_ selectedItem]; | 345 NSMenuItem* selectedItem = [folderPopUpButton_ selectedItem]; |
| 344 id representedObject = [selectedItem representedObject]; | 346 id representedObject = [selectedItem representedObject]; |
| 345 if ([representedObject isEqual:[[self class] chooseAnotherFolderObject]]) { | 347 if ([representedObject isEqual:[[self class] chooseAnotherFolderObject]]) { |
| 346 // "Choose another folder..." | 348 // "Choose another folder..." |
| 347 return; | 349 return; |
| 348 } | 350 } |
| 349 const BookmarkNode* newParent = | 351 const BookmarkNode* newParent = |
| 350 static_cast<const BookmarkNode*>([representedObject pointerValue]); | 352 static_cast<const BookmarkNode*>([representedObject pointerValue]); |
| 351 DCHECK(newParent); | 353 DCHECK(newParent); |
| 352 if (oldParent != newParent) { | 354 if (oldParent != newParent) { |
| 353 int index = newParent->child_count(); | 355 int index = newParent->child_count(); |
| 354 model_->Move(node_, newParent, index); | 356 model_->Move(node_, newParent, index); |
| 355 UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_ChangeParent")); | 357 content::RecordAction(UserMetricsAction("BookmarkBubble_ChangeParent")); |
| 356 } | 358 } |
| 357 } | 359 } |
| 358 | 360 |
| 359 // Fill in all information related to the folder pop up button. | 361 // Fill in all information related to the folder pop up button. |
| 360 - (void)fillInFolderList { | 362 - (void)fillInFolderList { |
| 361 [nameTextField_ setStringValue:base::SysUTF16ToNSString(node_->GetTitle())]; | 363 [nameTextField_ setStringValue:base::SysUTF16ToNSString(node_->GetTitle())]; |
| 362 DCHECK([folderPopUpButton_ numberOfItems] == 0); | 364 DCHECK([folderPopUpButton_ numberOfItems] == 0); |
| 363 [self addFolderNodes:model_->root_node() | 365 [self addFolderNodes:model_->root_node() |
| 364 toPopUpButton:folderPopUpButton_ | 366 toPopUpButton:folderPopUpButton_ |
| 365 indentation:0]; | 367 indentation:0]; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue]; | 427 NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue]; |
| 426 DCHECK(idx != -1); | 428 DCHECK(idx != -1); |
| 427 [folderPopUpButton_ selectItemAtIndex:idx]; | 429 [folderPopUpButton_ selectItemAtIndex:idx]; |
| 428 } | 430 } |
| 429 | 431 |
| 430 - (NSPopUpButton*)folderPopUpButton { | 432 - (NSPopUpButton*)folderPopUpButton { |
| 431 return folderPopUpButton_; | 433 return folderPopUpButton_; |
| 432 } | 434 } |
| 433 | 435 |
| 434 @end // implementation BookmarkBubbleController(ExposedForUnitTesting) | 436 @end // implementation BookmarkBubbleController(ExposedForUnitTesting) |
| OLD | NEW |