1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
6#define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
7
8#import <Cocoa/Cocoa.h>
9
10#include "base/mac/scoped_nsobject.h"
11#include "base/memory/scoped_ptr.h"
12#include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h"
13#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
14
15class BookmarkEditorBaseControllerBridge;
16class BookmarkModel;
17@class BookmarkTreeBrowserCell;
18
19// A base controller class for bookmark creation and editing dialogs which
20// present the current bookmark folder structure in a tree view.  Do not
21// instantiate this controller directly -- use one of its derived classes.
22// NOTE: If a derived class is intended to be dispatched via the
23// BookmarkEditor::Show static function found in the accompanying
24// implementation, that function will need to be update.
25@interface BookmarkEditorBaseController : NSWindowController {
26 @private
27  IBOutlet NSButton* newFolderButton_;
28  IBOutlet NSButton* okButton_;  // Used for unit testing only.
29  IBOutlet NSTreeController* folderTreeController_;
30  IBOutlet NSOutlineView* folderTreeView_;
31
32  NSWindow* parentWindow_;  // weak
33  Profile* profile_;  // weak
34  const BookmarkNode* parentNode_;  // weak; owned by the model
35  GURL url_;  // This and title_ are only used for new urls.
36  string16 title_;
37  BookmarkEditor::Configuration configuration_;
38  NSString* initialName_;
39  NSString* displayName_;  // Bound to a text field in the dialog.
40  BOOL okEnabled_;  // Bound to the OK button.
41  BOOL creatingNewFolders_;  // True while in createNewFolders.
42  // An array of BookmarkFolderInfo where each item describes a folder in the
43  // BookmarkNode structure.
44  base::scoped_nsobject<NSArray> folderTreeArray_;
45  // Bound to the table view giving a path to the current selections, of which
46  // there should only ever be one.
47  base::scoped_nsobject<NSArray> tableSelectionPaths_;
48  // C++ bridge object that observes the BookmarkModel for me.
49  scoped_ptr<BookmarkEditorBaseControllerBridge> observer_;
50}
51
52@property(nonatomic, copy) NSString* initialName;
53@property(nonatomic, copy) NSString* displayName;
54@property(nonatomic, assign) BOOL okEnabled;
55@property(nonatomic, retain, readonly) NSArray* folderTreeArray;
56@property(nonatomic, copy) NSArray* tableSelectionPaths;
57
58// Designated initializer.  Derived classes should call through to this init.
59// |url| and |title| are only used for BookmarkNode::Type::NEW_URL.
60- (id)initWithParentWindow:(NSWindow*)parentWindow
61                   nibName:(NSString*)nibName
62                   profile:(Profile*)profile
63                    parent:(const BookmarkNode*)parent
64                       url:(const GURL&)url
65                     title:(const string16&)title
66             configuration:(BookmarkEditor::Configuration)configuration;
67
68// Run the bookmark editor as a modal sheet.  Does not block.
69- (void)runAsModalSheet;
70
71// Create a new folder at the end of the selected parent folder, give it
72// an untitled name, and put it into editing mode.
73- (IBAction)newFolder:(id)sender;
74
75// The cancel action will dismiss the dialog.  Derived classes which
76// override cancel:, must call this after accessing any dialog-related
77// data.
78- (IBAction)cancel:(id)sender;
79
80// The OK action will dismiss the dialog.  This action is bound
81// to the OK button of a dialog which presents a tree view of a profile's
82// folder hierarchy and allows the creation of new folders within that tree.
83// When the OK button is pressed, this function will: 1) call the derived
84// class's -[willCommit] function, 2) create any new folders created by
85// the user while the dialog is presented, 3) call the derived class's
86// -[didCommit] function, and then 4) dismiss the dialog.  At least one
87// of -[willCommit] and -[didCommit] must be provided by the derived class
88// and should return a NSNumber containing a BOOL or nil ('nil' means YES)
89// indicating if the operation should be allowed to continue.
90// Note: A derived class should not override the ok: action.
91- (IBAction)ok:(id)sender;
92
93// Methods for use by derived classes only.
94
95// Determine and returns the rightmost selected/highlighted element (node)
96// in the bookmark tree view if the tree view is showing, otherwise returns
97// the original |parentNode_|.  If the tree view is showing but nothing is
98// selected then the root node is returned.
99- (const BookmarkNode*)selectedNode;
100
101// Expands the set of BookmarkNodes in |nodes|.
102- (void)expandNodes:(const BookmarkExpandedStateTracker::Nodes&)nodes;
103
104// Returns the set of expanded BookmarkNodes.
105- (BookmarkExpandedStateTracker::Nodes)getExpandedNodes;
106
107// Select/highlight the given node within the browser tree view.  If the
108// node is nil then select the bookmark bar node.  Exposed for unit test.
109- (void)selectNodeInBrowser:(const BookmarkNode*)node;
110
111// Notifications called when the BookmarkModel changes out from under me.
112- (void)nodeRemoved:(const BookmarkNode*)node
113         fromParent:(const BookmarkNode*)parent;
114- (void)modelChangedPreserveSelection:(BOOL)preserve;
115
116// Accessors
117- (BookmarkModel*)bookmarkModel;
118- (Profile*)profile;
119- (const BookmarkNode*)parentNode;
120- (const GURL&)url;
121- (const string16&)title;
122
123@end
124
125// Describes the profile's bookmark folder structure: the folder name, the
126// original BookmarkNode pointer (if the folder already exists), a BOOL
127// indicating if the folder is new (meaning: created during this session
128// but not yet committed to the bookmark structure), and an NSArray of
129// child folder BookmarkFolderInfo's following this same structure.
130@interface BookmarkFolderInfo : NSObject {
131 @private
132  NSString* folderName_;
133  const BookmarkNode* folderNode_;  // weak
134  NSMutableArray* children_;
135  BOOL newFolder_;
136}
137
138@property(nonatomic, copy) NSString* folderName;
139@property(nonatomic, assign) const BookmarkNode* folderNode;
140@property(nonatomic, retain) NSMutableArray* children;
141@property(nonatomic, assign) BOOL newFolder;
142
143// Convenience creator for adding a new folder to the editor's bookmark
144// structure.  This folder will be added to the bookmark model when the
145// user accepts the dialog. |folderName| must be provided.
146+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName;
147
148// Designated initializer.  |folderName| must be provided.  For folders which
149// already exist in the bookmark model, |folderNode| and |children| (if any
150// children are already attached to this folder) must be provided and
151// |newFolder| should be NO.  For folders which the user has added during
152// this session and which have not been committed yet, |newFolder| should be
153// YES and |folderNode| and |children| should be NULL/nil.
154- (id)initWithFolderName:(NSString*)folderName
155              folderNode:(const BookmarkNode*)folderNode
156                children:(NSMutableArray*)children
157               newFolder:(BOOL)newFolder;
158
159// Convenience creator used during construction of the editor's bookmark
160// structure.  |folderName| and |folderNode| must be provided. |children|
161// is optional.  Private: exposed here for unit testing purposes.
162+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName
163                            folderNode:(const BookmarkNode*)folderNode
164                              children:(NSMutableArray*)children;
165
166@end
167
168@interface BookmarkEditorBaseController(TestingAPI)
169
170@property(nonatomic, readonly) BOOL okButtonEnabled;
171
172// Create any newly added folders.  New folders are nodes in folderTreeArray
173// which are marked as being new (i.e. their kFolderTreeNewFolderKey
174// dictionary item is YES).  This is called by -[ok:].
175- (void)createNewFolders;
176
177// Select the given bookmark node within the tree view.
178- (void)selectTestNodeInBrowser:(const BookmarkNode*)node;
179
180// Return the dictionary for the folder selected in the tree.
181- (BookmarkFolderInfo*)selectedFolder;
182
183@end
184
185#endif  // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
186