summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormrossetti@chromium.org <mrossetti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 22:10:32 +0000
committermrossetti@chromium.org <mrossetti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 22:10:32 +0000
commitfbc93b36cbe62f4777c3f07f87ea113afbd2f348 (patch)
treef79f85acb61b6615d2b555ed75aecaa082e16854
parent094302f1c1fbd9815b03dc23769315e4b2875e40 (diff)
downloadchromium_src-fbc93b36cbe62f4777c3f07f87ea113afbd2f348.zip
chromium_src-fbc93b36cbe62f4777c3f07f87ea113afbd2f348.tar.gz
chromium_src-fbc93b36cbe62f4777c3f07f87ea113afbd2f348.tar.bz2
Original discussion in CL for 337010. See http://codereview.chromium.org/337010/show/.
BUG=25099 TEST=See 337010. Review URL: http://codereview.chromium.org/343042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30523 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/nibs/BookmarkEditor.xib58
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.h12
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.mm213
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller_unittest.mm36
-rw-r--r--chrome/browser/cocoa/bookmark_tree_browser_cell.h34
-rw-r--r--chrome/browser/cocoa/bookmark_tree_browser_cell.mm22
-rw-r--r--chrome/browser/cocoa/bookmark_tree_browser_cell_unittest.mm43
-rwxr-xr-xchrome/chrome.gyp3
8 files changed, 342 insertions, 79 deletions
diff --git a/chrome/app/nibs/BookmarkEditor.xib b/chrome/app/nibs/BookmarkEditor.xib
index 5b8cc25..aabecda 100644
--- a/chrome/app/nibs/BookmarkEditor.xib
+++ b/chrome/app/nibs/BookmarkEditor.xib
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.02">
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">1050</int>
- <string key="IBDocument.SystemVersion">9L30</string>
- <string key="IBDocument.InterfaceBuilderVersion">670</string>
+ <string key="IBDocument.SystemVersion">9L31a</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.54</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
@@ -14,6 +14,15 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1001">
@@ -353,14 +362,6 @@
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
- <string key="label">browser_</string>
- <reference key="source" ref="1001"/>
- <reference key="destination" ref="723395462"/>
- </object>
- <int key="connectionID">27</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="1005"/>
@@ -425,11 +426,27 @@
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
+ <string key="label">folderBrowser_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="723395462"/>
+ </object>
+ <int key="connectionID">59</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="723395462"/>
<reference key="destination" ref="1001"/>
</object>
- <int key="connectionID">53</int>
+ <int key="connectionID">60</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">target</string>
+ <reference key="source" ref="723395462"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">61</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
@@ -487,6 +504,7 @@
<int key="objectID">26</int>
<reference key="object" ref="723395462"/>
<reference key="parent" ref="1006"/>
+ <string key="objectName">Folder Tree Browser</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">34</int>
@@ -734,7 +752,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">54</int>
+ <int key="maxID">61</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -761,7 +779,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
- <string>browser_</string>
+ <string>folderBrowser_</string>
<string>nameField_</string>
<string>newFolderButton_</string>
<string>okButton_</string>
@@ -856,6 +874,18 @@
<reference key="sourceIdentifier" ref="262327023"/>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">NSBrowser</string>
+ <string key="superclassName">NSControl</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">target</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.h b/chrome/browser/cocoa/bookmark_editor_controller.h
index a0b8a95..4c03c98 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller.h
+++ b/chrome/browser/cocoa/bookmark_editor_controller.h
@@ -12,13 +12,15 @@
#include "base/scoped_nsobject.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
+@class BookmarkTreeBrowserCell;
+
// A controller for the bookmark editor, opened with Edit... from the
// context menu of a bookmark button.
@interface BookmarkEditorController : NSWindowController<NSTextFieldDelegate> {
@private
IBOutlet NSTextField* nameField_;
IBOutlet NSTextField* urlField_;
- IBOutlet NSBrowser* browser_;
+ IBOutlet NSBrowser* folderBrowser_;
IBOutlet NSButton* okButton_;
IBOutlet NSButton* newFolderButton_;
@@ -31,6 +33,7 @@
scoped_nsobject<NSString> initialName_;
scoped_nsobject<NSString> initialUrl_;
+ scoped_nsobject<BookmarkTreeBrowserCell> currentEditCell_;
}
- (id)initWithParentWindow:(NSWindow*)parentWindow
@@ -43,8 +46,11 @@
// Run the bookmark editor as a modal sheet. Does not block.
- (void)runAsModalSheet;
-// Actions for the buttons at the bottom of the window.
+// Create a new folder at the end of the selected parent folder, give it
+// an untitled name, and put it into editing mode.
- (IBAction)newFolder:(id)sender;
+
+// Actions for the buttons at the bottom of the window.
- (IBAction)cancel:(id)sender;
- (IBAction)ok:(id)sender;
@end
@@ -56,6 +62,4 @@
- (void)selectTestNodeInBrowser:(const BookmarkNode*)node;
@end
-
#endif /* CHROME_BROWSER_COCOA_BOOKMARK_EDITOR_CONTROLLER_H_ */
-
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.mm b/chrome/browser/cocoa/bookmark_editor_controller.mm
index 5ded618..93ea8e3 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller.mm
+++ b/chrome/browser/cocoa/bookmark_editor_controller.mm
@@ -2,27 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "app/l10n_util.h"
#include "base/logging.h"
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profile.h"
+#import "chrome/browser/cocoa/bookmark_tree_browser_cell.h"
#import "chrome/browser/cocoa/bookmark_editor_controller.h"
+#include "grit/generated_resources.h"
@interface BookmarkEditorController (Private)
// Grab the url from the text field and convert.
- (GURL)GURLFromUrlField;
+// Given a cell in the folder browser, make that cell editable so that the
+// bookmark folder name can be modified by the user.
+- (void)editFolderNameInCell:(BookmarkTreeBrowserCell*)cell;
+
+// The action called by the bookmark folder name cell being edited by
+// the user when editing has been completed (such as by pressing <return>).
+- (void)cellEditingCompleted:(id)sender;
+
+// Update the folder name from the current edit in the given cell
+// and return the focus to the folder tree browser.
+- (void)saveFolderNameForCell:(BookmarkTreeBrowserCell*)cell;
+
+// A custom action handler called by the bookmark folder browser when the
+// user has double-clicked on a folder name.
+- (void)browserDoubleClicked:(id)sender;
+
// Determine and returns the rightmost selected/highlighted element (node)
// in the bookmark tree view if the tree view is showing, otherwise returns
// the original parentNode_. If the tree view is showing but nothing is
-// selected then return the root node.
-- (const BookmarkNode*)selectedParentNode;
+// selected then return the root node. This assumes that leaf nodes (pure
+// bookmarks) are not being presented.
+- (const BookmarkNode*)selectedNode;
// Select/highlight the given node within the browser tree view. If the
-// node is not found then the selection will not be changed.
+// node is nil then select the bookmark bar.
- (void)selectNodeInBrowser:(const BookmarkNode*)node;
@end
@@ -131,42 +151,23 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
// Remember the NSBrowser's height; we will shrink our frame by that
// much.
NSRect frame = [[self window] frame];
- CGFloat browserHeight = [browser_ frame].size.height;
+ CGFloat browserHeight = [folderBrowser_ frame].size.height;
frame.size.height -= browserHeight;
frame.origin.y += browserHeight;
// Remove the NSBrowser and "new folder" button.
- [browser_ removeFromSuperview];
+ [folderBrowser_ removeFromSuperview];
[newFolderButton_ removeFromSuperview];
// Finally, commit the size change.
[[self window] setFrame:frame display:YES];
}
-}
-- (void)selectNodeInBrowser:(const BookmarkNode*)node {
- DCHECK(configuration_ == BookmarkEditor::SHOW_TREE);
- // Find and select the node in the browser by walking
- // back to the root node, then selecting forward.
- std::deque<NSInteger> rowsToSelect;
- const BookmarkNode* nodeParent = node->GetParent();
- // There should always be a parent node.
- DCHECK(nodeParent);
- while (nodeParent) {
- int nodeRow = IndexOfFolderChild(node);
- rowsToSelect.push_front(nodeRow);
- node = nodeParent;
- nodeParent = nodeParent->GetParent();
- }
- for (std::deque<NSInteger>::size_type column = 0;
- column < rowsToSelect.size();
- ++column) {
- [browser_ selectRow:rowsToSelect[column] inColumn:column];
- }
- [self controlTextDidChange:nil];
+ [folderBrowser_ setCellClass:[BookmarkTreeBrowserCell class]];
+ [folderBrowser_ setDoubleAction:@selector(browserDoubleClicked:)];
}
- (void)windowDidLoad {
if (configuration_ == BookmarkEditor::SHOW_TREE) {
- // Find and select the |parent| bookmark node.
+ // Find and select the |parent| bookmark node in the folder tree browser.
[self selectNodeInBrowser:parentNode_];
}
}
@@ -191,45 +192,124 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
contextInfo:nil];
}
-// TODO(jrg)
-- (IBAction)newFolder:(id)sender {
- NOTIMPLEMENTED();
-}
-
-- (IBAction)cancel:(id)sender {
- [NSApp endSheet:[self window]];
-}
-
-// If possible, return a valid GURL from the URL text field.
-- (GURL)GURLFromUrlField {
- NSString* url = [urlField_ stringValue];
- GURL newURL = GURL([url UTF8String]);
- if (!newURL.is_valid()) {
- // Mimic observed friendliness from Windows
- newURL = GURL([[NSString stringWithFormat:@"http://%@", url] UTF8String]);
+- (void)selectNodeInBrowser:(const BookmarkNode*)node {
+ DCHECK(configuration_ == BookmarkEditor::SHOW_TREE);
+ std::deque<NSInteger> rowsToSelect;
+ const BookmarkNode* nodeParent = nil;
+ if (node) {
+ nodeParent = node->GetParent();
+ // There should always be a parent node.
+ DCHECK(nodeParent);
+ while (nodeParent) {
+ int nodeRow = IndexOfFolderChild(node);
+ rowsToSelect.push_front(nodeRow);
+ node = nodeParent;
+ nodeParent = nodeParent->GetParent();
+ }
+ } else {
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ nodeParent = model->GetBookmarkBarNode();
+ rowsToSelect.push_front(0);
}
- return newURL;
+ for (std::deque<NSInteger>::size_type column = 0;
+ column < rowsToSelect.size();
+ ++column) {
+ [folderBrowser_ selectRow:rowsToSelect[column] inColumn:column];
+ }
+ [self controlTextDidChange:nil];
}
-- (const BookmarkNode*)selectedParentNode {
+- (const BookmarkNode*)selectedNode {
BookmarkModel* model = profile_->GetBookmarkModel();
- const BookmarkNode* selectedParentNode = NULL;
+ const BookmarkNode* selectedNode = NULL;
// Determine a new parent node only if the browser is showing.
if (configuration_ == BookmarkEditor::SHOW_TREE) {
- selectedParentNode = model->root_node();
+ selectedNode = model->root_node();
NSInteger column = 0;
- NSInteger selectedRow = [browser_ selectedRowInColumn:column];
+ NSInteger selectedRow = [folderBrowser_ selectedRowInColumn:column];
while (selectedRow >= 0) {
- selectedParentNode = GetFolderChildForParent(selectedParentNode,
- selectedRow);
+ selectedNode = GetFolderChildForParent(selectedNode,
+ selectedRow);
++column;
- selectedRow = [browser_ selectedRowInColumn:column];
+ selectedRow = [folderBrowser_ selectedRowInColumn:column];
}
} else {
// If the tree is not showing then we use the original parent.
- selectedParentNode = parentNode_;
+ selectedNode = parentNode_;
}
- return selectedParentNode;
+ return selectedNode;
+}
+
+#pragma mark New Folder Handler & Folder Cell Editing
+
+- (void)editFolderNameInCell:(BookmarkTreeBrowserCell*)cell {
+ DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
+ [cell setEditable:YES];
+ [cell setTarget:self];
+ [cell setAction:@selector(cellEditingCompleted:)];
+ [cell setSendsActionOnEndEditing:YES];
+ currentEditCell_.reset([cell retain]);
+ NSMatrix* matrix = [cell matrix];
+ // Set the delegate so that we get called when editing wants to complete.
+ [matrix setDelegate:self];
+ [matrix selectText:self];
+}
+
+- (void)cellEditingCompleted:(id)sender {
+ DCHECK([sender isKindOfClass:[NSMatrix class]]);
+ BookmarkTreeBrowserCell* cell = [sender selectedCell];
+ DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
+ [self saveFolderNameForCell:cell];
+}
+
+- (void)saveFolderNameForCell:(BookmarkTreeBrowserCell*)cell {
+ DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
+ // It's possible that the cell can get reused so clean things up
+ // to prevent inadvertant notifications.
+ [cell setTarget:nil];
+ [cell setAction:nil];
+ [cell setEditable:NO];
+ [cell setSendsActionOnEndEditing:NO];
+ // Force a responder change here to force the editing of the cell's text
+ // to complete otherwise the call to -[cell title] could return stale text.
+ [[folderBrowser_ window] makeFirstResponder:folderBrowser_];
+ const BookmarkNode* bookmarkNode = [cell bookmarkNode];
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ NSString* newTitle = [cell title];
+ model->SetTitle(bookmarkNode, base::SysNSStringToWide(newTitle));
+ currentEditCell_.reset();
+}
+
+- (void)browserDoubleClicked:(id)sender {
+ BookmarkTreeBrowserCell* cell = [folderBrowser_ selectedCell];
+ DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
+ [self editFolderNameInCell:cell];
+}
+
+- (IBAction)newFolder:(id)sender {
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ const BookmarkNode* newParentNode = [self selectedNode];
+ int newIndex = newParentNode->GetChildCount();
+ std::wstring newFolderString =
+ l10n_util::GetString(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
+ const BookmarkNode* newFolder = model->AddGroup(newParentNode, newIndex,
+ newFolderString);
+ [self selectNodeInBrowser:newFolder];
+ BookmarkTreeBrowserCell* cell = [folderBrowser_ selectedCell];
+ [self editFolderNameInCell:cell];
+}
+
+#pragma mark Bookmark Editing
+
+// If possible, return a valid GURL from the URL text field.
+- (GURL)GURLFromUrlField {
+ NSString* url = [urlField_ stringValue];
+ GURL newURL = GURL([url UTF8String]);
+ if (!newURL.is_valid()) {
+ // Mimic observed friendliness from Windows
+ newURL = GURL([[NSString stringWithFormat:@"http://%@", url] UTF8String]);
+ }
+ return newURL;
}
// Enable the OK button if there is a bookmark name and there is a valid URL.
@@ -261,7 +341,7 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
}
// Determine where the new/replacement bookmark is to go.
- const BookmarkNode* newParentNode = [self selectedParentNode];
+ const BookmarkNode* newParentNode = [self selectedNode];
BookmarkModel* model = profile_->GetBookmarkModel();
int newIndex = newParentNode->GetChildCount();
if (node_ && parentNode_) {
@@ -281,9 +361,20 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
[NSApp endSheet:[self window]];
}
+- (IBAction)cancel:(id)sender {
+ [NSApp endSheet:[self window]];
+}
+
- (void)didEndSheet:(NSWindow*)sheet
returnCode:(int)returnCode
contextInfo:(void*)contextInfo {
+ // If a folder name cell is being edited then force it to end editing
+ // so that any changes are recorded.
+ BookmarkTreeBrowserCell* currentEditCell = currentEditCell_.get();
+ if (currentEditCell) {
+ [self saveFolderNameForCell:currentEditCell];
+ currentEditCell_.reset();
+ }
// This is probably unnecessary but it feels cleaner since the
// delegate of a text field can be automatically registered for
// notifications.
@@ -336,8 +427,8 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
BookmarkModel* model = profile_->GetBookmarkModel();
const BookmarkNode* node = model->root_node();
for (NSInteger i = 0; i < column; ++i) {
- NSInteger selectedRowInColumn = [browser_ selectedRowInColumn:i];
- node = node->GetChild(selectedRowInColumn);
+ NSInteger selectedRowInColumn = [folderBrowser_ selectedRowInColumn:i];
+ node = GetFolderChildForParent(node, selectedRowInColumn);
}
return node;
}
@@ -363,14 +454,18 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
- (void)browser:(NSBrowser*)sender
willDisplayCell:(NSBrowserCell*)cell
atRow:(NSInteger)row
- column:(NSInteger)column {
+ column:(NSInteger)column {
DCHECK(row >= 0); // Trust AppKit, but verify.
DCHECK(column >= 0);
+ DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
const BookmarkNode* parentNode = [self parentNodeForColumn:column];
const BookmarkNode* childNode = GetFolderChildForParent(parentNode, row);
DCHECK(childNode);
- [cell setTitle:base::SysWideToNSString(childNode->GetTitle())];
- [cell setLeaf:childNode->GetChildCount() == 0];
+ BookmarkTreeBrowserCell* browserCell =
+ static_cast<BookmarkTreeBrowserCell*>(cell);
+ [browserCell setTitle:base::SysWideToNSString(childNode->GetTitle())];
+ [browserCell setBookmarkNode:childNode];
+ [browserCell setMatrix:[folderBrowser_ matrixInColumn:column]];
}
@end // BookmarkEditorController
diff --git a/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
index 79a3142..0e1e9b2 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
@@ -255,8 +255,6 @@ TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) {
[default_controller_ setDisplayName:@"NEW NAME"];
[default_controller_ ok:nil];
const BookmarkNode* newParent = bookmark_bb_3_->GetParent();
- std::cout << "oldParent: " << oldParent->GetTitle() << "\r";
- std::cout << "newParent: " << newParent->GetTitle() << "\r";
ASSERT_EQ(newParent, oldParent);
int childIndex = newParent->IndexOfChild(bookmark_bb_3_);
ASSERT_EQ(3, childIndex);
@@ -292,6 +290,14 @@ TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkGroup) {
EXPECT_EQ(bookmark_bb_3_->GetTitle(), L"NEW NAME");
}
+TEST_F(BookmarkEditorControllerTreeTest, AddFolderWithGroupSelected) {
+ [default_controller_ newFolder:nil];
+ [default_controller_ cancel:nil];
+ EXPECT_EQ(6, group_bb_->GetChildCount());
+ const BookmarkNode* folderChild = group_bb_->GetChild(5);
+ EXPECT_EQ(folderChild->GetTitle(), L"New folder");
+}
+
class BookmarkEditorControllerTreeNoNodeTest :
public BookmarkEditorControllerTreeTest {
public:
@@ -318,3 +324,29 @@ TEST_F(BookmarkEditorControllerTreeNoNodeTest, NewBookmarkNoNode) {
EXPECT_EQ(new_node->GetURL(), GURL("http://NEWURL.com"));
}
+class BookmarkEditorControllerTreeNoParentTest :
+ public BookmarkEditorControllerTreeTest {
+ public:
+ BookmarkEditorControllerTreeNoParentTest() {
+ // Reset the controller so that we have no |node|.
+ default_controller_.reset([[BookmarkEditorController alloc]
+ initWithParentWindow:cocoa_helper_.window()
+ profile:helper_.profile()
+ parent:nil
+ node:nil
+ configuration:BookmarkEditor::SHOW_TREE
+ handler:nil]);
+ [default_controller_ window]; // Forces a nib load
+ }
+};
+
+TEST_F(BookmarkEditorControllerTreeNoParentTest, AddFolderWithNoGroupSelected) {
+ [default_controller_ newFolder:nil];
+ [default_controller_ cancel:nil];
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+ const BookmarkNode* bookmarkBar = model->GetBookmarkBarNode();
+ EXPECT_EQ(5, bookmarkBar->GetChildCount());
+ const BookmarkNode* folderChild = bookmarkBar->GetChild(4);
+ EXPECT_EQ(folderChild->GetTitle(), L"New folder");
+}
+
diff --git a/chrome/browser/cocoa/bookmark_tree_browser_cell.h b/chrome/browser/cocoa/bookmark_tree_browser_cell.h
new file mode 100644
index 0000000..acdc5cb
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_tree_browser_cell.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef CHROME_BROWSER_COCOA_BOOKMARK_TREE_BROWSER_CELL_H_
+#define CHROME_BROWSER_COCOA_BOOKMARK_TREE_BROWSER_CELL_H_
+
+#import <Cocoa/Cocoa.h>
+
+class BookmarkNode;
+
+// Provides a custom cell as used in the BookmarkEditor.xib's folder tree
+// browser view. This cell customization adds target and action support
+// not provided by the NSBrowserCell as well as contextual information
+// identifying the bookmark node being edited and the column matrix
+// control in which is contained the cell.
+@interface BookmarkTreeBrowserCell : NSBrowserCell {
+ @private
+ const BookmarkNode* bookmarkNode_; // weak
+ NSMatrix* matrix_; // weak
+ id target_; // weak
+ SEL action_;
+}
+
+@property (assign) NSMatrix* matrix;
+@property (assign) id target;
+@property (assign) SEL action;
+
+- (const BookmarkNode*)bookmarkNode;
+- (void)setBookmarkNode:(const BookmarkNode*)bookmarkNode;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_BOOKMARK_TREE_BROWSER_CELL_H_
diff --git a/chrome/browser/cocoa/bookmark_tree_browser_cell.mm b/chrome/browser/cocoa/bookmark_tree_browser_cell.mm
new file mode 100644
index 0000000..27801e1
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_tree_browser_cell.mm
@@ -0,0 +1,22 @@
+// 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.
+
+#import "chrome/browser/cocoa/bookmark_tree_browser_cell.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+
+@implementation BookmarkTreeBrowserCell
+
+@synthesize matrix = matrix_;
+@synthesize target = target_;
+@synthesize action = action_;
+
+- (const BookmarkNode*)bookmarkNode {
+ return bookmarkNode_;
+}
+
+- (void)setBookmarkNode:(const BookmarkNode*)bookmarkNode {
+ bookmarkNode_ = bookmarkNode;
+}
+
+@end
diff --git a/chrome/browser/cocoa/bookmark_tree_browser_cell_unittest.mm b/chrome/browser/cocoa/bookmark_tree_browser_cell_unittest.mm
new file mode 100644
index 0000000..82fe455
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_tree_browser_cell_unittest.mm
@@ -0,0 +1,43 @@
+// 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#import "chrome/browser/cocoa/bookmark_tree_browser_cell.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/platform_test.h"
+
+class BookmarkTreeBrowserCellTest : public PlatformTest {
+ public:
+ BookmarkTreeBrowserCellTest() {
+ // Set up our mocks.
+ GURL gurl;
+ bookmarkNodeMock_.reset(new BookmarkNode(gurl));
+ matrixMock_.reset([[NSMatrix alloc] init]);
+ targetMock_.reset([[NSObject alloc] init]);
+ }
+
+ scoped_ptr<BookmarkNode> bookmarkNodeMock_;
+ scoped_nsobject<NSMatrix> matrixMock_;
+ scoped_nsobject<NSObject> targetMock_;
+};
+
+TEST_F(BookmarkTreeBrowserCellTest, BasicAllocDealloc) {
+ BookmarkTreeBrowserCell* cell = [[[BookmarkTreeBrowserCell alloc]
+ initTextCell:@"TEST STRING"] autorelease];
+ [cell setMatrix:matrixMock_.get()];
+ [cell setTarget:targetMock_.get()];
+ [cell setAction:@selector(mockAction:)];
+ [cell setBookmarkNode:bookmarkNodeMock_.get()];
+
+ NSMatrix* testMatrix = [cell matrix];
+ EXPECT_EQ(testMatrix, matrixMock_.get());
+ id testTarget = [cell target];
+ EXPECT_EQ(testTarget, targetMock_.get());
+ SEL testAction = [cell action];
+ EXPECT_EQ(testAction, @selector(mockAction:));
+ const BookmarkNode* testBookmarkNode = [cell bookmarkNode];
+ EXPECT_EQ(testBookmarkNode, bookmarkNodeMock_.get());
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 278fd06..255c6fc 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1060,6 +1060,8 @@
'browser/cocoa/bookmark_menu_cocoa_controller.mm',
'browser/cocoa/bookmark_name_folder_controller.h',
'browser/cocoa/bookmark_name_folder_controller.mm',
+ 'browser/cocoa/bookmark_tree_browser_cell.h',
+ 'browser/cocoa/bookmark_tree_browser_cell.mm',
'browser/cocoa/browser_test_helper.h',
'browser/cocoa/browser_frame_view.h',
'browser/cocoa/browser_frame_view.mm',
@@ -4452,6 +4454,7 @@
'browser/cocoa/bookmark_menu_bridge_unittest.mm',
'browser/cocoa/bookmark_menu_cocoa_controller_unittest.mm',
'browser/cocoa/bookmark_name_folder_controller_unittest.mm',
+ 'browser/cocoa/bookmark_tree_browser_cell_unittest.mm',
'browser/cocoa/browser_frame_view_unittest.mm',
'browser/cocoa/browser_window_cocoa_unittest.mm',
'browser/cocoa/browser_window_controller_unittest.mm',