Index: chrome/browser/cocoa/bookmark_bubble_controller.mm |
=================================================================== |
--- chrome/browser/cocoa/bookmark_bubble_controller.mm (revision 0) |
+++ chrome/browser/cocoa/bookmark_bubble_controller.mm (revision 0) |
@@ -0,0 +1,215 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "app/l10n_util_mac.h" |
+#include "base/mac_util.h" |
+#include "base/sys_string_conversions.h" |
+#include "chrome/browser/bookmarks/bookmark_model.h" |
+#import "chrome/browser/cocoa/bookmark_bubble_controller.h" |
+#import "chrome/browser/cocoa/bookmark_bubble_window.h" |
+#include "grit/generated_resources.h" |
+ |
+ |
+@interface BookmarkBubbleController(PrivateAPI) |
+- (void)closeWindow; |
+@end |
+ |
+@implementation BookmarkBubbleController |
+ |
+@synthesize delegate = delegate_; |
+@synthesize folderComboBox = folderComboBox_; |
+ |
+- (id)initWithDelegate:(id<BookmarkBubbleControllerDelegate>)delegate |
+ parentWindow:(NSWindow*)parentWindow |
+ topLeftForBubble:(NSPoint)topLeftForBubble |
+ model:(BookmarkModel*)model |
+ node:(const BookmarkNode*)node |
+ alreadyBookmarked:(BOOL)alreadyBookmarked { |
+ if ((self = [super initWithNibName:@"BookmarkBubble" |
+ bundle:mac_util::MainAppBundle()])) { |
+ // all these are weak... |
+ delegate_ = delegate; |
+ parentWindow_ = parentWindow; |
+ topLeftForBubble_ = topLeftForBubble; |
+ model_ = model; |
+ node_ = node; |
+ alreadyBookmarked_ = alreadyBookmarked; |
+ // But this is strong. |
+ titleMapping_.reset([[NSMutableDictionary alloc] init]); |
+ } |
+ return self; |
+} |
+ |
+- (void)dealloc { |
+ [self closeWindow]; |
+ [super dealloc]; |
+} |
+ |
+- (void)showWindow { |
+ [self view]; // force nib load and window_ allocation |
+ [window_ makeKeyAndOrderFront:self]; |
+} |
+ |
+// Actually close the window. Do nothing else. |
+- (void)closeWindow { |
+ [parentWindow_ removeChildWindow:window_]; |
+ [window_ close]; |
+} |
+ |
+- (void)awakeFromNib { |
+ window_.reset([self createBubbleWindow]); |
+ [parentWindow_ addChildWindow:window_ ordered:NSWindowAbove]; |
+ |
+ // Fill in inital values for text, controls, ... |
+ |
+ // Default is IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK; "Bookmark". |
+ // If adding for the 1st time the string becomes "Bookmark Added!" |
+ if (!alreadyBookmarked_) { |
+ NSString* title = |
+ l10n_util::GetNSString(IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED); |
+ [bigTitle_ setStringValue:title]; |
+ } |
+ |
+ [self fillInFolderList]; |
+} |
+ |
+- (IBAction)edit:(id)sender { |
+ [self updateBookmarkNode]; |
+ [self closeWindow]; |
+ [delegate_ editBookmarkNode:node_]; |
+ [delegate_ doneWithBubbleController:self]; |
+} |
+ |
+- (IBAction)close:(id)sender { |
+ if (node_) { |
+ // no node_ if the bookmark was just removed |
+ [self updateBookmarkNode]; |
+ } |
+ [self closeWindow]; |
+ [delegate_ doneWithBubbleController:self]; |
+} |
+ |
+// By implementing this, ESC causes the window to go away. |
+- (IBAction)cancel:(id)sender { |
+ [self close:sender]; |
+} |
+ |
+- (IBAction)remove:(id)sender { |
+ model_->SetURLStarred(node_->GetURL(), node_->GetTitle(), false); |
+ node_ = NULL; // no longer valid |
+ [self close:self]; |
+} |
+ |
+// We are the delegate of the combo box so we can tell when "choose |
+// another folder" was picked. |
+- (void)comboBoxSelectionDidChange:(NSNotification*)notification { |
+ NSString* selected = [folderComboBox_ objectValueOfSelectedItem]; |
+ if ([selected isEqual:chooseAnotherFolder_.get()]) { |
+ [self edit:self]; |
+ } |
+} |
+ |
+// We are the delegate of our own window so we know when we lose key. |
+// When we lose key status we close, mirroring Windows behaivor. |
+- (void)windowDidResignKey:(NSNotification*)notification { |
+ if ([window_ isVisible]) |
+ [self close:self]; |
+} |
+ |
+@end // BookmarkBubbleController |
+ |
+ |
+@implementation BookmarkBubbleController(ExposedForUnitTesting) |
+ |
+// Create and return a retained NSWindow for this bubble. |
+- (NSWindow*)createBubbleWindow { |
+ NSRect contentRect = [[self view] frame]; |
+ NSPoint origin = topLeftForBubble_; |
+ origin.y -= contentRect.size.height; // since it'll be our bottom-left |
+ contentRect.origin = origin; |
+ // Now convert to global coordinates since it'll be used for a window. |
+ contentRect.origin = [parentWindow_ convertBaseToScreen:contentRect.origin]; |
+ NSWindow* window = [[BookmarkBubbleWindow alloc] |
+ initWithContentRect:contentRect]; |
+ [window setDelegate:self]; |
+ [window setContentView:[self view]]; |
+ return window; |
+} |
+ |
+// Fill in all information related to the folder combo box. |
+// |
+// TODO(jrg): make sure nested folders that have the same name are |
+// handled properly. |
+// http://crbug.com/19408 |
+- (void)fillInFolderList { |
+ [nameTextField_ setStringValue:base::SysWideToNSString(node_->GetTitle())]; |
+ [self addFolderNodes:model_->root_node() toComboBox:folderComboBox_]; |
+ |
+ // Add "Choose another folder...". Remember it for later to compare against. |
+ chooseAnotherFolder_.reset( |
+ [l10n_util::GetNSString(IDS_BOOMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER) |
+ retain]); |
+ [folderComboBox_ addItemWithObjectValue:chooseAnotherFolder_.get()]; |
+ |
+ // Finally, select the current parent. |
+ NSString* parentTitle = base::SysWideToNSString( |
+ node_->GetParent()->GetTitle()); |
+ [folderComboBox_ selectItemWithObjectValue:parentTitle]; |
+} |
+ |
+- (BOOL)windowHasBeenClosed { |
+ return ![window_ isVisible]; |
+} |
+ |
+// For the given folder node, walk the tree and add folder names to |
+// the given combo box. |
+// |
+// TODO(jrg): no distinction is made among folders with the same name. |
+- (void)addFolderNodes:(const BookmarkNode*)parent toComboBox:(NSComboBox*)box { |
+ NSString* title = base::SysWideToNSString(parent->GetTitle()); |
+ if ([title length]) { // no title if root |
+ [box addItemWithObjectValue:title]; |
+ [titleMapping_ setValue:[NSValue valueWithPointer:parent] forKey:title]; |
+ } |
+ for (int i = 0; i < parent->GetChildCount(); i++) { |
+ const BookmarkNode* child = parent->GetChild(i); |
+ if (child->is_folder()) |
+ [self addFolderNodes:child toComboBox:box]; |
+ } |
+} |
+ |
+// Look at the dialog; if the user has changed anything, update the |
+// bookmark node to reflect this. |
+- (void)updateBookmarkNode { |
+ // First the title... |
+ NSString* oldTitle = base::SysWideToNSString(node_->GetTitle()); |
+ NSString* newTitle = [nameTextField_ stringValue]; |
+ if (![oldTitle isEqual:newTitle]) { |
+ model_->SetTitle(node_, base::SysNSStringToWide(newTitle)); |
+ } |
+ // Then the parent folder. |
+ NSString* oldParentTitle = base::SysWideToNSString( |
+ node_->GetParent()->GetTitle()); |
+ NSString* newParentTitle = [folderComboBox_ objectValueOfSelectedItem]; |
+ if (![oldParentTitle isEqual:newParentTitle]) { |
+ const BookmarkNode* newParent = static_cast<const BookmarkNode*>( |
+ [[titleMapping_ objectForKey:newParentTitle] pointerValue]); |
+ if (newParent) { |
+ // newParent should only ever possibly be NULL in a unit test. |
+ int index = newParent->GetChildCount(); |
+ model_->Move(node_, newParent, index); |
+ } |
+ } |
+} |
+ |
+- (void)setTitle:(NSString*)title parentFolder:(NSString*)folder { |
+ [nameTextField_ setStringValue:title]; |
+ [folderComboBox_ selectItemWithObjectValue:folder]; |
+} |
+ |
+- (NSString*)chooseAnotherFolderString { |
+ return chooseAnotherFolder_.get(); |
+} |
+ |
+@end // implementation BookmarkBubbleController(ExposedForUnitTesting) |
Property changes on: chrome/browser/cocoa/bookmark_bubble_controller.mm |
___________________________________________________________________ |
Name: svn:eol-style |
+ LF |