1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
12 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h"
13 #include "components/bookmarks/browser/bookmark_model.h"
14 #include "components/url_fixer/url_fixer.h"
15 #include "components/user_prefs/user_prefs.h"
17 using bookmarks::BookmarkExpandedStateTracker;
18 using bookmarks::BookmarkModel;
19 using bookmarks::BookmarkNode;
21 @interface BookmarkEditorController (Private)
23 // Grab the url from the text field and convert.
24 - (GURL)GURLFromUrlField;
28 @implementation BookmarkEditorController
30 @synthesize displayURL = displayURL_;
32 + (NSSet*)keyPathsForValuesAffectingOkEnabled {
33 return [NSSet setWithObject:@"displayURL"];
36 - (id)initWithParentWindow:(NSWindow*)parentWindow
37 profile:(Profile*)profile
38 parent:(const BookmarkNode*)parent
39 node:(const BookmarkNode*)node
41 title:(const base::string16&)title
42 configuration:(BookmarkEditor::Configuration)configuration {
43 if ((self = [super initWithParentWindow:parentWindow
44 nibName:@"BookmarkEditor"
49 configuration:configuration])) {
50 // "Add Page..." has no "node" so this may be NULL.
57 [displayURL_ release];
61 - (void)awakeFromNib {
62 // Check if NSTextFieldCell supports the method. This check is in place as
63 // only 10.6 and greater support the setUsesSingleLineMode method.
64 // TODO(kushi.p): Remove this when the project hits a 10.6+ only state.
65 NSTextFieldCell* nameFieldCell_ = [nameTextField_ cell];
67 respondsToSelector:@selector(setUsesSingleLineMode:)]) {
68 [nameFieldCell_ setUsesSingleLineMode:YES];
71 // Set text fields to match our bookmark. If the node is NULL we
72 // arrived here from an "Add Page..." item in a context menu.
74 [self setInitialName:base::SysUTF16ToNSString(node_->GetTitle())];
75 PrefService* prefs = [self profile] ?
76 user_prefs::UserPrefs::Get([self profile]) :
78 base::string16 urlString =
79 chrome::FormatBookmarkURLForDisplay(node_->url(), prefs);
80 initialUrl_.reset([base::SysUTF16ToNSString(urlString) retain]);
82 GURL url = [self url];
83 [self setInitialName:base::SysUTF16ToNSString([self title])];
85 initialUrl_.reset([[NSString stringWithUTF8String:url.spec().c_str()]
88 [self setDisplayURL:initialUrl_];
91 [self bookmarkModel]->expanded_state_tracker()->GetExpandedNodes()];
94 - (void)nodeRemoved:(const BookmarkNode*)node
95 fromParent:(const BookmarkNode*)parent
97 // Be conservative; it is needed (e.g. "Add Page...")
102 #pragma mark Bookmark Editing
104 // If possible, return a valid GURL from the URL text field.
105 - (GURL)GURLFromUrlField {
106 NSString* url = [self displayURL];
107 return url_fixer::FixupURL([url UTF8String], std::string());
110 // Enable the OK button if there is a valid URL.
113 if ([[self displayURL] length]) {
114 GURL newURL = [self GURLFromUrlField];
115 okEnabled = (newURL.is_valid()) ? YES : NO;
118 [urlField_ setBackgroundColor:[NSColor whiteColor]];
120 [urlField_ setBackgroundColor:[NSColor colorWithCalibratedRed:1.0
127 // The bookmark's URL is assumed to be valid (otherwise the OK button
128 // should not be enabled). Previously existing bookmarks for which the
129 // parent has not changed are updated in-place. Those for which the parent
130 // has changed are removed with a new node created under the new parent.
131 // Called by -[BookmarkEditorBaseController ok:].
132 - (NSNumber*)didCommit {
133 NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
134 [NSCharacterSet newlineCharacterSet]];
135 base::string16 newTitle = base::SysNSStringToUTF16(name);
136 const BookmarkNode* newParentNode = [self selectedNode];
137 GURL newURL = [self GURLFromUrlField];
138 if (!newURL.is_valid()) {
139 // Shouldn't be reached -- OK button should be disabled if not valid!
141 return [NSNumber numberWithBool:NO];
144 // Determine where the new/replacement bookmark is to go.
145 BookmarkModel* model = [self bookmarkModel];
146 // If there was an old node then we update the node, and move it to its new
147 // parent if the parent has changed (rather than deleting it from the old
148 // parent and adding to the new -- which also prevents the 'poofing' that
149 // occurs when a node is deleted).
151 model->SetURL(node_, newURL);
152 model->SetTitle(node_, newTitle);
153 const BookmarkNode* oldParentNode = [self parentNode];
154 if (newParentNode != oldParentNode)
155 model->Move(node_, newParentNode, newParentNode->child_count());
157 // Otherwise, add a new bookmark at the end of the newly selected folder.
158 model->AddURL(newParentNode, newParentNode->child_count(), newTitle,
162 // Update the expanded state.
163 BookmarkExpandedStateTracker::Nodes expanded_nodes = [self getExpandedNodes];
164 [self bookmarkModel]->expanded_state_tracker()->
165 SetExpandedNodes(expanded_nodes);
166 return [NSNumber numberWithBool:YES];
169 - (NSColor *)urlFieldColor {
170 return [urlField_ backgroundColor];
173 @end // BookmarkEditorController