diff options
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/location_bar_fieldeditor_unittest.mm | 88 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.h | 17 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.mm | 45 | ||||
-rw-r--r-- | chrome/chrome.gyp | 1 |
5 files changed, 153 insertions, 4 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index f363008..d071f7c 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -766,4 +766,10 @@ willPositionSheet:(NSWindow *)sheet browser_->ExecuteCommand(command); } +- (id)windowWillReturnFieldEditor:(NSWindow*)sender toObject:(id)obj { + // Ask the toolbar controller if it wants to return a custom field editor + // for the specific object. + return [toolbarController_ customFieldEditorForObject:obj]; +} + @end diff --git a/chrome/browser/cocoa/location_bar_fieldeditor_unittest.mm b/chrome/browser/cocoa/location_bar_fieldeditor_unittest.mm new file mode 100644 index 0000000..fca4411 --- /dev/null +++ b/chrome/browser/cocoa/location_bar_fieldeditor_unittest.mm @@ -0,0 +1,88 @@ +// 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 "chrome/browser/cocoa/toolbar_controller.h" + +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace { +int NumTypesOnPasteboard(NSPasteboard* pb) { + return [[pb types] count]; +} + +void ClearPasteboard(NSPasteboard* pb) { + [pb declareTypes:[NSArray array] owner:nil]; +} + +bool NoRichTextOnClipboard(NSPasteboard* pb) { + return ([pb dataForType:NSRTFPboardType] == nil) && + ([pb dataForType:NSRTFDPboardType] == nil) && + ([pb dataForType:NSHTMLPboardType] == nil); +} + +bool ClipboardContainsText(NSPasteboard* pb, NSString* cmp) { + NSString* clipboard_text = [pb stringForType:NSStringPboardType]; + return [clipboard_text isEqualToString:cmp]; +} + +} // namespace + +class LocationBarFieldEditorTest : public PlatformTest { + public: + virtual void SetUp() { + PlatformTest::SetUp(); + pb_ = [NSPasteboard pasteboardWithUniqueName]; + } + + virtual void TearDown() { + [pb_ releaseGlobally]; + pb_ = nil; + PlatformTest::TearDown(); + } + + NSPasteboard *clipboard() { + DCHECK(pb_); + return pb_; + } + + private: + NSPasteboard *pb_; +}; + +TEST_F(LocationBarFieldEditorTest, CutCopyTest) { + // Make sure pasteboard is empty before we start. + ASSERT_EQ(NumTypesOnPasteboard(clipboard()), 0); + + NSString* test_string_1 = @"astring"; + NSString* test_string_2 = @"another string"; + + scoped_nsobject<LocationBarFieldEditor> field_editor( + [[LocationBarFieldEditor alloc] init]); + [field_editor.get() setRichText:YES]; + + // Put some text on the clipboard. + [field_editor.get() setString:test_string_1]; + [field_editor.get() selectAll:nil]; + [field_editor.get() alignRight:nil]; // Add a rich text attribute. + ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); + + // Check that copying it works and we only get plain text. + NSPasteboard* pb = clipboard(); + [field_editor.get() performCopy:pb]; + ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); + ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_1)); + + // Check that cutting it works and we only get plain text. + [field_editor.get() setString:test_string_2]; + [field_editor.get() selectAll:nil]; + [field_editor.get() alignLeft:nil]; // Add a rich text attribute. + [field_editor.get() performCut:pb]; + ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); + ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_2)); + ASSERT_EQ([[field_editor.get() textStorage] length], 0U); +} diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h index 1909800..1aa38bb 100644 --- a/chrome/browser/cocoa/toolbar_controller.h +++ b/chrome/browser/cocoa/toolbar_controller.h @@ -8,6 +8,7 @@ #import <Cocoa/Cocoa.h> #include "base/scoped_ptr.h" +#include "base/scoped_nsobject.h" #import "chrome/browser/cocoa/command_observer_bridge.h" class CommandUpdater; @@ -18,6 +19,15 @@ class TabContents; class ToolbarModel; class ToolbarView; +// Field editor used for the location bar. +@interface LocationBarFieldEditor : NSTextView +// Copy contents of the TextView to the designated clipboard as plain text. +- (void)performCopy:(NSPasteboard*)pb; + +// Same as above, note that this calls through to performCopy. +- (void)performCut:(NSPasteboard*)pb; +@end + // A controller for the toolbar in the browser window. Manages updating the // state for location bar and back/fwd/reload/go buttons. @@ -28,6 +38,7 @@ class ToolbarView; Profile* profile_; // weak, one per window scoped_ptr<CommandObserverBridge> commandObserver_; scoped_ptr<LocationBarViewMac> locationBarView_; + scoped_nsobject<LocationBarFieldEditor> locationBarFieldEditor_; // strong // The ordering is important for unit tests. If new items are added or the // ordering is changed, make sure to update |-toolbarViews| and the @@ -49,6 +60,12 @@ class ToolbarView; // Get the C++ bridge object representing the location bar for this tab. - (LocationBar*)locationBar; +// Called by the Window delegate so we can provide a custom field editor if +// needed. +// Note that this may be called for objects unrelated to the toolbar. +// returns nil if we don't want to override the custom field editor for |obj|. +- (id)customFieldEditorForObject:(id)obj; + // Make the location bar the first responder, if possible. - (void)focusLocationBar; diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index 74f319f..81fdf04 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -14,6 +14,30 @@ static NSString* const kStarImageName = @"star"; static NSString* const kStarredImageName = @"starred"; +@implementation LocationBarFieldEditor +- (void)copy:(id)sender { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [self performCopy:pb]; +} + +- (void)cut:(id)sender { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [self performCut:pb]; +} + +- (void)performCopy:(NSPasteboard*)pb { + [pb declareTypes:[NSArray array] owner:nil]; + [self writeSelectionToPasteboard:pb types: + [NSArray arrayWithObject:NSStringPboardType]]; +} + +- (void)performCut:(NSPasteboard*)pb { + [self performCopy:pb]; + [self delete:nil]; +} + +@end + @interface ToolbarController(Private) - (void)initCommandStatus:(CommandUpdater*)commands; @end @@ -51,10 +75,6 @@ static NSString* const kStarredImageName = @"starred"; [locationBar_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; } -- (void)dealloc { - [super dealloc]; -} - - (LocationBar*)locationBar { return locationBarView_.get(); } @@ -121,6 +141,23 @@ static NSString* const kStarredImageName = @"starred"; [goButton_ setTag:tag]; } +- (id)customFieldEditorForObject:(id)obj { + if (obj == locationBar_) { + // Lazilly construct Field editor, Cocoa UI code always runs on the + // same thread, so there shoudn't be a race condition here. + if (locationBarFieldEditor_.get() == nil) { + locationBarFieldEditor_.reset([[LocationBarFieldEditor alloc] init]); + } + + // This needs to be called every time, otherwise notifications + // aren't sent correctly. + DCHECK(locationBarFieldEditor_.get()); + [locationBarFieldEditor_.get() setFieldEditor:YES]; + return locationBarFieldEditor_.get(); + } + return nil; +} + // Returns an array of views in the order of the outlets above. - (NSArray*)toolbarViews { return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_, diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 4684d58..f0ac4cb 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -3283,6 +3283,7 @@ 'browser/cocoa/find_bar_view_unittest.mm', 'browser/cocoa/location_bar_cell_unittest.mm', 'browser/cocoa/location_bar_view_mac_unittest.mm', + 'browser/cocoa/location_bar_fieldeditor_unittest.mm', 'browser/cocoa/gradient_button_cell_unittest.mm', 'browser/cocoa/grow_box_view_unittest.mm', 'browser/cocoa/preferences_window_controller_unittest.mm', |