summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/bookmark_all_tabs_controller.h5
-rw-r--r--chrome/browser/cocoa/bookmark_all_tabs_controller.mm19
-rw-r--r--chrome/browser/cocoa/bookmark_all_tabs_controller_unittest.mm5
-rw-r--r--chrome/browser/cocoa/bookmark_editor_base_controller.h102
-rw-r--r--chrome/browser/cocoa/bookmark_editor_base_controller.mm507
-rw-r--r--chrome/browser/cocoa/bookmark_editor_base_controller_unittest.mm69
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.h5
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.mm13
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller_unittest.mm267
9 files changed, 585 insertions, 407 deletions
diff --git a/chrome/browser/cocoa/bookmark_all_tabs_controller.h b/chrome/browser/cocoa/bookmark_all_tabs_controller.h
index e861c50..8d2d2b9 100644
--- a/chrome/browser/cocoa/bookmark_all_tabs_controller.h
+++ b/chrome/browser/cocoa/bookmark_all_tabs_controller.h
@@ -15,8 +15,9 @@
typedef std::pair<std::wstring, GURL> ActiveTabNameURLPair;
typedef std::vector<ActiveTabNameURLPair> ActiveTabsNameURLPairVector;
-// A controller for the bookmark editor, opened with Edit... from the
-// context menu of a bookmark button.
+// A controller for the Bookmark All Tabs sheet which is presented upon
+// selecting the Bookmark All Tabs... menu item shown by the contextual
+// menu in the bookmarks bar.
@interface BookmarkAllTabsController : BookmarkEditorBaseController {
@private
ActiveTabsNameURLPairVector activeTabPairsVector_;
diff --git a/chrome/browser/cocoa/bookmark_all_tabs_controller.mm b/chrome/browser/cocoa/bookmark_all_tabs_controller.mm
index 93b4026..8c2e236 100644
--- a/chrome/browser/cocoa/bookmark_all_tabs_controller.mm
+++ b/chrome/browser/cocoa/bookmark_all_tabs_controller.mm
@@ -30,9 +30,8 @@
}
- (void)awakeFromNib {
- [self
- setInitialName:
- l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME)];
+ [self setInitialName:
+ l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME)];
[super awakeFromNib];
}
@@ -52,10 +51,10 @@
}
}
-// The the name for the folder into which the tabs will be recorded as
-// bookmarks is assumed to be non-empty. The folder is then created
-// and a bookmark for each open tab added therein.
-- (IBAction)ok:(id)sender {
+// Called by -[BookmarkEditorBaseController ok:]. Creates the container
+// folder for the tabs and then the bookmarks in that new folder.
+// Returns a BOOL as an NSNumber indicating that the commit may proceed.
+- (NSNumber*)didCommit {
NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
std::wstring newTitle = base::SysNSStringToWide(name);
@@ -67,7 +66,7 @@
BookmarkModel* model = [self bookmarkModel];
const BookmarkNode* newFolder = model->AddGroup(newParentNode, newIndex,
newFolderString);
- [self NotifyHandlerCreatedNode:newFolder];
+ [self notifyHandlerCreatedNode:newFolder];
// Get a list of all open tabs, create nodes for them, and add
// to the new folder node.
[self UpdateActiveTabPairs];
@@ -77,9 +76,9 @@
it != activeTabPairsVector_.end(); ++it, ++i) {
const BookmarkNode* node = model->AddURL(newFolder, i,
it->first, it->second);
- [self NotifyHandlerCreatedNode:node];
+ [self notifyHandlerCreatedNode:node];
}
- [super ok:sender];
+ return [NSNumber numberWithBool:YES];
}
- (ActiveTabsNameURLPairVector*)activeTabPairsVector {
diff --git a/chrome/browser/cocoa/bookmark_all_tabs_controller_unittest.mm b/chrome/browser/cocoa/bookmark_all_tabs_controller_unittest.mm
index 1d0a724..118a554 100644
--- a/chrome/browser/cocoa/bookmark_all_tabs_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_all_tabs_controller_unittest.mm
@@ -59,11 +59,11 @@ class BookmarkAllTabsControllerTest : public CocoaTest {
virtual void SetUp() {
CocoaTest::SetUp();
controller_ = CreateController();
- EXPECT_TRUE([controller_ window]);
+ [controller_ runAsModalSheet];
}
virtual void TearDown() {
- [controller_ close];
+ controller_ = NULL;
CocoaTest::TearDown();
}
};
@@ -71,6 +71,7 @@ class BookmarkAllTabsControllerTest : public CocoaTest {
TEST_F(BookmarkAllTabsControllerTest, BookmarkAllTabs) {
// OK button should always be enabled.
EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ selectTestNodeInBrowser:group_a_];
[controller_ setDisplayName:@"ALL MY TABS"];
[controller_ ok:nil];
EXPECT_EQ(4, group_a_->GetChildCount());
diff --git a/chrome/browser/cocoa/bookmark_editor_base_controller.h b/chrome/browser/cocoa/bookmark_editor_base_controller.h
index cb0725d..265289f 100644
--- a/chrome/browser/cocoa/bookmark_editor_base_controller.h
+++ b/chrome/browser/cocoa/bookmark_editor_base_controller.h
@@ -12,23 +12,23 @@
#include "base/scoped_nsobject.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
-@class BookmarkTreeBrowserCell;
class BookmarkModel;
+@class BookmarkTreeBrowserCell;
// A base controller class for bookmark creation and editing dialogs which
// present the current bookmark folder structure in a tree view. Do not
// instantiate this controller directly -- use one of its derived classes.
-// NOTE: If your derived classes is intended to be dispatched via the
+// NOTE: If a derived class is intended to be dispatched via the
// BookmarkEditor::Show static function found in the accompanying
-// implementation will need to update that function.
-@interface BookmarkEditorBaseController :
- NSWindowController<NSMatrixDelegate, NSTextFieldDelegate> {
+// implementation, that function will need to be update.
+@interface BookmarkEditorBaseController : NSWindowController {
@private
- IBOutlet NSBrowser* folderBrowser_;
IBOutlet NSButton* newFolderButton_;
IBOutlet NSButton* okButton_; // Used for unit testing only.
+ IBOutlet NSTreeController* folderTreeController_;
+ IBOutlet NSOutlineView* folderTreeView_;
- NSWindow* parentWindow_;
+ NSWindow* parentWindow_; // weak
Profile* profile_; // weak
const BookmarkNode* parentNode_; // weak; owned by the model
BookmarkEditor::Configuration configuration_;
@@ -36,11 +36,19 @@ class BookmarkModel;
NSString* initialName_;
NSString* displayName_; // Bound to a text field in the dialog.
BOOL okEnabled_; // Bound to the OK button.
+ // An array of BookmarkFolderInfo where each item describes a folder in the
+ // BookmarkNode structure.
+ scoped_nsobject<NSArray> folderTreeArray_;
+ // Bound to the table view giving a path to the current selections, of which
+ // there should only ever be one.
+ scoped_nsobject<NSArray> tableSelectionPaths_;
}
@property (copy) NSString* initialName;
@property (copy) NSString* displayName;
@property (assign) BOOL okEnabled;
+@property (retain, readonly) NSArray* folderTreeArray;
+@property (copy) NSArray* tableSelectionPaths;
// Designated initializer. Derived classes should call through to this init.
- (id)initWithParentWindow:(NSWindow*)parentWindow
@@ -57,11 +65,22 @@ class BookmarkModel;
// an untitled name, and put it into editing mode.
- (IBAction)newFolder:(id)sender;
-// Actions for the buttons at the bottom of the window.
+// The cancel action will dismiss the dialog. Derived classes which
+// override cancel:, must call this after accessing any dialog-related
+// data.
- (IBAction)cancel:(id)sender;
-// The OK action will record the edited bookmark. The default dismisses
-// the dialog and should be called by the derived class if overridden.
+// The OK action will dismiss the dialog. This action is bound
+// to the OK button of a dialog which presents a tree view of a profile's
+// folder hierarchy and allows the creation of new folders within that tree.
+// When the OK button is pressed, this function will: 1) call the derived
+// class's -[willCommit] function, 2) create any new folders created by
+// the user while the dialog is presented, 3) call the derived class's
+// -[didCommit] function, and then 4) dismiss the dialog. At least one
+// of -[willCommit] and -[didCommit] must be provided by the derived class
+// and should return a NSNumber containing a BOOL or nil ('nil' means YES)
+// indicating if the operation should be allowed to continue.
+// Note: A derived class should not override the ok: action.
- (IBAction)ok:(id)sender;
// Methods for use by derived classes only.
@@ -69,8 +88,7 @@ class BookmarkModel;
// 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. This assumes that leaf nodes (pure
-// bookmarks) are not being presented.
+// selected then the root node is returned.
- (const BookmarkNode*)selectedNode;
// Select/highlight the given node within the browser tree view. If the
@@ -78,7 +96,7 @@ class BookmarkModel;
- (void)selectNodeInBrowser:(const BookmarkNode*)node;
// Notify the handler, if any, of a node creation.
-- (void)NotifyHandlerCreatedNode:(const BookmarkNode*)node;
+- (void)notifyHandlerCreatedNode:(const BookmarkNode*)node;
// Accessors
- (BookmarkModel*)bookmarkModel;
@@ -86,12 +104,64 @@ class BookmarkModel;
@end
+// Describes the profile's bookmark folder structure: the folder name, the
+// original BookmarkNode pointer (if the folder already exists), a BOOL
+// indicating if the folder is new (meaning: created during this session
+// but not yet committed to the bookmark structure), and an NSArray of
+// child folder BookmarkFolderInfo's following this same structure.
+@interface BookmarkFolderInfo : NSObject {
+ @private
+ NSString* folderName_;
+ const BookmarkNode* folderNode_; // weak
+ NSMutableArray* children_;
+ BOOL newFolder_;
+}
+
+@property (copy, readwrite) NSString* folderName;
+@property (assign, readwrite) const BookmarkNode* folderNode;
+@property (retain, readwrite) NSMutableArray* children;
+@property (assign, readwrite) BOOL newFolder;
+
+// Convenience creator for adding a new folder to the editor's bookmark
+// structure. This folder will be added to the bookmark model when the
+// user accepts the dialog. |folderName| must be provided.
++ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName;
+
+// Designated initializer. |folderName| must be provided. For folders which
+// already exist in the bookmark model, |folderNode| and |children| (if any
+// children are already attached to this folder) must be provided and
+// |newFolder| should be NO. For folders which the user has added during
+// this session and which have not been committed yet, |newFolder| should be
+// YES and |folderNode| and |children| should be NULL/nil.
+- (id)initWithFolderName:(NSString*)folderName
+ folderNode:(const BookmarkNode*)folderNode
+ children:(NSMutableArray*)children
+ newFolder:(BOOL)newFolder;
+
+// Convenience creator used during construction of the editor's bookmark
+// structure. |folderName| and |folderNode| must be provided. |children|
+// is optional. Private: exposed here for unit testing purposes.
++ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName
+ folderNode:(const BookmarkNode*)folderNode
+ children:(NSMutableArray*)children;
+
+@end
+
@interface BookmarkEditorBaseController(TestingAPI)
+
@property (readonly) BOOL okButtonEnabled;
+
+// Create any newly added folders. New folders are nodes in folderTreeArray
+// which are marked as being new (i.e. their kFolderTreeNewFolderKey
+// dictionary item is YES). This is called by -[ok:].
+- (void)createNewFolders;
+
+// Select the given bookmark node within the tree view.
- (void)selectTestNodeInBrowser:(const BookmarkNode*)node;
-+ (const BookmarkNode*)folderChildForParent:(const BookmarkNode*)parent
- withFolderIndex:(NSInteger)index;
-+ (int)indexOfFolderChild:(const BookmarkNode*)child;
+
+// Return the dictionary for the folder selected in the tree.
+- (BookmarkFolderInfo*)selectedFolder;
+
@end
#endif /* CHROME_BROWSER_COCOA_BOOKMARK_EDITOR_BASE_CONTROLLER_H_ */
diff --git a/chrome/browser/cocoa/bookmark_editor_base_controller.mm b/chrome/browser/cocoa/bookmark_editor_base_controller.mm
index d97874a..59b8913 100644
--- a/chrome/browser/cocoa/bookmark_editor_base_controller.mm
+++ b/chrome/browser/cocoa/bookmark_editor_base_controller.mm
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stack>
+
#import "chrome/browser/cocoa/bookmark_editor_base_controller.h"
#include "app/l10n_util.h"
+#include "app/l10n_util_mac.h"
#include "base/logging.h"
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
@@ -16,25 +19,27 @@
@interface BookmarkEditorBaseController (Private)
-// 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;
+@property (retain, readwrite) NSArray* folderTreeArray;
+
+// Return the folder tree object for the given path.
+- (BookmarkFolderInfo*)folderForIndexPath:(NSIndexPath*)path;
-// 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;
+// Given a folder node, collect an array containing BookmarkFolderInfos
+// describing its subchildren which are also folders.
+- (NSMutableArray*)addChildFoldersFromNode:(const BookmarkNode*)node;
-// 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;
+// Scan the folder tree stemming from the given tree folder and create
+// any newly added folders.
+- (void)createNewFoldersForFolder:(BookmarkFolderInfo*)treeFolder;
-// A custom action handler called by the bookmark folder browser when the
-// user has double-clicked on a folder name.
-- (void)browserDoubleClicked:(id)sender;
+// Scan the folder tree looking for the given bookmark node and return
+// the selection path thereto.
+- (NSIndexPath*)selectionPathForNode:(const BookmarkNode*)node;
@end
-// static; implemented for each platform.
+// static; implemented for each platform. Update this function for new
+// classes derived from BookmarkEditorBaseController.
void BookmarkEditor::Show(gfx::NativeWindow parent_hwnd,
Profile* profile,
const BookmarkNode* parent,
@@ -61,40 +66,6 @@ void BookmarkEditor::Show(gfx::NativeWindow parent_hwnd,
[controller runAsModalSheet];
}
-#pragma mark Bookmark TreeNode Helpers
-
-namespace {
-
-// Find the index'th folder child of a parent, ignoring bookmarks (leafs).
-const BookmarkNode* GetFolderChildForParent(const BookmarkNode* parent_node,
- NSInteger folder_index) {
- const BookmarkNode* child_node = nil;
- int i = 0;
- int child_count = parent_node->GetChildCount();
- do {
- child_node = parent_node->GetChild(i);
- if (child_node->type() != BookmarkNode::URL)
- --folder_index;
- ++i;
- } while (folder_index >= 0 && i < child_count);
- return child_node;
-}
-
-// Determine the index of a child within its parent ignoring
-// bookmarks (leafs).
-int IndexOfFolderChild(const BookmarkNode* child_node) {
- const BookmarkNode* node_parent = child_node->GetParent();
- int child_index = node_parent->IndexOfChild(child_node);
- for (int i = child_index - 1; i >= 0; --i) {
- const BookmarkNode* sibling = node_parent->GetChild(i);
- if (sibling->type() == BookmarkNode::URL)
- --child_index;
- }
- return child_index;
-}
-
-} // namespace
-
@implementation BookmarkEditorBaseController
@synthesize initialName = initialName_;
@@ -131,21 +102,24 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
[self setDisplayName:[self initialName]];
if (configuration_ != BookmarkEditor::SHOW_TREE) {
- // Remember the NSBrowser's height; we will shrink our frame by that
- // much.
+ // Remember the tree view's height; we will shrink our frame by that much.
NSRect frame = [[self window] frame];
- CGFloat browserHeight = [folderBrowser_ frame].size.height;
+ CGFloat browserHeight = [folderTreeView_ frame].size.height;
frame.size.height -= browserHeight;
frame.origin.y += browserHeight;
- // Remove the NSBrowser and "new folder" button.
- [folderBrowser_ removeFromSuperview];
+ // Remove the folder tree and "new folder" button.
+ [folderTreeView_ removeFromSuperview];
[newFolderButton_ removeFromSuperview];
// Finally, commit the size change.
[[self window] setFrame:frame display:YES];
}
- [folderBrowser_ setCellClass:[BookmarkTreeBrowserCell class]];
- [folderBrowser_ setDoubleAction:@selector(browserDoubleClicked:)];
+ // Build up a tree of the current folder configuration.
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ const BookmarkNode* rootNode = model->root_node();
+ NSMutableArray* baseArray = [self addChildFoldersFromNode:rootNode];
+ DCHECK(baseArray);
+ [self setFolderTreeArray:baseArray];
}
- (void)windowDidLoad {
@@ -154,13 +128,6 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
}
}
-- (void)windowWillClose:(NSNotification *)notification {
- // If a folder name cell is being edited then force it to end editing
- // so that any changes are recorded.
- [[self window] makeFirstResponder:nil];
- [self autorelease];
-}
-
/* TODO(jrg):
// Implementing this informal protocol allows us to open the sheet
// somewhere other than at the top of the window. NOTE: this means
@@ -181,50 +148,93 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
contextInfo:nil];
}
-- (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);
+- (BOOL)okEnabled {
+ return YES;
+}
+
+- (IBAction)ok:(id)sender {
+ // At least one of these two functions should be provided by derived classes.
+ BOOL hasWillCommit = [self respondsToSelector:@selector(willCommit)];
+ BOOL hasDidCommit = [self respondsToSelector:@selector(didCommit)];
+ DCHECK(hasWillCommit || hasDidCommit);
+ BOOL shouldContinue = YES;
+ if (hasWillCommit) {
+ NSNumber* hasWillContinue = [self performSelector:@selector(willCommit)];
+ if (hasWillContinue && [hasWillContinue isKindOfClass:[NSNumber class]])
+ shouldContinue = [hasWillContinue boolValue];
}
- for (std::deque<NSInteger>::size_type column = 0;
- column < rowsToSelect.size();
- ++column) {
- [folderBrowser_ selectRow:rowsToSelect[column] inColumn:column];
+ if (shouldContinue)
+ [self createNewFolders];
+ if (hasDidCommit) {
+ NSNumber* hasDidContinue = [self performSelector:@selector(didCommit)];
+ if (hasDidContinue && [hasDidContinue isKindOfClass:[NSNumber class]])
+ shouldContinue = [hasDidContinue boolValue];
}
+ if (shouldContinue)
+ [NSApp endSheet:[self window]];
+}
- // Force the OK button state to be re-evaluated.
- [self willChangeValueForKey:@"okEnabled"];
- [self didChangeValueForKey:@"okEnabled"];
+- (IBAction)cancel:(id)sender {
+ [NSApp endSheet:[self window]];
+}
+
+- (void)didEndSheet:(NSWindow*)sheet
+ returnCode:(int)returnCode
+ contextInfo:(void*)contextInfo {
+ [sheet close];
+}
+
+- (void)windowWillClose:(NSNotification*)notification {
+ [self autorelease];
+}
+
+#pragma mark Folder Tree Management
+
+- (BookmarkModel*)bookmarkModel {
+ return profile_->GetBookmarkModel();
+}
+
+- (const BookmarkNode*)parentNode {
+ return parentNode_;
+}
+
+- (BookmarkFolderInfo*)folderForIndexPath:(NSIndexPath*)indexPath {
+ NSUInteger pathCount = [indexPath length];
+ BookmarkFolderInfo* item = nil;
+ NSArray* treeNode = [self folderTreeArray];
+ for (NSUInteger i = 0; i < pathCount; ++i) {
+ item = [treeNode objectAtIndex:[indexPath indexAtPosition:i]];
+ treeNode = [item children];
+ }
+ return item;
+}
+
+- (NSIndexPath*)selectedIndexPath {
+ NSIndexPath* selectedIndexPath = nil;
+ NSArray* selections = [self tableSelectionPaths];
+ if ([selections count]) {
+ DCHECK([selections count] == 1); // Should be exactly one selection.
+ selectedIndexPath = [selections objectAtIndex:0];
+ }
+ return selectedIndexPath;
+}
+
+- (BookmarkFolderInfo*)selectedFolder {
+ BookmarkFolderInfo* item = nil;
+ NSIndexPath* selectedIndexPath = [self selectedIndexPath];
+ if (selectedIndexPath) {
+ item = [self folderForIndexPath:selectedIndexPath];
+ }
+ return item;
}
- (const BookmarkNode*)selectedNode {
- BookmarkModel* model = profile_->GetBookmarkModel();
const BookmarkNode* selectedNode = NULL;
// Determine a new parent node only if the browser is showing.
if (configuration_ == BookmarkEditor::SHOW_TREE) {
- selectedNode = model->root_node();
- NSInteger column = 0;
- NSInteger selectedRow = [folderBrowser_ selectedRowInColumn:column];
- while (selectedRow >= 0) {
- selectedNode = GetFolderChildForParent(selectedNode,
- selectedRow);
- ++column;
- selectedRow = [folderBrowser_ selectedRowInColumn:column];
- }
+ BookmarkFolderInfo* folderInfo = [self selectedFolder];
+ if (folderInfo)
+ selectedNode = [folderInfo folderNode];
} else {
// If the tree is not showing then we use the original parent.
selectedNode = parentNode_;
@@ -232,94 +242,156 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
return selectedNode;
}
-- (void)NotifyHandlerCreatedNode:(const BookmarkNode*)node {
+- (void)notifyHandlerCreatedNode:(const BookmarkNode*)node {
if (handler_.get())
handler_->NodeCreated(node);
}
-#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];
- NSMatrix* matrix = [cell matrix];
- // Set the delegate so that we get called when editing completes.
- [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.
- // The focus does not automatically get reset to the browser when the
- // cell gives up focus.
- [[folderBrowser_ window] makeFirstResponder:folderBrowser_];
- const BookmarkNode* bookmarkNode = [cell bookmarkNode];
- BookmarkModel* model = profile_->GetBookmarkModel();
- NSString* newTitle = [cell title];
- model->SetTitle(bookmarkNode, base::SysNSStringToWide(newTitle));
+- (NSArray*)folderTreeArray {
+ return folderTreeArray_.get();
}
-- (void)browserDoubleClicked:(id)sender {
- BookmarkTreeBrowserCell* cell = [folderBrowser_ selectedCell];
- DCHECK([cell isKindOfClass:[BookmarkTreeBrowserCell class]]);
- [self editFolderNameInCell:cell];
+- (void)setFolderTreeArray:(NSArray*)folderTreeArray {
+ folderTreeArray_.reset([folderTreeArray retain]);
}
-- (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];
+- (NSArray*)tableSelectionPaths {
+ return tableSelectionPaths_.get();
}
-- (BOOL)okEnabled {
- return YES;
+- (void)setTableSelectionPath:(NSIndexPath*)tableSelectionPath {
+ [self setTableSelectionPaths:[NSArray arrayWithObject:tableSelectionPath]];
}
-- (IBAction)ok:(id)sender {
- [NSApp endSheet:[self window]];
+- (void)setTableSelectionPaths:(NSArray*)tableSelectionPaths {
+ tableSelectionPaths_.reset([tableSelectionPaths retain]);
}
-- (IBAction)cancel:(id)sender {
- [NSApp endSheet:[self window]];
+- (void)selectNodeInBrowser:(const BookmarkNode*)node {
+ DCHECK(configuration_ == BookmarkEditor::SHOW_TREE);
+ NSIndexPath* selectionPath = [self selectionPathForNode:node];
+ [self willChangeValueForKey:@"okEnabled"];
+ [self setTableSelectionPath:selectionPath];
+ [self didChangeValueForKey:@"okEnabled"];
}
-- (void)didEndSheet:(NSWindow*)sheet
- returnCode:(int)returnCode
- contextInfo:(void*)contextInfo {
- [sheet close];
+- (NSIndexPath*)selectionPathForNode:(const BookmarkNode*)desiredNode {
+ // Back up the parent chaing for desiredNode, building up a stack
+ // of ancestor nodes. Then crawl down the folderTreeArray looking
+ // for each ancestor in order while building up the selectionPath.
+ std::stack<const BookmarkNode*> nodeStack;
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ const BookmarkNode* rootNode = model->root_node();
+ const BookmarkNode* node = desiredNode;
+ while (node != rootNode) {
+ nodeStack.push(node);
+ node = node->GetParent();
+ }
+ NSUInteger stackSize = nodeStack.size();
+
+ NSIndexPath* path = nil;
+ NSArray* folders = [self folderTreeArray];
+ while (!nodeStack.empty()) {
+ node = nodeStack.top();
+ nodeStack.pop();
+ // Find node in the current folders array.
+ NSUInteger i = 0;
+ for (BookmarkFolderInfo *folderInfo in folders) {
+ const BookmarkNode* testNode = [folderInfo folderNode];
+ if (testNode == node) {
+ path = path ? [path indexPathByAddingIndex:i] :
+ [NSIndexPath indexPathWithIndex:i];
+ folders = [folderInfo children];
+ break;
+ }
+ ++i;
+ }
+ }
+ DCHECK([path length] == stackSize);
+ return path;
}
-- (BookmarkModel*)bookmarkModel {
- return profile_->GetBookmarkModel();
+- (NSMutableArray*)addChildFoldersFromNode:(const BookmarkNode*)node {
+ NSMutableArray* childFolders = nil;
+ int childCount = node->GetChildCount();
+ for (int i = 0; i < childCount; ++i) {
+ const BookmarkNode* childNode = node->GetChild(i);
+ if (childNode->type() != BookmarkNode::URL) {
+ NSString* childName = base::SysWideToNSString(childNode->GetTitle());
+ NSMutableArray* children = [self addChildFoldersFromNode:childNode];
+ BookmarkFolderInfo* folderInfo =
+ [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:childName
+ folderNode:childNode
+ children:children];
+ if (!childFolders)
+ childFolders = [NSMutableArray arrayWithObject:folderInfo];
+ else
+ [childFolders addObject:folderInfo];
+ }
+ }
+ return childFolders;
}
-- (const BookmarkNode*)parentNode {
- return parentNode_;
+#pragma mark New Folder Handler
+
+- (void)createNewFoldersForFolder:(BookmarkFolderInfo*)folderInfo {
+ NSArray* subfolders = [folderInfo children];
+ const BookmarkNode* parentNode = [folderInfo folderNode];
+ DCHECK(parentNode);
+ NSUInteger i = 0;
+ for (BookmarkFolderInfo *subFolderInfo in subfolders) {
+ if ([subFolderInfo newFolder]) {
+ BookmarkModel* model = [self bookmarkModel];
+ const BookmarkNode* newFolder =
+ model->AddGroup(parentNode, i,
+ base::SysNSStringToWide([subFolderInfo folderName]));
+ [self notifyHandlerCreatedNode:newFolder];
+ // Update our dictionary with the actual folder node just created.
+ [subFolderInfo setFolderNode:newFolder];
+ [subFolderInfo setNewFolder:NO];
+ }
+ [self createNewFoldersForFolder:subFolderInfo];
+ ++i;
+ }
+}
+
+- (IBAction)newFolder:(id)sender {
+ // Create a new folder off of the selected folder node.
+ BookmarkFolderInfo* parentInfo = [self selectedFolder];
+ if (parentInfo) {
+ NSIndexPath* selection = [self selectedIndexPath];
+ NSString* newFolderName =
+ l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
+ BookmarkFolderInfo* folderInfo =
+ [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:newFolderName];
+ [self willChangeValueForKey:@"folderTreeArray"];
+ NSMutableArray* children = [parentInfo children];
+ if (children) {
+ [children addObject:folderInfo];
+ } else {
+ children = [NSMutableArray arrayWithObject:folderInfo];
+ [parentInfo setChildren:children];
+ }
+ [self didChangeValueForKey:@"folderTreeArray"];
+
+ // Expose the parent folder children.
+ [folderTreeView_ expandItem:parentInfo];
+
+ // Select the new folder node and put the folder name into edit mode.
+ selection = [selection indexPathByAddingIndex:[children count] - 1];
+ [self setTableSelectionPath:selection];
+ NSInteger row = [folderTreeView_ selectedRow];
+ DCHECK(row >= 0);
+ [folderTreeView_ editColumn:0 row:row withEvent:nil select:YES];
+ }
+}
+
+- (void)createNewFolders {
+ // Scan the tree looking for nodes marked 'newFolder' and create those nodes.
+ NSArray* folderTreeArray = [self folderTreeArray];
+ for (BookmarkFolderInfo *folderInfo in folderTreeArray) {
+ [self createNewFoldersForFolder:folderInfo];
+ }
}
#pragma mark For Unit Test Use Only
@@ -332,67 +404,64 @@ int IndexOfFolderChild(const BookmarkNode* child_node) {
[self selectNodeInBrowser:node];
}
-+ (const BookmarkNode*)folderChildForParent:(const BookmarkNode*)parent
- withFolderIndex:(NSInteger)index {
- return GetFolderChildForParent(parent, index);
-}
+@end // BookmarkEditorBaseController
-+ (int)indexOfFolderChild:(const BookmarkNode*)child {
- return IndexOfFolderChild(child);
+@implementation BookmarkFolderInfo
+
+@synthesize folderName = folderName_;
+@synthesize folderNode = folderNode_;
+@synthesize children = children_;
+@synthesize newFolder = newFolder_;
+
++ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName
+ folderNode:(const BookmarkNode*)folderNode
+ children:(NSMutableArray*)children {
+ return [[[BookmarkFolderInfo alloc] initWithFolderName:folderName
+ folderNode:folderNode
+ children:children
+ newFolder:NO]
+ autorelease];
}
++ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName {
+ return [[[BookmarkFolderInfo alloc] initWithFolderName:folderName
+ folderNode:NULL
+ children:nil
+ newFolder:YES]
+ autorelease];
+}
-#pragma mark NSBrowser delegate methods
-
-// Given a column number, determine the parent bookmark folder node for the
-// bookmarks being shown in that column. This is done by scanning forward
-// from column zero and following the selected row for each column up
-// to the parent of the desired column.
-- (const BookmarkNode*)parentNodeForColumn:(NSInteger)column {
- DCHECK(column >= 0);
- BookmarkModel* model = profile_->GetBookmarkModel();
- const BookmarkNode* node = model->root_node();
- for (NSInteger i = 0; i < column; ++i) {
- NSInteger selectedRowInColumn = [folderBrowser_ selectedRowInColumn:i];
- node = GetFolderChildForParent(node, selectedRowInColumn);
- }
- return node;
-}
-
-// This implementation returns the number of folders contained in the parent
-// folder node for this column.
-// TOTO(mrossetti): Decide if bookmark (i.e. non-folder) nodes should be
-// shown, perhaps in gray.
-- (NSInteger)browser:(NSBrowser*)sender numberOfRowsInColumn:(NSInteger)col {
- NSInteger rowCount = 0;
- const BookmarkNode* parentNode = [self parentNodeForColumn:col];
- if (parentNode) {
- int childCount = parentNode->GetChildCount();
- for (int i = 0; i < childCount; ++i) {
- const BookmarkNode* childNode = parentNode->GetChild(i);
- if (childNode->type() != BookmarkNode::URL)
- ++rowCount;
+- (id)initWithFolderName:(NSString*)folderName
+ folderNode:(const BookmarkNode*)folderNode
+ children:(NSMutableArray*)children
+ newFolder:(BOOL)newFolder {
+ if ((self = [super init])) {
+ // A folderName is always required, and if newFolder is NO then there
+ // should be a folderNode. Children is optional.
+ DCHECK(folderName && (newFolder || folderNode));
+ if (folderName && (newFolder || folderNode)) {
+ folderName_ = [folderName copy];
+ folderNode_ = folderNode;
+ children_ = [children retain];
+ newFolder_ = newFolder;
+ } else {
+ NOTREACHED(); // Invalid init.
+ [self release];
+ self = nil;
}
}
- return rowCount;
-}
-
-- (void)browser:(NSBrowser*)sender
- willDisplayCell:(NSBrowserCell*)cell
- atRow:(NSInteger)row
- 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);
- BookmarkTreeBrowserCell* browserCell =
- static_cast<BookmarkTreeBrowserCell*>(cell);
- [browserCell setTitle:base::SysWideToNSString(childNode->GetTitle())];
- [browserCell setBookmarkNode:childNode];
- [browserCell setMatrix:[folderBrowser_ matrixInColumn:column]];
+ return self;
}
-@end // BookmarkEditorBaseController
+- (id)init {
+ NOTREACHED(); // Should never be called.
+ return [self initWithFolderName:nil folderNode:nil children:nil newFolder:NO];
+}
+
+- (void)dealloc {
+ [folderName_ release];
+ [children_ release];
+ [super dealloc];
+}
+@end
diff --git a/chrome/browser/cocoa/bookmark_editor_base_controller_unittest.mm b/chrome/browser/cocoa/bookmark_editor_base_controller_unittest.mm
index 2bb1fa1..698276e 100644
--- a/chrome/browser/cocoa/bookmark_editor_base_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_editor_base_controller_unittest.mm
@@ -4,18 +4,20 @@
#import <Cocoa/Cocoa.h>
+#include "app/l10n_util_mac.h"
#include "base/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#import "chrome/browser/cocoa/bookmark_editor_controller.h"
#include "chrome/browser/cocoa/browser_test_helper.h"
#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
class BookmarkEditorBaseControllerTest : public CocoaTest {
public:
- BrowserTestHelper helper_;
- BookmarkEditorBaseController* controller_;
+ BrowserTestHelper browser_helper_;
+ BookmarkEditorBaseController* controller_; // weak
const BookmarkNode* group_a_;
const BookmarkNode* group_b_;
const BookmarkNode* group_b_0_;
@@ -33,7 +35,7 @@ class BookmarkEditorBaseControllerTest : public CocoaTest {
// b-30
// b-31
// b-4
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
+ BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
const BookmarkNode* root = model.GetBookmarkBarNode();
group_a_ = model.AddGroup(root, 0, L"a");
model.AddURL(group_a_, 0, L"a-0", GURL("http://a-0.com"));
@@ -63,7 +65,7 @@ class BookmarkEditorBaseControllerTest : public CocoaTest {
return [[BookmarkEditorBaseController alloc]
initWithParentWindow:test_window()
nibName:@"BookmarkAllTabs"
- profile:helper_.profile()
+ profile:browser_helper_.profile()
parent:group_b_0_
configuration:BookmarkEditor::SHOW_TREE
handler:nil];
@@ -73,16 +75,17 @@ class BookmarkEditorBaseControllerTest : public CocoaTest {
CocoaTest::SetUp();
controller_ = CreateController();
EXPECT_TRUE([controller_ window]);
+ [controller_ runAsModalSheet];
}
virtual void TearDown() {
- [controller_ close];
+ controller_ = NULL;
CocoaTest::TearDown();
}
};
TEST_F(BookmarkEditorBaseControllerTest, VerifyBookmarkTestModel) {
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
+ BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
const BookmarkNode& root(*model.GetBookmarkBarNode());
EXPECT_EQ(4, root.GetChildCount());
// a
@@ -127,22 +130,52 @@ TEST_F(BookmarkEditorBaseControllerTest, VerifyBookmarkTestModel) {
// d
child = root.GetChild(3);
EXPECT_EQ(0, child->GetChildCount());
+ [controller_ cancel:nil];
}
-TEST_F(BookmarkEditorBaseControllerTest, FolderChildForParent) {
- const BookmarkNode* child =
- [BookmarkEditorBaseController folderChildForParent:group_b_
- withFolderIndex:1];
- EXPECT_EQ(child, group_b_3_);
+TEST_F(BookmarkEditorBaseControllerTest, NodeSelection) {
+ EXPECT_TRUE([controller_ folderTreeArray]);
+ [controller_ selectTestNodeInBrowser:group_b_3_];
+ const BookmarkNode* node = [controller_ selectedNode];
+ EXPECT_EQ(node, group_b_3_);
+ [controller_ cancel:nil];
}
-TEST_F(BookmarkEditorBaseControllerTest, IndexOfFolderChild) {
- int index = [BookmarkEditorBaseController indexOfFolderChild:group_b_3_];
- EXPECT_EQ(index, 1);
+TEST_F(BookmarkEditorBaseControllerTest, CreateFolder) {
+ EXPECT_EQ(2, group_b_3_->GetChildCount());
+ [controller_ selectTestNodeInBrowser:group_b_3_];
+ NSString* expectedName =
+ l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
+ [controller_ setDisplayName:expectedName];
+ [controller_ newFolder:nil];
+ NSArray* selectionPaths = [controller_ tableSelectionPaths];
+ EXPECT_EQ(1U, [selectionPaths count]);
+ NSIndexPath* selectionPath = [selectionPaths objectAtIndex:0];
+ EXPECT_EQ(4U, [selectionPath length]);
+ BookmarkFolderInfo* newFolderInfo = [controller_ selectedFolder];
+ EXPECT_TRUE(newFolderInfo);
+ NSString* newFolderName = [newFolderInfo folderName];
+ EXPECT_TRUE([newFolderName isEqualToString:expectedName]);
+ [controller_ createNewFolders];
+ // Verify that the tab folder was added to the new folder.
+ EXPECT_EQ(3, group_b_3_->GetChildCount());
+ [controller_ cancel:nil];
}
-TEST_F(BookmarkEditorBaseControllerTest, NodeSelection) {
- [controller_ selectNodeInBrowser:group_b_3_];
- const BookmarkNode* node = [controller_ selectedNode];
- EXPECT_EQ(node, group_b_3_);
+
+class BookmarkFolderInfoTest : public CocoaTest { };
+
+TEST_F(BookmarkFolderInfoTest, Construction) {
+ NSMutableArray* children = [NSMutableArray arrayWithObject:@"child"];
+ // We just need a pointer, and any pointer will do.
+ const BookmarkNode* fakeNode =
+ reinterpret_cast<const BookmarkNode*>(&children);
+ BookmarkFolderInfo* info =
+ [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:@"name"
+ folderNode:fakeNode
+ children:children];
+ EXPECT_TRUE(info);
+ EXPECT_EQ([info folderName], @"name");
+ EXPECT_EQ([info children], children);
+ EXPECT_EQ([info folderNode], fakeNode);
}
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.h b/chrome/browser/cocoa/bookmark_editor_controller.h
index ff779b8..1fcf5f7 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller.h
+++ b/chrome/browser/cocoa/bookmark_editor_controller.h
@@ -7,8 +7,9 @@
#import "chrome/browser/cocoa/bookmark_editor_base_controller.h"
-// A controller for the bookmark editor, opened with Edit... from the
-// context menu of a bookmark button.
+// A controller for the bookmark editor, opened by 1) Edit... from the
+// context menu of a bookmark button, and 2) Bookmark this Page...'s Edit
+// button.
@interface BookmarkEditorController : BookmarkEditorBaseController {
@private
const BookmarkNode* node_; // weak; owned by the model
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.mm b/chrome/browser/cocoa/bookmark_editor_controller.mm
index 8164d4b..f471f1f 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller.mm
+++ b/chrome/browser/cocoa/bookmark_editor_controller.mm
@@ -87,8 +87,9 @@
// should not be enabled). If the bookmark previously existed then it is
// removed from its old folder. The bookmark is then added to its new
// folder. If the folder has not changed then the bookmark stays in its
-// original position (index) otherwise it is added to the end of the new folder.
-- (IBAction)ok:(id)sender {
+// original position (index) otherwise it is added to the end of the new
+// folder. Called by -[BookmarkEditorBaseController ok:].
+- (NSNumber*)didCommit {
NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
std::wstring newTitle = base::SysNSStringToWide(name);
@@ -97,9 +98,9 @@
int newIndex = newParentNode->GetChildCount();
GURL newURL = [self GURLFromUrlField];
if (!newURL.is_valid()) {
- // Shouldn't be reached -- OK button disabled if not valid!
+ // Shouldn't be reached -- OK button should be disabled if not valid!
NOTREACHED();
- return;
+ return [NSNumber numberWithBool:NO];
}
// Determine where the new/replacement bookmark is to go.
@@ -116,8 +117,8 @@
const BookmarkNode* node = model->AddURL(newParentNode, newIndex,
newTitle, newURL);
// Honor handler semantics: callback on node creation.
- [self NotifyHandlerCreatedNode:node];
- [super ok:sender];
+ [self notifyHandlerCreatedNode:node];
+ return [NSNumber numberWithBool:YES];
}
@end // BookmarkEditorController
diff --git a/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
index db340b1..f505585 100644
--- a/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
@@ -4,7 +4,6 @@
#import <Cocoa/Cocoa.h>
-#include "base/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#import "chrome/browser/cocoa/bookmark_editor_controller.h"
#include "chrome/browser/cocoa/browser_test_helper.h"
@@ -14,86 +13,40 @@
class BookmarkEditorControllerTest : public CocoaTest {
public:
- BrowserTestHelper helper_;
+ BrowserTestHelper browser_helper_;
const BookmarkNode* default_node_;
const BookmarkNode* default_parent_;
const char* default_name_;
std::wstring default_title_;
- BookmarkEditorController* default_controller_;
+ BookmarkEditorController* controller_;
virtual void SetUp() {
CocoaTest::SetUp();
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+ BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
default_parent_ = model->GetBookmarkBarNode();
default_name_ = "http://www.zim-bop-a-dee.com/";
default_title_ = L"ooh title";
const BookmarkNode* default_node = model->AddURL(default_parent_, 0,
default_title_,
GURL(default_name_));
- default_controller_ = [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:default_parent_
- node:default_node
- configuration:BookmarkEditor::NO_TREE
- handler:nil];
- [default_controller_ window]; // Forces a nib load
+ controller_ = [[BookmarkEditorController alloc]
+ initWithParentWindow:test_window()
+ profile:browser_helper_.profile()
+ parent:default_parent_
+ node:default_node
+ configuration:BookmarkEditor::NO_TREE
+ handler:nil];
+ [controller_ runAsModalSheet];
}
virtual void TearDown() {
- [default_controller_ close];
+ controller_ = NULL;
CocoaTest::TearDown();
}
};
-TEST_F(BookmarkEditorControllerTest, NoNodeNoTree) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* node = NULL;
-
- BookmarkEditorController* controller =
- [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- node:node
- configuration:BookmarkEditor::NO_TREE
- handler:nil];
-
- EXPECT_NE((NSWindow*)nil, [controller window]); // Forces a nib load
- EXPECT_EQ(@"", [controller displayName]);
- EXPECT_EQ(@"", [controller displayURL]);
- EXPECT_FALSE([controller okButtonEnabled]);
- [controller close];
-}
-
-TEST_F(BookmarkEditorControllerTest, YesNodeShowTree) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const char* url_name = "http://www.zim-bop-a-dee.com/";
- const BookmarkNode* node = model->AddURL(parent, 0, default_title_,
- GURL(url_name));
-
- BookmarkEditorController* controller =
- [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- node:node
- configuration:BookmarkEditor::SHOW_TREE
- handler:nil];
-
- EXPECT_NE((NSWindow*)nil, [controller window]); // Forces a nib load
- EXPECT_TRUE([base::SysWideToNSString(default_title_)
- isEqual:[controller displayName]]);
- EXPECT_TRUE([[NSString stringWithCString:url_name
- encoding:NSUTF8StringEncoding]
- isEqual:[controller displayURL]]);
- [controller close];
-}
-
TEST_F(BookmarkEditorControllerTest, NoEdit) {
- [default_controller_ ok:nil];
+ [controller_ cancel:nil];
ASSERT_EQ(default_parent_->GetChildCount(), 1);
const BookmarkNode* child = default_parent_->GetChild(0);
EXPECT_EQ(child->GetTitle(), default_title_);
@@ -101,8 +54,8 @@ TEST_F(BookmarkEditorControllerTest, NoEdit) {
}
TEST_F(BookmarkEditorControllerTest, EditTitle) {
- [default_controller_ setDisplayName:@"whamma jamma bamma"];
- [default_controller_ ok:nil];
+ [controller_ setDisplayName:@"whamma jamma bamma"];
+ [controller_ ok:nil];
ASSERT_EQ(default_parent_->GetChildCount(), 1);
const BookmarkNode* child = default_parent_->GetChild(0);
EXPECT_EQ(child->GetTitle(), L"whamma jamma bamma");
@@ -110,10 +63,10 @@ TEST_F(BookmarkEditorControllerTest, EditTitle) {
}
TEST_F(BookmarkEditorControllerTest, EditURL) {
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
- [default_controller_ setDisplayURL:@"http://yellow-sneakers.com/"];
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
- [default_controller_ ok:nil];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ setDisplayURL:@"http://yellow-sneakers.com/"];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ ok:nil];
ASSERT_EQ(default_parent_->GetChildCount(), 1);
const BookmarkNode* child = default_parent_->GetChild(0);
EXPECT_EQ(child->GetTitle(), default_title_);
@@ -121,8 +74,8 @@ TEST_F(BookmarkEditorControllerTest, EditURL) {
}
TEST_F(BookmarkEditorControllerTest, EditAndFixPrefix) {
- [default_controller_ setDisplayURL:@"x"];
- [default_controller_ ok:nil];
+ [controller_ setDisplayURL:@"x"];
+ [controller_ ok:nil];
ASSERT_EQ(default_parent_->GetChildCount(), 1);
const BookmarkNode* child = default_parent_->GetChild(0);
EXPECT_TRUE(child->GetURL().is_valid());
@@ -131,27 +84,102 @@ TEST_F(BookmarkEditorControllerTest, EditAndFixPrefix) {
TEST_F(BookmarkEditorControllerTest, EditAndConfirmOKButton) {
// Confirm OK button enabled/disabled as appropriate:
// First test the URL.
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
- [default_controller_ setDisplayURL:@""];
- EXPECT_FALSE([default_controller_ okButtonEnabled]);
- [default_controller_ setDisplayURL:@"http://www.cnn.com"];
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
+ EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ setDisplayURL:@""];
+ EXPECT_FALSE([controller_ okButtonEnabled]);
+ [controller_ setDisplayURL:@"http://www.cnn.com"];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
// Then test the name.
- [default_controller_ setDisplayName:@""];
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
- [default_controller_ setDisplayName:@" "];
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
+ [controller_ setDisplayName:@""];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ setDisplayName:@" "];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
// Then little mix of both.
- [default_controller_ setDisplayName:@"name"];
- EXPECT_TRUE([default_controller_ okButtonEnabled]);
- [default_controller_ setDisplayURL:@""];
- EXPECT_FALSE([default_controller_ okButtonEnabled]);
+ [controller_ setDisplayName:@"name"];
+ EXPECT_TRUE([controller_ okButtonEnabled]);
+ [controller_ setDisplayURL:@""];
+ EXPECT_FALSE([controller_ okButtonEnabled]);
+ [controller_ cancel:nil];
+}
+
+class BookmarkEditorControllerNoNodeTest : public CocoaTest {
+ public:
+ BrowserTestHelper browser_helper_;
+ BookmarkEditorController* controller_;
+
+ virtual void SetUp() {
+ CocoaTest::SetUp();
+ BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ controller_ = [[BookmarkEditorController alloc]
+ initWithParentWindow:test_window()
+ profile:browser_helper_.profile()
+ parent:parent
+ node:NULL
+ configuration:BookmarkEditor::NO_TREE
+ handler:nil];
+
+ [controller_ runAsModalSheet];
+ }
+
+ virtual void TearDown() {
+ controller_ = NULL;
+ CocoaTest::TearDown();
+ }
+};
+
+TEST_F(BookmarkEditorControllerNoNodeTest, NoNodeNoTree) {
+ EXPECT_EQ(@"", [controller_ displayName]);
+ EXPECT_EQ(@"", [controller_ displayURL]);
+ EXPECT_FALSE([controller_ okButtonEnabled]);
+ [controller_ cancel:nil];
+}
+
+class BookmarkEditorControllerYesNodeTest : public CocoaTest {
+ public:
+ BrowserTestHelper browser_helper_;
+ std::wstring default_title_;
+ const char* url_name_;
+ BookmarkEditorController* controller_;
+
+ virtual void SetUp() {
+ CocoaTest::SetUp();
+ BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ default_title_ = L"wooh title";
+ url_name_ = "http://www.zoom-baby-doo-da.com/";
+ const BookmarkNode* node = model->AddURL(parent, 0, default_title_,
+ GURL(url_name_));
+ controller_ = [[BookmarkEditorController alloc]
+ initWithParentWindow:test_window()
+ profile:browser_helper_.profile()
+ parent:parent
+ node:node
+ configuration:BookmarkEditor::NO_TREE
+ handler:nil];
+
+ [controller_ runAsModalSheet];
+ }
+
+ virtual void TearDown() {
+ controller_ = NULL;
+ CocoaTest::TearDown();
+ }
+};
+
+TEST_F(BookmarkEditorControllerYesNodeTest, YesNodeShowTree) {
+ EXPECT_TRUE([base::SysWideToNSString(default_title_)
+ isEqual:[controller_ displayName]]);
+ EXPECT_TRUE([[NSString stringWithCString:url_name_
+ encoding:NSUTF8StringEncoding]
+ isEqual:[controller_ displayURL]]);
+ [controller_ cancel:nil];
}
class BookmarkEditorControllerTreeTest : public CocoaTest {
public:
- BrowserTestHelper helper_;
- BookmarkEditorController* default_controller_;
+ BrowserTestHelper browser_helper_;
+ BookmarkEditorController* controller_;
const BookmarkNode* group_a_;
const BookmarkNode* group_b_;
const BookmarkNode* group_bb_;
@@ -169,7 +197,7 @@ class BookmarkEditorControllerTreeTest : public CocoaTest {
// bb-4
// b-1
// b-2
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
+ BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
const BookmarkNode* root = model.GetBookmarkBarNode();
group_a_ = model.AddGroup(root, 0, L"a");
model.AddURL(group_a_, 0, L"a-0", GURL("http://a-0.com"));
@@ -200,7 +228,7 @@ class BookmarkEditorControllerTreeTest : public CocoaTest {
virtual BookmarkEditorController* CreateController() {
return [[BookmarkEditorController alloc]
initWithParentWindow:test_window()
- profile:helper_.profile()
+ profile:browser_helper_.profile()
parent:group_bb_
node:bookmark_bb_3_
configuration:BookmarkEditor::SHOW_TREE
@@ -208,19 +236,18 @@ class BookmarkEditorControllerTreeTest : public CocoaTest {
}
virtual void SetUp() {
- CocoaTest::SetUp();
- default_controller_ = CreateController();
- EXPECT_TRUE([default_controller_ window]);
+ controller_ = CreateController();
+ [controller_ runAsModalSheet];
}
virtual void TearDown() {
- [default_controller_ close];
+ controller_ = NULL;
CocoaTest::TearDown();
}
};
TEST_F(BookmarkEditorControllerTreeTest, VerifyBookmarkTestModel) {
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
+ BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
model.root_node();
const BookmarkNode& root(*model.GetBookmarkBarNode());
EXPECT_EQ(4, root.GetChildCount());
@@ -267,12 +294,13 @@ TEST_F(BookmarkEditorControllerTreeTest, VerifyBookmarkTestModel) {
child = root.GetChild(3);
EXPECT_EQ(0, child->GetChildCount());
+ [controller_ cancel:nil];
}
TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) {
const BookmarkNode* oldParent = bookmark_bb_3_->GetParent();
- [default_controller_ setDisplayName:@"NEW NAME"];
- [default_controller_ ok:nil];
+ [controller_ setDisplayName:@"NEW NAME"];
+ [controller_ ok:nil];
const BookmarkNode* newParent = bookmark_bb_3_->GetParent();
ASSERT_EQ(newParent, oldParent);
int childIndex = newParent->IndexOfChild(bookmark_bb_3_);
@@ -281,8 +309,8 @@ TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) {
TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkURLInPlace) {
const BookmarkNode* oldParent = bookmark_bb_3_->GetParent();
- [default_controller_ setDisplayURL:@"http://NEWURL.com"];
- [default_controller_ ok:nil];
+ [controller_ setDisplayURL:@"http://NEWURL.com"];
+ [controller_ ok:nil];
const BookmarkNode* newParent = bookmark_bb_3_->GetParent();
ASSERT_EQ(newParent, oldParent);
int childIndex = newParent->IndexOfChild(bookmark_bb_3_);
@@ -290,8 +318,8 @@ TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkURLInPlace) {
}
TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkGroup) {
- [default_controller_ selectTestNodeInBrowser:group_c_];
- [default_controller_ ok:nil];
+ [controller_ selectTestNodeInBrowser:group_c_];
+ [controller_ ok:nil];
const BookmarkNode* parent = bookmark_bb_3_->GetParent();
ASSERT_EQ(parent, group_c_);
int childIndex = parent->IndexOfChild(bookmark_bb_3_);
@@ -299,9 +327,9 @@ TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkGroup) {
}
TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkGroup) {
- [default_controller_ setDisplayName:@"NEW NAME"];
- [default_controller_ selectTestNodeInBrowser:group_c_];
- [default_controller_ ok:nil];
+ [controller_ setDisplayName:@"NEW NAME"];
+ [controller_ selectTestNodeInBrowser:group_c_];
+ [controller_ ok:nil];
const BookmarkNode* parent = bookmark_bb_3_->GetParent();
ASSERT_EQ(parent, group_c_);
int childIndex = parent->IndexOfChild(bookmark_bb_3_);
@@ -310,11 +338,10 @@ TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkGroup) {
}
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");
+ // Folders are NOT added unless the OK button is pressed.
+ [controller_ newFolder:nil];
+ [controller_ cancel:nil];
+ EXPECT_EQ(5, group_bb_->GetChildCount());
}
class BookmarkEditorControllerTreeNoNodeTest :
@@ -323,7 +350,7 @@ class BookmarkEditorControllerTreeNoNodeTest :
virtual BookmarkEditorController* CreateController() {
return [[BookmarkEditorController alloc]
initWithParentWindow:test_window()
- profile:helper_.profile()
+ profile:browser_helper_.profile()
parent:group_bb_
node:nil
configuration:BookmarkEditor::SHOW_TREE
@@ -333,35 +360,11 @@ class BookmarkEditorControllerTreeNoNodeTest :
};
TEST_F(BookmarkEditorControllerTreeNoNodeTest, NewBookmarkNoNode) {
- [default_controller_ setDisplayName:@"NEW BOOKMARK"];
- [default_controller_ setDisplayURL:@"http://NEWURL.com"];
- [default_controller_ ok:nil];
+ [controller_ setDisplayName:@"NEW BOOKMARK"];
+ [controller_ setDisplayURL:@"http://NEWURL.com"];
+ [controller_ ok:nil];
const BookmarkNode* new_node = group_bb_->GetChild(5);
ASSERT_EQ(0, new_node->GetChildCount());
EXPECT_EQ(new_node->GetTitle(), L"NEW BOOKMARK");
EXPECT_EQ(new_node->GetURL(), GURL("http://NEWURL.com"));
}
-
-class BookmarkEditorControllerTreeNoParentTest :
- public BookmarkEditorControllerTreeTest {
- public:
- virtual BookmarkEditorController* CreateController() {
- return [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:nil
- node:nil
- configuration:BookmarkEditor::SHOW_TREE
- handler:nil];
- }
-};
-
-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");
-}