summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 23:57:19 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 23:57:19 +0000
commitee01535e43949832b8fb57a74d892390e01d36dd (patch)
tree630574b28df21ef914369b9a16c0bfdca1b74527
parentd7aef10706a8e8b5da86d48113136887b3ca97a1 (diff)
downloadchromium_src-ee01535e43949832b8fb57a74d892390e01d36dd.zip
chromium_src-ee01535e43949832b8fb57a74d892390e01d36dd.tar.gz
chromium_src-ee01535e43949832b8fb57a74d892390e01d36dd.tar.bz2
Implement bookmark editor. No tree display or hierarchy movement, but
name/url editing works. Get to the edotir from a context menu (Edit, Add Page). Also Implement Open All Bookmarks menu item. BUG=http://crbug.com/8381, http://crbug.com/17006 TEST=Add some bookmarks. Right-click on a bookmark and pick Edit. Test editing the name and URL. Make sure you can't add a bogus URL. Right-click on a bookmark or the bar and Add Page. Fill in name and URL fields to add a new bookmark. Right-click Open All Bookmarks and make sure it hoses your machine. Review URL: http://codereview.chromium.org/155874 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21241 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/nibs/BookmarkBar.xib78
-rw-r--r--chrome/app/nibs/BookmarkEditor.xib624
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.h13
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.mm54
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller_unittest.mm135
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.h54
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller.mm186
-rw-r--r--chrome/browser/cocoa/bookmark_editor_controller_unittest.mm105
-rw-r--r--chrome/chrome.gyp6
9 files changed, 1191 insertions, 64 deletions
diff --git a/chrome/app/nibs/BookmarkBar.xib b/chrome/app/nibs/BookmarkBar.xib
index 2002d9b..4abb7d0 100644
--- a/chrome/app/nibs/BookmarkBar.xib
+++ b/chrome/app/nibs/BookmarkBar.xib
@@ -8,9 +8,9 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="1"/>
- <integer value="4"/>
<integer value="18"/>
+ <integer value="4"/>
+ <integer value="1"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -301,14 +301,6 @@
<object class="IBActionConnection" key="connection">
<string key="label">commandDispatch:</string>
<reference key="source" ref="1003"/>
- <reference key="destination" ref="6422781"/>
- </object>
- <int key="connectionID">32</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">commandDispatch:</string>
- <reference key="source" ref="1003"/>
<reference key="destination" ref="115646576"/>
</object>
<int key="connectionID">33</int>
@@ -341,14 +333,6 @@
<object class="IBActionConnection" key="connection">
<string key="label">commandDispatch:</string>
<reference key="source" ref="1003"/>
- <reference key="destination" ref="926809071"/>
- </object>
- <int key="connectionID">37</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">commandDispatch:</string>
- <reference key="source" ref="1003"/>
<reference key="destination" ref="90793013"/>
</object>
<int key="connectionID">38</int>
@@ -373,22 +357,6 @@
<object class="IBActionConnection" key="connection">
<string key="label">commandDispatch:</string>
<reference key="source" ref="1003"/>
- <reference key="destination" ref="182996500"/>
- </object>
- <int key="connectionID">44</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">commandDispatch:</string>
- <reference key="source" ref="1003"/>
- <reference key="destination" ref="527115352"/>
- </object>
- <int key="connectionID">46</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">commandDispatch:</string>
- <reference key="source" ref="1003"/>
<reference key="destination" ref="595609715"/>
</object>
<int key="connectionID">47</int>
@@ -441,6 +409,38 @@
</object>
<int key="connectionID">55</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">editBookmark:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="182996500"/>
+ </object>
+ <int key="connectionID">56</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">openAllBookmarks:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="6422781"/>
+ </object>
+ <int key="connectionID">57</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">addPage:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="527115352"/>
+ </object>
+ <int key="connectionID">58</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">addPage:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="926809071"/>
+ </object>
+ <int key="connectionID">59</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -735,7 +735,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">55</int>
+ <int key="maxID">59</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -755,7 +755,10 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>addPage:</string>
<string>deleteBookmark:</string>
+ <string>editBookmark:</string>
+ <string>openAllBookmarks:</string>
<string>openBookmark:</string>
<string>openBookmarkInIncognitoWindow:</string>
<string>openBookmarkInNewForegroundTab:</string>
@@ -768,6 +771,9 @@
<string>id</string>
<string>id</string>
<string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
@@ -848,7 +854,7 @@
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
- <string key="IBDocument.LastKnownRelativeProjectPath">../../../chrome.xcodeproj</string>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../../chrome.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>
diff --git a/chrome/app/nibs/BookmarkEditor.xib b/chrome/app/nibs/BookmarkEditor.xib
new file mode 100644
index 0000000..d574a2e
--- /dev/null
+++ b/chrome/app/nibs/BookmarkEditor.xib
@@ -0,0 +1,624 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">1050</int>
+ <string key="IBDocument.SystemVersion">9J61</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.46</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="2"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1001">
+ <string key="NSClassName">BookmarkEditorController</string>
+ </object>
+ <object class="NSCustomObject" id="1003">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1004">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSWindowTemplate" id="1005">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{196, 240}, {480, 270}}</string>
+ <int key="NSWTFlags">536870912</int>
+ <string key="NSWindowTitle">Edit Bookmark</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ <string key="NSWindowContentMinSize">{331, 270}</string>
+ <object class="NSView" key="NSWindowView" id="1006">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSButton" id="631907363">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{14, 12}, {111, 32}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="732374144">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents">New Folder</string>
+ <object class="NSFont" key="NSSupport" id="899171858">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.300000e+01</double>
+ <int key="NSfFlags">1044</int>
+ </object>
+ <reference key="NSControlView" ref="631907363"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSButton" id="983581711">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{370, 12}, {96, 32}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="137649770">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents">OK</string>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="983581711"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSButton" id="110527617">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{274, 12}, {96, 32}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="820689210">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents">Cancel</string>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="110527617"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">268435585</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent">.</string>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="1036501322">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 230}, {45, 17}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="52444064">
+ <int key="NSCellFlags">68288064</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents">Name:</string>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="1036501322"/>
+ <object class="NSColor" key="NSBackgroundColor" id="519536938">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="728676191">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <object class="NSColor" key="NSColor" id="528526553">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="NSTextField" id="209927002">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 205}, {38, 17}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="268808428">
+ <int key="NSCellFlags">68288064</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents">URL:</string>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="209927002"/>
+ <reference key="NSBackgroundColor" ref="519536938"/>
+ <reference key="NSTextColor" ref="728676191"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="921757931">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{74, 228}, {386, 22}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="1025899850">
+ <int key="NSCellFlags">-1804468671</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="921757931"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <object class="NSColor" key="NSBackgroundColor" id="31051313">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="90031784">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textColor</string>
+ <reference key="NSColor" ref="528526553"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSTextField" id="812603726">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{74, 203}, {386, 22}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="991096593">
+ <int key="NSCellFlags">-1804468671</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="899171858"/>
+ <reference key="NSControlView" ref="812603726"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <reference key="NSBackgroundColor" ref="31051313"/>
+ <reference key="NSTextColor" ref="90031784"/>
+ </object>
+ </object>
+ <object class="NSBrowser" id="723395462">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 60}, {440, 143}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSBrowserCell" key="NSCellPrototype">
+ <int key="NSCellFlags">67239488</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents"> </string>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.200000e+01</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ <string key="NSPathSeparator">/</string>
+ <int key="NSMinColumnWidth">100</int>
+ <int key="NSNumberOfVisibleColumns">3</int>
+ <int key="NSColumnResizingType">1</int>
+ <double key="NSPreferedColumnWidth">1.000000e+02</double>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ <int key="NSBrFlags">469843968</int>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 270}</string>
+ <reference key="NSSuperview"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
+ <string key="NSMinSize">{331, 292}</string>
+ <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">newFolder:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="631907363"/>
+ </object>
+ <int key="connectionID">21</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cancel:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="110527617"/>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">ok:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="983581711"/>
+ </object>
+ <int key="connectionID">23</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">nameField_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="921757931"/>
+ </object>
+ <int key="connectionID">24</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">urlField_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="812603726"/>
+ </object>
+ <int key="connectionID">25</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">browser_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="723395462"/>
+ </object>
+ <int key="connectionID">27</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="1005"/>
+ </object>
+ <int key="connectionID">28</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="1005"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">29</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">newFolderButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="631907363"/>
+ </object>
+ <int key="connectionID">30</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1002">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1001"/>
+ <reference key="parent" ref="1002"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1003"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1004"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="1005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1006"/>
+ </object>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="1006"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="631907363"/>
+ <reference ref="110527617"/>
+ <reference ref="921757931"/>
+ <reference ref="1036501322"/>
+ <reference ref="812603726"/>
+ <reference ref="209927002"/>
+ <reference ref="723395462"/>
+ <reference ref="983581711"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="631907363"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="732374144"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="732374144"/>
+ <reference key="parent" ref="631907363"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="983581711"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="137649770"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="137649770"/>
+ <reference key="parent" ref="983581711"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="110527617"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="820689210"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="820689210"/>
+ <reference key="parent" ref="110527617"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="1036501322"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="52444064"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="52444064"/>
+ <reference key="parent" ref="1036501322"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="209927002"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="268808428"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">12</int>
+ <reference key="object" ref="268808428"/>
+ <reference key="parent" ref="209927002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="921757931"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1025899850"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">14</int>
+ <reference key="object" ref="1025899850"/>
+ <reference key="parent" ref="921757931"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="812603726"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="991096593"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">16</int>
+ <reference key="object" ref="991096593"/>
+ <reference key="parent" ref="812603726"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">26</int>
+ <reference key="object" ref="723395462"/>
+ <reference key="parent" ref="1006"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>1.IBWindowTemplateEditedContentRect</string>
+ <string>1.NSWindowTemplate.visibleAtLaunch</string>
+ <string>1.WindowOrigin</string>
+ <string>1.editorWindowContentRectSynchronizationRect</string>
+ <string>1.windowTemplate.hasMaxSize</string>
+ <string>1.windowTemplate.hasMinSize</string>
+ <string>1.windowTemplate.maxSize</string>
+ <string>1.windowTemplate.minSize</string>
+ <string>10.IBPluginDependency</string>
+ <string>11.IBPluginDependency</string>
+ <string>12.IBPluginDependency</string>
+ <string>13.IBPluginDependency</string>
+ <string>14.IBPluginDependency</string>
+ <string>15.IBPluginDependency</string>
+ <string>16.IBPluginDependency</string>
+ <string>2.IBPluginDependency</string>
+ <string>26.IBPluginDependency</string>
+ <string>3.IBPluginDependency</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>6.IBPluginDependency</string>
+ <string>7.IBPluginDependency</string>
+ <string>8.IBPluginDependency</string>
+ <string>9.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{609, 978}, {480, 270}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{609, 978}, {480, 270}}</string>
+ <boolean value="NO" id="6"/>
+ <string>{196, 240}</string>
+ <string>{{357, 418}, {480, 270}}</string>
+ <reference ref="6"/>
+ <boolean value="YES"/>
+ <string>{331, 270}</string>
+ <string>{331, 270}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">30</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">BookmarkEditorController</string>
+ <string key="superclassName">NSWindowController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>cancel:</string>
+ <string>newFolder:</string>
+ <string>ok:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>browser_</string>
+ <string>nameField_</string>
+ <string>newFolderButton_</string>
+ <string>urlField_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSBrowser</string>
+ <string>NSTextField</string>
+ <string>NSButton</string>
+ <string>NSTextField</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/bookmark_editor_controller.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../../chrome.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmark_bar_controller.h
index 662da61..6e57bfa 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.h
+++ b/chrome/browser/cocoa/bookmark_bar_controller.h
@@ -29,9 +29,9 @@ class PrefService;
// and hiding based on the preference in the given profile.
@interface BookmarkBarController : NSViewController {
@private
+ Profile* profile_; // weak
BookmarkModel* bookmarkModel_; // weak; part of the profile owned by the
// top-level Browser object.
- PrefService* preferences_; // (ditto)
// Currently these two are always the same when not in fullscreen
// mode, but they mean slightly different things.
@@ -83,13 +83,20 @@ class PrefService;
// if needed. For fullscreen mode.
- (void)setBookmarkBarEnabled:(BOOL)enabled;
-// Actions for opening bookmarks. From a button, ...
+// Actions for manipulating bookmarks.
+// From a button, ...
- (IBAction)openBookmark:(id)sender;
-// ... or from a context menu over the button.
+// From a context menu over the button, ...
- (IBAction)openBookmarkInNewForegroundTab:(id)sender;
- (IBAction)openBookmarkInNewWindow:(id)sender;
- (IBAction)openBookmarkInIncognitoWindow:(id)sender;
+- (IBAction)editBookmark:(id)sender;
- (IBAction)deleteBookmark:(id)sender;
+// From a context menu over the bar, ...
+- (IBAction)openAllBookmarks:(id)sender;
+// Or from a context menu over either the bar or a button.
+- (IBAction)addPage:(id)sender;
+
@end
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm
index d4af000..65a8135 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller.mm
@@ -4,6 +4,7 @@
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
+#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
@@ -11,6 +12,7 @@
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
#import "chrome/browser/cocoa/bookmark_bar_view.h"
#import "chrome/browser/cocoa/bookmark_button_cell.h"
+#import "chrome/browser/cocoa/bookmark_editor_controller.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -48,8 +50,8 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
delegate:(id<BookmarkURLOpener>)delegate {
if ((self = [super initWithNibName:@"BookmarkBar"
bundle:mac_util::MainAppBundle()])) {
+ profile_ = profile;
bookmarkModel_ = profile->GetBookmarkModel();
- preferences_ = profile->GetPrefs();
parentView_ = parentView;
webContentView_ = webContentView;
infoBarsView_ = infoBarsView;
@@ -72,7 +74,7 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
NSViewMinYMargin)];
// Be sure to enable the bar before trying to show it...
barIsEnabled_ = YES;
- if (preferences_->GetBoolean(prefs::kShowBookmarkBar))
+ if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar))
[self showBookmarkBar:YES immediately:YES];
// Don't pass ourself along (as 'self') until our init is completely
@@ -181,7 +183,7 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
if (enabled) {
// Enabling the bar; set enabled then show if needed.
barIsEnabled_ = YES;
- if (preferences_->GetBoolean(prefs::kShowBookmarkBar))
+ if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar))
[self showBookmarkBar:YES immediately:YES];
} else {
// Disabling the bar; hide if visible.
@@ -232,12 +234,58 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
[delegate_ openBookmarkURL:node->GetURL() disposition:OFF_THE_RECORD];
}
+- (IBAction)editBookmark:(id)sender {
+ BookmarkNode* node = [self nodeFromMenuItem:sender];
+ // There is no real need to jump to a platform-common routine at
+ // this point (which just jumps back to objc) other than consistency
+ // across platforms.
+ //
+ // TODO(jrg): identify when we NO_TREE. I can see it in the code
+ // for the other platforms but can't find a way to trigger it in the
+ // UI.
+ BookmarkEditor::Show([[[self view] window] contentView],
+ profile_,
+ node->GetParent(),
+ node,
+ BookmarkEditor::SHOW_TREE,
+ nil);
+}
+
- (IBAction)deleteBookmark:(id)sender {
BookmarkNode* node = [self nodeFromMenuItem:sender];
bookmarkModel_->Remove(node->GetParent(),
node->GetParent()->IndexOfChild(node));
}
+- (void)openBookmarkNodesRecursive:(BookmarkNode*)node {
+ for (int i = 0; i < node->GetChildCount(); i++) {
+ BookmarkNode* child = node->GetChild(i);
+ if (child->is_url())
+ [delegate_ openBookmarkURL:child->GetURL()
+ disposition:NEW_BACKGROUND_TAB];
+ else
+ [self openBookmarkNodesRecursive:child];
+ }
+}
+
+- (IBAction)openAllBookmarks:(id)sender {
+ // TODO(jrg):
+ // Is there an easier way to get a non-const root node for the bookmark bar?
+ // I can't iterate over them unless it's non-const.
+
+ BookmarkNode* node = (BookmarkNode*)bookmarkModel_->GetBookmarkBarNode();
+ [self openBookmarkNodesRecursive:node];
+}
+
+- (IBAction)addPage:(id)sender {
+ BookmarkEditor::Show([[[self view] window] contentView],
+ profile_,
+ bookmarkModel_->GetBookmarkBarNode(),
+ nil,
+ BookmarkEditor::SHOW_TREE,
+ nil);
+}
+
// Delete all bookmarks from the bookmark bar.
- (void)clearBookmarkBar {
[buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)];
diff --git a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
index e1dbdbc..095e3bd 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
@@ -4,6 +4,7 @@
#import <Cocoa/Cocoa.h>
+#include "base/basictypes.h"
#include "base/scoped_nsobject.h"
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
#include "chrome/browser/cocoa/browser_test_helper.h"
@@ -13,16 +14,20 @@
// Pretend BookmarkURLOpener delegate to keep track of requests
@interface BookmarkURLOpenerPong : NSObject<BookmarkURLOpener> {
@public
- GURL url_;
- WindowOpenDisposition disposition_;
+ std::vector<GURL> urls_;
+ std::vector<WindowOpenDisposition> dispositions_;
}
@end
@implementation BookmarkURLOpenerPong
- (void)openBookmarkURL:(const GURL&)url
disposition:(WindowOpenDisposition)disposition {
- url_ = url;
- disposition_ = disposition;
+ urls_.push_back(url);
+ dispositions_.push_back(disposition);
+}
+- (void)clear {
+ urls_.clear();
+ dispositions_.clear();
}
@end
@@ -83,14 +88,42 @@ class BookmarkBarControllerTest : public testing::Test {
// make sure it's open so certain things aren't no-ops
[bar_ toggleBookmarkBar];
+
+ // Create a menu/item to act like a sender
+ menu_.reset([[NSMenu alloc] initWithTitle:@"I_dont_care"]);
+ menu_item_.reset([[NSMenuItem alloc]
+ initWithTitle:@"still_dont_care"
+ action:NULL
+ keyEquivalent:@""]);
+ cell_.reset([[NSButtonCell alloc] init]);
+ [menu_item_ setMenu:menu_.get()];
+ [menu_ setDelegate:cell_.get()];
+ }
+
+ // Return a menu item that points to the right URL.
+ NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) {
+ node_.reset(new BookmarkNode(gurl));
+ [cell_ setRepresentedObject:[NSValue valueWithPointer:node_.get()]];
+ return menu_item_;
}
+ // Does NOT take ownership of node.
+ NSMenuItem* ItemForBookmarkBarMenu(const BookmarkNode* node) {
+ [cell_ setRepresentedObject:[NSValue valueWithPointer:node]];
+ return menu_item_;
+ }
+
+
CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
scoped_nsobject<NSView> content_area_;
scoped_nsobject<NSView> infobar_view_;
scoped_nsobject<NSView> parent_view_;
BrowserTestHelper helper_;
scoped_nsobject<BookmarkBarController> bar_;
+ scoped_nsobject<NSMenu> menu_;
+ scoped_nsobject<NSMenuItem> menu_item_;
+ scoped_nsobject<NSButtonCell> cell_;
+ scoped_ptr<BookmarkNode> node_;
};
TEST_F(BookmarkBarControllerTest, ShowHide) {
@@ -139,8 +172,8 @@ TEST_F(BookmarkBarControllerTest, OpenBookmark) {
[cell setRepresentedObject:[NSValue valueWithPointer:node.get()]];
[bar_ openBookmark:button];
- EXPECT_EQ(pong.get()->url_, node->GetURL());
- EXPECT_EQ(pong.get()->disposition_, CURRENT_TAB);
+ EXPECT_EQ(pong.get()->urls_[0], node->GetURL());
+ EXPECT_EQ(pong.get()->dispositions_[0], CURRENT_TAB);
[bar_ setDelegate:nil];
}
@@ -152,15 +185,6 @@ TEST_F(BookmarkBarControllerTest, OpenBookmarkFromMenus) {
init]);
[bar_ setDelegate:pong.get()];
- scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"I_dont_care"]);
- scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc]
- initWithTitle:@"still_dont_care"
- action:NULL
- keyEquivalent:@""]);
- scoped_nsobject<NSButtonCell> cell([[NSButtonCell alloc] init]);
- [item setMenu:menu.get()];
- [menu setDelegate:cell];
-
const char* urls[] = { "http://walla.walla.ding.dong.com",
"http://i_dont_know.com",
"http://cee.enn.enn.dot.com" };
@@ -173,13 +197,14 @@ TEST_F(BookmarkBarControllerTest, OpenBookmarkFromMenus) {
for (unsigned int i = 0;
i < sizeof(dispositions)/sizeof(dispositions[0]);
i++) {
- scoped_ptr<BookmarkNode> node(new BookmarkNode(GURL(urls[i])));
- [cell setRepresentedObject:[NSValue valueWithPointer:node.get()]];
- [bar_ performSelector:selectors[i] withObject:item.get()];
- EXPECT_EQ(pong.get()->url_, node->GetURL());
- EXPECT_EQ(pong.get()->disposition_, dispositions[i]);
- [cell setRepresentedObject:nil];
+ GURL gurl(urls[i]);
+ [bar_ performSelector:selectors[i]
+ withObject:ItemForBookmarkBarMenu(gurl)];
+ EXPECT_EQ(pong.get()->urls_[0], gurl);
+ EXPECT_EQ(pong.get()->dispositions_[0], dispositions[i]);
+ [pong clear];
}
+ [bar_ setDelegate:nil];
}
TEST_F(BookmarkBarControllerTest, TestAddRemoveAndClear) {
@@ -278,6 +303,69 @@ TEST_F(BookmarkBarControllerTest, CheckForGrowth) {
EXPECT_GE(frame_2.origin.x, frame_1.origin.x + frame_1.size.width);
}
+TEST_F(BookmarkBarControllerTest, DeleteBookmark) {
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+
+ const char* urls[] = { "https://secret.url.com",
+ "http://super.duper.web.site.for.doodz.gov",
+ "http://www.foo-bar-baz.com/" };
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ for (unsigned int i = 0; i < arraysize(urls); i++) {
+ model->AddURL(parent, parent->GetChildCount(),
+ L"title", GURL(urls[i]));
+ }
+ EXPECT_EQ(3, parent->GetChildCount());
+ const BookmarkNode* middle_node = parent->GetChild(1);
+
+ NSMenuItem* item = ItemForBookmarkBarMenu(middle_node);
+ [bar_ deleteBookmark:item];
+ EXPECT_EQ(2, parent->GetChildCount());
+ EXPECT_EQ(parent->GetChild(0)->GetURL(), GURL(urls[0]));
+ // node 2 moved into spot 1
+ EXPECT_EQ(parent->GetChild(1)->GetURL(), GURL(urls[2]));
+}
+
+TEST_F(BookmarkBarControllerTest, OpenAllBookmarks) {
+ scoped_nsobject<BookmarkURLOpenerPong> pong([[BookmarkURLOpenerPong alloc]
+ init]);
+ [bar_ setDelegate:pong.get()];
+
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ // { one, { two-one, two-two }, three }
+ model->AddURL(parent, parent->GetChildCount(),
+ L"title", GURL("http://one.com"));
+ const BookmarkNode* folder = model->AddGroup(parent,
+ parent->GetChildCount(),
+ L"group");
+ model->AddURL(folder, folder->GetChildCount(),
+ L"title", GURL("http://two-one.com"));
+ model->AddURL(folder, folder->GetChildCount(),
+ L"title", GURL("http://two-two.com"));
+ model->AddURL(parent, parent->GetChildCount(),
+ L"title", GURL("https://three.com"));
+ [bar_ openAllBookmarks:nil];
+
+ EXPECT_EQ(pong.get()->urls_.size(), 4U);
+ EXPECT_EQ(pong.get()->dispositions_.size(), 4U);
+
+ // I can't use EXPECT_EQ() here since the macro can't expand
+ // properly (no way to print the value of an iterator).
+ std::vector<GURL>::iterator i;
+ std::vector<GURL>::iterator begin = pong.get()->urls_.begin();
+ std::vector<GURL>::iterator end = pong.get()->urls_.end();
+ i = find(begin, end, GURL("http://two-one.com"));
+ EXPECT_FALSE(i == end);
+ i = find(begin, end, GURL("https://three.com"));
+ EXPECT_FALSE(i == end);
+ i = find(begin, end, GURL("https://will-not-be-found.com"));
+ EXPECT_TRUE(i == end);
+
+ EXPECT_EQ(pong.get()->dispositions_[3], NEW_BACKGROUND_TAB);
+
+ [bar_ setDelegate:nil];
+}
+
// TODO(jrg): write a test to confirm that nodeFavIconLoaded calls
// checkForBookmarkButtonGrowth:.
@@ -300,4 +388,9 @@ TEST_F(BookmarkBarControllerTest, Display) {
[[bar_ view] display];
}
+// Cannot test these methods since they simply call a single static
+// method, BookmarkEditor::Show(), which is impossible to mock.
+// editBookmark:, addPage:
+
+
} // namespace
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.h b/chrome/browser/cocoa/bookmark_editor_controller.h
new file mode 100644
index 0000000..e297ea3
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_editor_controller.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COCOA_BOOKMARK_EDITOR_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_BOOKMARK_EDITOR_CONTROLLER_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_ptr.h"
+#include "base/scoped_nsobject.h"
+#include "chrome/browser/bookmarks/bookmark_editor.h"
+
+// A controller for the bookmark editor, opened with Edit... from the
+// context menu of a bookmark button.
+@interface BookmarkEditorController : NSWindowController {
+ @private
+ IBOutlet NSTextField* nameField_;
+ IBOutlet NSTextField* urlField_;
+ IBOutlet NSBrowser* browser_;
+ IBOutlet NSButton* newFolderButton_;
+
+ NSWindow* parentWindow_;
+ Profile* profile_; // weak
+ const BookmarkNode* parentNode_; // weak; owned by the model
+ const BookmarkNode* node_; // weak; owned by the model
+ BookmarkEditor::Configuration configuration_;
+ scoped_ptr<BookmarkEditor::Handler> handler_; // we take ownership
+
+ scoped_nsobject<NSString> initialName_;
+ scoped_nsobject<NSString> initialUrl_;
+}
+
+- (id)initWithParentWindow:(NSWindow*)parentWindow
+ profile:(Profile*)profile
+ parent:(const BookmarkNode*)parent
+ node:(const BookmarkNode*)node
+ configuration:(BookmarkEditor::Configuration)configuration
+ handler:(BookmarkEditor::Handler*)handler;
+
+// Actions for the buttons at the bottom of the window.
+- (IBAction)newFolder:(id)sender;
+- (IBAction)cancel:(id)sender;
+- (IBAction)ok:(id)sender;
+@end
+
+@interface BookmarkEditorController(TestingAPI)
+@property (assign) NSString* displayName;
+@property (assign) NSString* displayURL;
+@end
+
+
+#endif /* CHROME_BROWSER_COCOA_BOOKMARK_EDITOR_CONTROLLER_H_ */
+
diff --git a/chrome/browser/cocoa/bookmark_editor_controller.mm b/chrome/browser/cocoa/bookmark_editor_controller.mm
new file mode 100644
index 0000000..704c56e
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_editor_controller.mm
@@ -0,0 +1,186 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/mac_util.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/bookmarks/bookmark_editor.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/profile.h"
+#import "chrome/browser/cocoa/bookmark_editor_controller.h"
+
+@interface BookmarkEditorController(Private)
+// Run the bookmark editor as a modal sheet. Does not block.
+- (void)runModal;
+@end
+
+// static; implemented for each platform.
+void BookmarkEditor::Show(gfx::NativeView parent_hwnd,
+ Profile* profile,
+ const BookmarkNode* parent,
+ const BookmarkNode* node,
+ Configuration configuration,
+ Handler* handler) {
+ NSWindow* window = [parent_hwnd window];
+ BookmarkEditorController* controller = [[BookmarkEditorController alloc]
+ initWithParentWindow:window
+ profile:profile
+ parent:parent
+ node:node
+ configuration:configuration
+ handler:handler];
+ [controller runModal];
+}
+
+
+@implementation BookmarkEditorController
+
+- (id)initWithParentWindow:(NSWindow*)parentWindow
+ profile:(Profile*)profile
+ parent:(const BookmarkNode*)parent
+ node:(const BookmarkNode*)node
+ configuration:(BookmarkEditor::Configuration)configuration
+ handler:(BookmarkEditor::Handler*)handler {
+ NSString* nibpath = [mac_util::MainAppBundle()
+ pathForResource:@"BookmarkEditor"
+ ofType:@"nib"];
+ if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
+ parentWindow_ = parentWindow;
+ profile_ = profile;
+ parentNode_ = parent;
+ // "Add Page..." has no "node" so this may be NULL.
+ node_ = node;
+ configuration_ = configuration;
+ handler_.reset(handler);
+ }
+ return self;
+}
+
+- (void)awakeFromNib {
+ // Set text fields to match our bookmark. If the node is NULL we
+ // arrived here from an "Add Page..." item in a context menu.
+ if (node_) {
+ initialName_.reset([base::SysWideToNSString(node_->GetTitle()) retain]);
+ std::string url_string = node_->GetURL().possibly_invalid_spec();
+ initialUrl_.reset([[NSString stringWithUTF8String:url_string.c_str()]
+ retain]);
+ } else {
+ initialName_.reset([@"" retain]);
+ initialUrl_.reset([@"" retain]);
+ }
+ [nameField_ setStringValue:initialName_];
+ [urlField_ setStringValue:initialUrl_];
+
+ if (configuration_ == BookmarkEditor::SHOW_TREE) {
+ // build the tree et al
+ NOTIMPLEMENTED();
+ } else {
+ // Remember the NSBrowser's height; we will shrink our frame by that
+ // much.
+ NSRect frame = [[self window] frame];
+ CGFloat browserHeight = [browser_ frame].size.height;
+ frame.size.height -= browserHeight;
+ frame.origin.y += browserHeight;
+ // Remove the NSBrowser and "new folder" button.
+ [browser_ removeFromSuperview];
+ [newFolderButton_ removeFromSuperview];
+ // Finally, commit the size change.
+ [[self window] setFrame:frame display:YES];
+ }
+}
+
+/* TODO(jrg):
+// Implementing this informal protocol allows us to open the sheet
+// somewhere other than at the top of the window. NOTE: this means
+// that I, the controller, am also the window's delegate.
+- (NSRect)window:(NSWindow*)window willPositionSheet:(NSWindow*)sheet
+ usingRect:(NSRect)rect {
+ // adjust rect.origin.y to be the bottom of the toolbar
+ return rect;
+}
+*/
+
+// TODO(jrg): consider NSModalSession.
+- (void)runModal {
+ [NSApp beginSheet:[self window]
+ modalForWindow:parentWindow_
+ modalDelegate:self
+ didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
+ contextInfo:nil];
+}
+
+// TODO(jrg)
+- (IBAction)newFolder:(id)sender {
+ NOTIMPLEMENTED();
+}
+
+- (IBAction)cancel:(id)sender {
+ [NSApp endSheet:[self window]];
+}
+
+// TODO(jrg): Once the tree is available edits may be more extensive
+// than just name/url.
+- (IBAction)ok:(id)sender {
+ NSString *name = [nameField_ stringValue];
+ NSString *url = [urlField_ stringValue];
+
+ if ((![name isEqual:initialName_]) ||
+ (![url isEqual:initialUrl_])) {
+ std::wstring newTitle = base::SysNSStringToWide(name);
+ GURL newURL = GURL([url UTF8String]);
+ if (!newURL.is_valid()) {
+ // Mimic observed friendliness from Windows
+ newURL = GURL([[NSString stringWithFormat:@"http://%@", url] UTF8String]);
+ }
+ if (!newURL.is_valid()) {
+ // Silently ignoring a bad URL is unfriendly.
+ newURL = GURL();
+ }
+ int index = 0;
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ if (node_) {
+ index = parentNode_->IndexOfChild(node_);
+ model->Remove(parentNode_, index);
+ } else {
+ index = parentNode_->GetChildCount();
+ }
+ const BookmarkNode* node = model->AddURL(parentNode_, index,
+ newTitle, newURL);
+ // Honor handler semantics: callback on node creation
+ if (handler_.get())
+ handler_->NodeCreated(node);
+ }
+
+ [NSApp endSheet:[self window]];
+}
+
+- (void)didEndSheet:(NSWindow*)sheet
+ returnCode:(int)returnCode
+ contextInfo:(void*)contextInfo {
+ [[self window] orderOut:self];
+
+ // BookmarkEditor::Show() will create us then run away. Unusually
+ // for a controller, we are responsible for deallocating ourself.
+ [self autorelease];
+}
+
+
+- (NSString*)displayName {
+ return [nameField_ stringValue];
+}
+
+- (NSString*)displayURL {
+ return [urlField_ stringValue];
+}
+
+- (void)setDisplayName:(NSString*)name {
+ [nameField_ setStringValue:name];
+}
+
+- (void)setDisplayURL:(NSString*)name {
+ [urlField_ setStringValue:name];
+}
+
+@end // BookmarkEditorController
+
diff --git a/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
new file mode 100644
index 0000000..c6bfa83
--- /dev/null
+++ b/chrome/browser/cocoa/bookmark_editor_controller_unittest.mm
@@ -0,0 +1,105 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_nsobject.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 "testing/gtest/include/gtest/gtest.h"
+
+class BookmarkEditorControllerTest : public testing::Test {
+ public:
+ CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
+ BrowserTestHelper helper_;
+ scoped_nsobject<BookmarkEditorController> bar_;
+};
+
+// Lots TODO here.
+
+TEST_F(BookmarkEditorControllerTest, NoNodeNoTree) {
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ const BookmarkNode* node = NULL;
+
+ scoped_nsobject<BookmarkEditorController>
+ controller([[BookmarkEditorController alloc]
+ initWithParentWindow:cocoa_helper_.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]);
+}
+
+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, L"ooh title",
+ GURL(url_name));
+
+ scoped_nsobject<BookmarkEditorController>
+ controller([[BookmarkEditorController alloc]
+ initWithParentWindow:cocoa_helper_.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([@"ooh title" isEqual:[controller displayName]]);
+ EXPECT_TRUE([[NSString stringWithCString:url_name]
+ isEqual:[controller displayURL]]);
+}
+
+TEST_F(BookmarkEditorControllerTest, UserEditsStuff) {
+ 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, L"ooh title",
+ GURL(url_name));
+
+ scoped_nsobject<BookmarkEditorController>
+ controller([[BookmarkEditorController alloc]
+ initWithParentWindow:cocoa_helper_.window()
+ profile:helper_.profile()
+ parent:parent
+ node:node
+ configuration:BookmarkEditor::NO_TREE
+ handler:nil]);
+
+ EXPECT_NE((NSWindow*)nil, [controller window]); // Forces a nib load
+
+ // No change.
+ [controller ok:nil];
+ const BookmarkNode* child = parent->GetChild(0);
+ EXPECT_EQ(child->GetTitle(), L"ooh title");
+ EXPECT_EQ(child->GetURL(), GURL(url_name));
+
+ // Change just the title.
+ [controller setDisplayName:@"whamma jamma bamma"];
+ [controller ok:nil];
+ child = parent->GetChild(0);
+ EXPECT_EQ(child->GetTitle(), L"whamma jamma bamma");
+ EXPECT_EQ(child->GetURL(), GURL(url_name));
+
+ // Change just the URL
+ [controller setDisplayURL:@"http://yellow-sneakers.com/"];
+ [controller ok:nil];
+ child = parent->GetChild(0);
+ EXPECT_EQ(child->GetTitle(), L"whamma jamma bamma");
+ EXPECT_EQ(child->GetURL(), GURL("http://yellow-sneakers.com/"));
+}
+
+
+
+
+
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 8c20b27..04df059 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -51,7 +51,7 @@
'../views/controls/table/table_view_unittest.cc',
'../views/focus/focus_manager_unittest.cc',
'../views/grid_layout_unittest.cc',
- ]
+ ]
},
'includes': [
'../build/common.gypi',
@@ -758,6 +758,8 @@
'browser/cocoa/bookmark_bar_view.mm',
'browser/cocoa/bookmark_button_cell.h',
'browser/cocoa/bookmark_button_cell.mm',
+ 'browser/cocoa/bookmark_editor_controller.h',
+ 'browser/cocoa/bookmark_editor_controller.mm',
'browser/cocoa/bookmark_menu_bridge.h',
'browser/cocoa/bookmark_menu_bridge.mm',
'browser/cocoa/bookmark_menu_cocoa_controller.h',
@@ -2608,6 +2610,7 @@
# them.
'app/nibs/About.xib',
'app/nibs/BookmarkBar.xib',
+ 'app/nibs/BookmarkEditor.xib',
'app/nibs/BrowserWindow.xib',
'app/nibs/ClearBrowsingData.xib',
'app/nibs/DownloadItem.xib',
@@ -3662,6 +3665,7 @@
'browser/cocoa/bookmark_bar_controller_unittest.mm',
'browser/cocoa/bookmark_bar_view_unittest.mm',
'browser/cocoa/bookmark_button_cell_unittest.mm',
+ 'browser/cocoa/bookmark_editor_controller_unittest.mm',
'browser/cocoa/bookmark_menu_bridge_unittest.mm',
'browser/cocoa/bookmark_menu_cocoa_controller_unittest.mm',
'browser/cocoa/browser_window_cocoa_unittest.mm',