Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(684)

Side by Side Diff: chrome/browser/cocoa/bookmark_manager_controller.mm

Issue 501073: Native Cocoa bookmark manager, part 1 (Closed)
Patch Set: Style fixes, and copy/paste unit tests Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2009 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/cocoa/bookmark_manager_controller.h"
6
7 #include "app/resource_bundle.h"
8 #include "base/mac_util.h"
9 #include "base/sys_string_conversions.h"
10 #include "chrome/browser/bookmarks/bookmark_model.h"
11 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
12 #include "chrome/browser/browser.h"
13 #include "chrome/browser/browser_list.h"
14 #include "chrome/browser/browser_window.h"
15 #import "chrome/browser/cocoa/bookmark_groups_controller.h"
16 #import "chrome/browser/cocoa/bookmark_tree_controller.h"
17 #include "chrome/browser/profile.h"
18 #include "grit/app_resources.h"
19 #include "grit/theme_resources.h"
20 #include "skia/ext/skia_utils_mac.h"
21
22
23 // There's at most one BookmarkManagerController at a time. This points to it.
24 static BookmarkManagerController* sInstance;
25
26
27 @interface BookmarkManagerController ()
28 - (void)nodeChanged:(const BookmarkNode*)node
29 childrenChanged:(BOOL)childrenChanged;
30 @end
31
32
33 // Adapter to tell BookmarkManagerController when bookmarks change.
34 class BookmarkManagerBridge : public BookmarkModelObserver {
35 public:
36 BookmarkManagerBridge(BookmarkManagerController* manager)
37 :manager_(manager) { }
38
39 virtual void Loaded(BookmarkModel* model) {
40 // Ignore this; model has already loaded by this point.
41 }
42
43 virtual void BookmarkNodeMoved(BookmarkModel* model,
44 const BookmarkNode* old_parent,
45 int old_index,
46 const BookmarkNode* new_parent,
47 int new_index) {
48 [manager_ nodeChanged:old_parent childrenChanged:YES];
49 [manager_ nodeChanged:new_parent childrenChanged:YES];
50 }
51
52 virtual void BookmarkNodeAdded(BookmarkModel* model,
53 const BookmarkNode* parent,
54 int index) {
55 [manager_ nodeChanged:parent childrenChanged:YES];
56 }
57
58 virtual void BookmarkNodeRemoved(BookmarkModel* model,
59 const BookmarkNode* parent,
60 int old_index,
61 const BookmarkNode* node) {
62 [manager_ nodeChanged:parent childrenChanged:YES];
63 [manager_ forgetNode:node];
64 }
65
66 virtual void BookmarkNodeChanged(BookmarkModel* model,
67 const BookmarkNode* node) {
68 [manager_ nodeChanged:node childrenChanged:NO];
69 }
70
71 virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
72 const BookmarkNode* node) {
73 [manager_ nodeChanged:node childrenChanged:NO];
74 }
75
76 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
77 const BookmarkNode* node) {
78 [manager_ nodeChanged:node childrenChanged:YES];
79 }
80
81 private:
82 BookmarkManagerController* manager_; // weak
83 };
84
85
86 @implementation BookmarkManagerController
87
88
89 // Private instance initialization method.
90 - (id)initWithProfile:(Profile*)profile {
91 // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we
92 // can override it in a unit test.
93 NSString* nibPath = [mac_util::MainAppBundle()
94 pathForResource:@"BookmarkManager"
95 ofType:@"nib"];
96 self = [super initWithWindowNibPath:nibPath owner:self];
97 if (self != nil) {
98 profile_ = profile;
99 bridge_ = new BookmarkManagerBridge(self);
100 profile_->GetBookmarkModel()->AddObserver(bridge_);
101
102 // Initialize some cached icons:
103 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
104 folderIcon_.reset([rb.GetNSImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]);
105 defaultFavIcon_.reset([rb.GetNSImageNamed(IDR_DEFAULT_FAVICON) retain]);
106 }
107 return self;
108 }
109
110 - (void)dealloc {
111 if (self == sInstance) {
112 sInstance = nil;
113 }
114 if (bridge_) {
115 profile_->GetBookmarkModel()->RemoveObserver(bridge_);
116 delete bridge_;
117 }
118 [super dealloc];
119 }
120
121 - (void)awakeFromNib {
122 [groupsController_ reload];
123 [treeController_ bind:@"group"
124 toObject:groupsController_
125 withKeyPath:@"selectedGroup"
126 options:0];
127 }
128
129 // can't synthesize category methods, unfortunately
130 - (BookmarkGroupsController*)groupsController {
131 return groupsController_;
132 }
133
134 - (BookmarkTreeController*)treeController {
135 return treeController_;
136 }
137
138
139 #pragma mark -
140 #pragma mark DATA MODEL:
141
142
143 // Getter for the |bookmarkModel| property.
144 - (BookmarkModel*)bookmarkModel {
145 return profile_->GetBookmarkModel();
146 }
147
148 // Maps a BookmarkNode to a table/outline row item placeholder.
149 - (const BookmarkNode*)nodeFromItem:(id)item {
150 return (const BookmarkNode*)[item pointerValue];
151 }
152
153 // Maps a table/outline row item placeholder back to a BookmarkNode.
154 - (id)itemFromNode:(const BookmarkNode*)node {
155 if (!nodeMap_) {
156 nodeMap_.reset([[NSMapTable alloc]
157 initWithKeyOptions:NSPointerFunctionsOpaqueMemory |
158 NSPointerFunctionsOpaquePersonality
159 valueOptions:NSPointerFunctionsStrongMemory
160 capacity:500]);
161 }
162 NSValue* item = (NSValue*)NSMapGet(nodeMap_, node);
163 if (!item) {
164 item = [NSValue valueWithPointer:node];
165 NSMapInsertKnownAbsent(nodeMap_, node, item);
166 }
167 return item;
168 }
169
170 // Removes a BookmarkNode from the node<->item mapping table.
171 - (void)forgetNode:(const BookmarkNode*)node {
172 NSMapRemove(nodeMap_, node);
173 for (int i = node->GetChildCount() - 1 ; i >= 0 ; i--) {
174 [self forgetNode:node->GetChild(i)];
175 }
176 }
177
178 // Called when the bookmark model changes; forwards to the sub-controllers.
179 - (void)nodeChanged:(const BookmarkNode*)node
180 childrenChanged:(BOOL)childrenChanged {
181 [groupsController_ nodeChanged:node childrenChanged:childrenChanged];
182 // TreeController only cares about nodes we have items for, so don't bother
183 // creating a new item if the node's never been seen:
184 id item = (NSValue*)NSMapGet(nodeMap_, node);
185 if (item) {
186 [treeController_ itemChanged:item childrenChanged:childrenChanged];
187 }
188 }
189
190
191 // Returns the icon (fav- or folder) for a table/outline item.
192 - (NSImage*)iconForItem:(id)item {
193 const BookmarkNode* node = [self nodeFromItem:item];
194 if (node->is_folder()) {
195 return folderIcon_;
196 } else if (node->is_url()) {
197 const BookmarkNode* node = [self nodeFromItem:item];
198 const SkBitmap& skIcon = [self bookmarkModel]->GetFavIcon(node);
199 if (!skIcon.isNull()) {
200 return gfx::SkBitmapToNSImage(skIcon);
201 }
202 }
203 return defaultFavIcon_;
204 }
205
206
207 #pragma mark -
208 #pragma mark WINDOW MANAGEMENT:
209
210
211 // Public entry point to open the bookmark manager.
212 + (BookmarkManagerController*)showBookmarkManager:(Profile*)profile
213 {
214 if (!sInstance) {
215 sInstance = [[self alloc] initWithProfile:profile];
216 }
217 [sInstance showWindow:self];
218 return sInstance;
219 }
220
221 // When window closes, get rid of myself too. (NSWindow delegate)
222 - (void)windowWillClose:(NSNotification*)n {
223 [self autorelease];
224 }
225
226 // Install the search field into the search toolbar item. (NSToolbar delegate)
227 - (void)toolbarWillAddItem:(NSNotification*)notification {
228 NSToolbarItem* item = [[notification userInfo] objectForKey:@"item"];
229 if ([[item itemIdentifier] isEqualToString:@"search"]) {
230 [item setView:toolbarSearchView_];
231 NSSize size = [toolbarSearchView_ frame].size;
232 [item setMinSize:size];
233 [item setMaxSize:size];
234 }
235 }
236
237 // Called when the user types into the search field.
238 - (IBAction)searchFieldChanged:(id)sender {
239 //TODO(snej): Implement this
240 }
241
242
243 // Open a bookmark, by having Chrome open a tab on its URL.
244 - (void)openBookmarkItem:(id)item {
245 const BookmarkNode* node = [self nodeFromItem:item];
246 DCHECK(node);
247 if (!node->is_url())
248 return;
249 GURL url = node->GetURL();
250
251 Browser* browser = BrowserList::GetLastActive();
252 // if no browser window exists then create one with no tabs to be filled in
253 if (!browser) {
254 browser = Browser::Create(profile_);
255 browser->window()->Show();
256 }
257 browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB,
258 PageTransition::AUTO_BOOKMARK);
259 }
260
261 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698