• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5#import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
6
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"
16
17using bookmarks::BookmarkExpandedStateTracker;
18
19@interface BookmarkEditorController (Private)
20
21// Grab the url from the text field and convert.
22- (GURL)GURLFromUrlField;
23
24@end
25
26@implementation BookmarkEditorController
27
28@synthesize displayURL = displayURL_;
29
30+ (NSSet*)keyPathsForValuesAffectingOkEnabled {
31  return [NSSet setWithObject:@"displayURL"];
32}
33
34- (id)initWithParentWindow:(NSWindow*)parentWindow
35                   profile:(Profile*)profile
36                    parent:(const BookmarkNode*)parent
37                      node:(const BookmarkNode*)node
38                       url:(const GURL&)url
39                     title:(const base::string16&)title
40             configuration:(BookmarkEditor::Configuration)configuration {
41  if ((self = [super initWithParentWindow:parentWindow
42                                  nibName:@"BookmarkEditor"
43                                  profile:profile
44                                   parent:parent
45                                      url:url
46                                    title:title
47                            configuration:configuration])) {
48    // "Add Page..." has no "node" so this may be NULL.
49    node_ = node;
50  }
51  return self;
52}
53
54- (void)dealloc {
55  [displayURL_ release];
56  [super dealloc];
57}
58
59- (void)awakeFromNib {
60  // Check if NSTextFieldCell supports the method. This check is in place as
61  // only 10.6 and greater support the setUsesSingleLineMode method.
62  // TODO(kushi.p): Remove this when the project hits a 10.6+ only state.
63  NSTextFieldCell* nameFieldCell_ = [nameTextField_ cell];
64  if ([nameFieldCell_
65          respondsToSelector:@selector(setUsesSingleLineMode:)]) {
66    [nameFieldCell_ setUsesSingleLineMode:YES];
67  }
68
69  // Set text fields to match our bookmark.  If the node is NULL we
70  // arrived here from an "Add Page..." item in a context menu.
71  if (node_) {
72    [self setInitialName:base::SysUTF16ToNSString(node_->GetTitle())];
73    PrefService* prefs = [self profile] ?
74        user_prefs::UserPrefs::Get([self profile]) :
75        NULL;
76    base::string16 urlString =
77        chrome::FormatBookmarkURLForDisplay(node_->url(), prefs);
78    initialUrl_.reset([base::SysUTF16ToNSString(urlString) retain]);
79  } else {
80    GURL url = [self url];
81    [self setInitialName:base::SysUTF16ToNSString([self title])];
82    if (url.is_valid())
83      initialUrl_.reset([[NSString stringWithUTF8String:url.spec().c_str()]
84                          retain]);
85  }
86  [self setDisplayURL:initialUrl_];
87  [super awakeFromNib];
88  [self expandNodes:
89      [self bookmarkModel]->expanded_state_tracker()->GetExpandedNodes()];
90}
91
92- (void)nodeRemoved:(const BookmarkNode*)node
93         fromParent:(const BookmarkNode*)parent
94{
95  // Be conservative; it is needed (e.g. "Add Page...")
96  node_ = NULL;
97  [self cancel:self];
98}
99
100#pragma mark Bookmark Editing
101
102// If possible, return a valid GURL from the URL text field.
103- (GURL)GURLFromUrlField {
104  NSString* url = [self displayURL];
105  return url_fixer::FixupURL([url UTF8String], std::string());
106}
107
108// Enable the OK button if there is a valid URL.
109- (BOOL)okEnabled {
110  BOOL okEnabled = NO;
111  if ([[self displayURL] length]) {
112    GURL newURL = [self GURLFromUrlField];
113    okEnabled = (newURL.is_valid()) ? YES : NO;
114  }
115  if (okEnabled)
116    [urlField_ setBackgroundColor:[NSColor whiteColor]];
117  else
118    [urlField_ setBackgroundColor:[NSColor colorWithCalibratedRed:1.0
119                                                            green:0.67
120                                                             blue:0.67
121                                                            alpha:1.0]];
122  return okEnabled;
123}
124
125// The bookmark's URL is assumed to be valid (otherwise the OK button
126// should not be enabled). Previously existing bookmarks for which the
127// parent has not changed are updated in-place. Those for which the parent
128// has changed are removed with a new node created under the new parent.
129// Called by -[BookmarkEditorBaseController ok:].
130- (NSNumber*)didCommit {
131  NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
132                    [NSCharacterSet newlineCharacterSet]];
133  base::string16 newTitle = base::SysNSStringToUTF16(name);
134  const BookmarkNode* newParentNode = [self selectedNode];
135  GURL newURL = [self GURLFromUrlField];
136  if (!newURL.is_valid()) {
137    // Shouldn't be reached -- OK button should be disabled if not valid!
138    NOTREACHED();
139    return [NSNumber numberWithBool:NO];
140  }
141
142  // Determine where the new/replacement bookmark is to go.
143  BookmarkModel* model = [self bookmarkModel];
144  // If there was an old node then we update the node, and move it to its new
145  // parent if the parent has changed (rather than deleting it from the old
146  // parent and adding to the new -- which also prevents the 'poofing' that
147  // occurs when a node is deleted).
148  if (node_) {
149    model->SetURL(node_, newURL);
150    model->SetTitle(node_, newTitle);
151    const BookmarkNode* oldParentNode = [self parentNode];
152    if (newParentNode != oldParentNode)
153      model->Move(node_, newParentNode, newParentNode->child_count());
154  } else {
155    // Otherwise, add a new bookmark at the end of the newly selected folder.
156    model->AddURL(newParentNode, newParentNode->child_count(), newTitle,
157                  newURL);
158  }
159
160  // Update the expanded state.
161  BookmarkExpandedStateTracker::Nodes expanded_nodes = [self getExpandedNodes];
162  [self bookmarkModel]->expanded_state_tracker()->
163      SetExpandedNodes(expanded_nodes);
164  return [NSNumber numberWithBool:YES];
165}
166
167- (NSColor *)urlFieldColor {
168  return [urlField_ backgroundColor];
169}
170
171@end  // BookmarkEditorController
172
173