diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-26 19:13:08 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-26 19:13:08 +0000 |
commit | d665d12de993bc2eb904cfa9607661ffc6f553b9 (patch) | |
tree | 35d625564c0ac77b9e1a79dc098c677a02ac21ca | |
parent | 64c67f0fdbca63433f52127b3725bcd2c3417b36 (diff) | |
download | chromium_src-d665d12de993bc2eb904cfa9607661ffc6f553b9.zip chromium_src-d665d12de993bc2eb904cfa9607661ffc6f553b9.tar.gz chromium_src-d665d12de993bc2eb904cfa9607661ffc6f553b9.tar.bz2 |
[Mac] Adjust Omnibox implementation to not break undo chain.
This does not fix undo, it just makes the implementation break it
less.
BUG=18084
TEST=Omnibox should continue to work.
Review URL: http://codereview.chromium.org/337027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30071 0039d316-1c4b-4281-b951-d872f2087c98
4 files changed, 102 insertions, 1 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index 0fe9e1e..27c25a9 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -430,7 +430,7 @@ void AutocompleteEditViewMac::SetText(const std::wstring& display_text) { range:ComponentToNSRange(parts.scheme)]; } - [field_ setObjectValue:as]; + [field_ setAttributedStringValue:as]; // TODO(shess): This may be an appropriate place to call: // controller_->OnChanged(); diff --git a/chrome/browser/cocoa/autocomplete_text_field.h b/chrome/browser/cocoa/autocomplete_text_field.h index 58e514c..c101eed 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.h +++ b/chrome/browser/cocoa/autocomplete_text_field.h @@ -77,6 +77,11 @@ class AutocompleteTextFieldObserver { // enough to scroll. - (CGFloat)availableDecorationWidth; +// Superclass aborts editing before changing the string, which causes +// problems for undo. This version modifies the field editor's +// contents if the control is already being edited. +- (void)setAttributedStringValue:(NSAttributedString*)aString; + @end #endif // CHROME_BROWSER_COCOA_AUTOCOMPLETE_TEXT_FIELD_H_ diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm index 3071519..182a8b3 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.mm +++ b/chrome/browser/cocoa/autocomplete_text_field.mm @@ -193,4 +193,19 @@ return NO; } +- (void)setAttributedStringValue:(NSAttributedString*)aString { + NSTextView* editor = static_cast<NSTextView*>([self currentEditor]); + if (!editor) { + [super setAttributedStringValue:aString]; + } else { + // -currentEditor is defined to return NSText*, make sure our + // assumptions still hold, here. + DCHECK([editor isKindOfClass:[NSTextView class]]); + + NSTextStorage* textStorage = [editor textStorage]; + DCHECK(textStorage); + [textStorage setAttributedString:aString]; + } +} + @end diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm index dfa4183..4a3f208 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm @@ -578,4 +578,85 @@ TEST_F(AutocompleteTextFieldTest, SecurityIconMouseDown) { [field_ mouseDown:event]; } +// Verify that -setAttributedStringValue: works as expected when +// focussed or when not focussed. Our code mostly depends on about +// whether -stringValue works right. +TEST_F(AutocompleteTextFieldTest, SetAttributedStringBaseline) { + EXPECT_EQ(nil, [field_ currentEditor]); + + // So that we can set rich text. + [field_ setAllowsEditingTextAttributes:YES]; + + // Set an attribute different from the field's default so we can + // tell we got the same string out as we put in. + NSFont* font = [NSFont fontWithDescriptor:[[field_ font] fontDescriptor] + size:[[field_ font] pointSize] + 2]; + NSDictionary* attributes = + [NSDictionary dictionaryWithObject:font + forKey:NSFontAttributeName]; + static const NSString* kString = @"This is a test"; + scoped_nsobject<NSAttributedString> attributedString( + [[NSAttributedString alloc] initWithString:kString + attributes:attributes]); + + // Check that what we get back looks like what we put in. + EXPECT_FALSE([[field_ stringValue] isEqualToString:kString]); + [field_ setAttributedStringValue:attributedString]; + EXPECT_TRUE([[field_ attributedStringValue] + isEqualToAttributedString:attributedString]); + EXPECT_TRUE([[field_ stringValue] isEqualToString:kString]); + + // Try that again with focus. + cocoa_helper_.makeFirstResponder(field_); + EXPECT_TRUE([field_ currentEditor]); + + // Check that what we get back looks like what we put in. + [field_ setStringValue:@""]; + EXPECT_FALSE([[field_ stringValue] isEqualToString:kString]); + [field_ setAttributedStringValue:attributedString]; + EXPECT_TRUE([[field_ attributedStringValue] + isEqualToAttributedString:attributedString]); + EXPECT_TRUE([[field_ stringValue] isEqualToString:kString]); +} + +// -setAttributedStringValue: shouldn't reset the undo state if things +// are being editted. +TEST_F(AutocompleteTextFieldTest, SetAttributedStringUndo) { + NSColor* redColor = [NSColor redColor]; + NSDictionary* attributes = + [NSDictionary dictionaryWithObject:redColor + forKey:NSForegroundColorAttributeName]; + static const NSString* kString = @"This is a test"; + scoped_nsobject<NSAttributedString> attributedString( + [[NSAttributedString alloc] initWithString:kString + attributes:attributes]); + + cocoa_helper_.makeFirstResponder(field_); + EXPECT_TRUE([field_ currentEditor]); + NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]); + NSUndoManager* undoManager = [editor undoManager]; + EXPECT_TRUE(undoManager); + + // Nothing to undo, yet. + EXPECT_FALSE([undoManager canUndo]); + + // Starting an editing action creates an undoable item. + [editor shouldChangeTextInRange:NSMakeRange(0, 0) replacementString:@""]; + [editor didChangeText]; + EXPECT_TRUE([undoManager canUndo]); + + // -setStringValue: resets the editor's undo chain. + [field_ setStringValue:kString]; + EXPECT_FALSE([undoManager canUndo]); + + // Verify that -setAttributedStringValue: does not reset the + // editor's undo chain. + [field_ setStringValue:@""]; + [editor shouldChangeTextInRange:NSMakeRange(0, 0) replacementString:@""]; + [editor didChangeText]; + EXPECT_TRUE([undoManager canUndo]); + [field_ setAttributedStringValue:attributedString]; + EXPECT_TRUE([undoManager canUndo]); +} + } // namespace |