diff options
author | pamg@google.com <pamg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 22:01:07 +0000 |
---|---|---|
committer | pamg@google.com <pamg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 22:01:07 +0000 |
commit | 405dfb4047a28defa718f5d2d6e7fa16497f927b (patch) | |
tree | 934bbf26555028ca667d873eb30a1501d7356594 | |
parent | d05aa247ac300beabb8b13bc5fab88b549a1af54 (diff) | |
download | chromium_src-405dfb4047a28defa718f5d2d6e7fa16497f927b.zip chromium_src-405dfb4047a28defa718f5d2d6e7fa16497f927b.tar.gz chromium_src-405dfb4047a28defa718f5d2d6e7fa16497f927b.tar.bz2 |
Refactor security-icon code to a more general form, also more consistent with
the Windows implementation, in preparation for implementing page actions.
BUG=14899, 22922, 12281
TEST=unit tests included
Review URL: http://codereview.chromium.org/264037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29827 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 319 insertions, 132 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h index 51bb40e..f43f218 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h @@ -96,7 +96,6 @@ class AutocompleteEditViewMac : public AutocompleteEditView, virtual bool CanPasteAndGo(); virtual int GetPasteActionStringId(); virtual void OnPasteAndGo(); - virtual void OnSecurityIconClicked(); virtual void OnFrameChanged(); // Helper functions for use from AutocompleteEditHelper Objective-C diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index 0fe9e1e..8ac115e 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -16,10 +16,8 @@ #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" -#include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/cocoa/event_utils.h" -#include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "grit/generated_resources.h" @@ -632,16 +630,6 @@ bool AutocompleteEditViewMac::CanPasteAndGo() { model_->CanPasteAndGo(GetClipboardText(g_browser_process->clipboard())); } -void AutocompleteEditViewMac::OnSecurityIconClicked() { - TabContents* tab = BrowserList::GetLastActive()->GetSelectedTabContents(); - NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); - if (!nav_entry) { - NOTREACHED(); - return; - } - tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); -} - int AutocompleteEditViewMac::GetPasteActionStringId() { DCHECK(CanPasteAndGo()); diff --git a/chrome/browser/cocoa/autocomplete_text_field.h b/chrome/browser/cocoa/autocomplete_text_field.h index 58e514c..e8cbbd7 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.h +++ b/chrome/browser/cocoa/autocomplete_text_field.h @@ -50,10 +50,6 @@ class AutocompleteTextFieldObserver { // search" into |field_|. virtual void OnPasteAndGo() = 0; - // Called when the user clicks the hint icon (i.e. the security icon) in the - // location bar. - virtual void OnSecurityIconClicked() = 0; - // Called when the field's frame changes. virtual void OnFrameChanged() = 0; }; diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm index 91ac998..0b17415 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.mm +++ b/chrome/browser/cocoa/autocomplete_text_field.mm @@ -143,11 +143,11 @@ return; } - // Check to see if the user clicked the hint icon in the cell. If so, we need - // to display the page info window. - const NSRect hintIconFrame = [cell hintImageFrameForFrame:[self bounds]]; + // Check to see if the user clicked the security hint icon in the cell. If so, + // we need to display the page info window. + const NSRect hintIconFrame = [cell securityImageFrameForFrame:[self bounds]]; if (NSMouseInRect(location, hintIconFrame, [self isFlipped])) { - observer_->OnSecurityIconClicked(); + [cell onSecurityIconMousePressed]; return; } diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.h b/chrome/browser/cocoa/autocomplete_text_field_cell.h index e158e4a..2aa04a8 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_cell.h +++ b/chrome/browser/cocoa/autocomplete_text_field_cell.h @@ -5,6 +5,7 @@ #import <Cocoa/Cocoa.h> #include "base/scoped_nsobject.h" +#include "chrome/browser/cocoa/location_bar_view_mac.h" // AutocompleteTextFieldCell customizes the look of the Omnibox text // field. The border and focus ring are modified, as is the font @@ -26,13 +27,10 @@ // side of the field. Exclusive WRT |keywordString_|; scoped_nsobject<NSAttributedString> hintString_; - // Icon that represents the state of the SSL connection - scoped_nsobject<NSImage> hintIcon_; - - // Optional text that appears to the right of the hint icon which - // appears only alongside the icon (i.e., it's possible to display a - // hintIcon without an hintIconLabel, but not vice-versa). - scoped_nsobject<NSAttributedString> hintIconLabel_; + // View showing the state of the SSL connection. Owned by the location bar. + // Display is exclusive WRT the |hintString_| and |keywordString_|. + // This may be NULL during testing. + LocationBarViewMac::SecurityImageView* security_image_view_; } // Chooses |partialString| if |width| won't fit |fullString|. Strings @@ -54,9 +52,11 @@ availableWidth:(CGFloat)width; - (void)clearKeywordAndHint; -// Sets the hint icon and optional icon label. If |icon| is nil, the current -// icon is cleared. If |label| is provided, |color| must be provided as well. -- (void)setHintIcon:(NSImage*)icon label:(NSString*)label color:(NSColor*)color; +- (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view; + +// Called when the security icon is visible and clicked. Passed through to the +// security_image_view_ to handle the click (i.e., show the page info dialog). +- (void)onSecurityIconMousePressed; // Return the portion of the cell to show the text cursor over. - (NSRect)textCursorFrameForFrame:(NSRect)cellFrame; @@ -65,8 +65,9 @@ // corresponds to the frame with our added decorations sliced off. - (NSRect)textFrameForFrame:(NSRect)cellFrame; -// Return the portion of the cell to use for displaing the |hintIcon_|. -- (NSRect)hintImageFrameForFrame:(NSRect)cellFrame; +// Return the portion of the cell to use for displaying the security (SSL lock) +// icon, leaving space for its label if any. +- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame; @end @@ -75,7 +76,6 @@ @property(readonly) NSAttributedString* keywordString; @property(readonly) NSAttributedString* hintString; -@property(readonly) NSImage* hintIcon; @property(readonly) NSAttributedString* hintIconLabel; @end diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm index 929fd44..56581ce 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm @@ -41,11 +41,11 @@ const NSInteger kKeywordHintImageBaseline = -6; // use that. const NSInteger kBaselineOffset = 4; -// The amount of padding on either side reserved for drawing the hint icon -const NSInteger kHintIconHorizontalPad = 3; +// The amount of padding on either side reserved for drawing an icon. +const NSInteger kIconHorizontalPad = 3; // How far to shift bounding box of hint icon label down from top of field. -const NSInteger kHintIconLabelYOffset = 7; +const NSInteger kIconLabelYOffset = 7; // How far the editor insets itself, for purposes of determining if // decorations need to be trimmed. @@ -196,27 +196,12 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { hintString_.reset(); } -- (void)setHintIcon:(NSImage*)icon - label:(NSString*)label - color:(NSColor*)color { - // Create an attributed string for the label, if a label was given. - NSAttributedString* as = nil; - if (label) { - DCHECK(color); - NSFont *baseFont = [self font]; - NSFont *font = [NSFont fontWithDescriptor:[baseFont fontDescriptor] - size:[baseFont pointSize] - 2.0]; - NSDictionary* attributes = - [NSDictionary dictionaryWithObjectsAndKeys: - color, NSForegroundColorAttributeName, - font, NSFontAttributeName, - NULL]; - as = [[[NSAttributedString alloc] initWithString:label - attributes:attributes] autorelease]; - } +- (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view { + security_image_view_ = view; +} - hintIconLabel_.reset([as retain]); - hintIcon_.reset([icon retain]); +- (void)onSecurityIconMousePressed { + security_image_view_->OnMousePressed(); } // TODO(shess): This code is manually drawing the cell's border area, @@ -286,11 +271,13 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { textFrame.origin.x += keywordWidth; textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); } - } else if (hintIcon_) { - CGFloat width = [hintIcon_ size].width; - width += kHintIconHorizontalPad * 2; - if (hintIconLabel_) { - width += ceil([hintIconLabel_ size].width) + kHintXOffset; + } else if (security_image_view_ && security_image_view_->IsVisible()) { + NSImage* image = security_image_view_->GetImage(); + CGFloat width = [image size].width; + width += kIconHorizontalPad * 2; + NSAttributedString* label = security_image_view_->GetLabel(); + if (label) { + width += ceil([label size].width) + kHintXOffset; } if (width < NSWidth(cellFrame)) { textFrame.size.width -= width; @@ -300,28 +287,24 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { return textFrame; } -// For NSTextFieldCell this is the area within the borders. For our -// purposes, we count the info decorations as being part of the -// border. -- (NSRect)drawingRectForBounds:(NSRect)theRect { - return [super drawingRectForBounds:[self textFrameForFrame:theRect]]; -} - -- (NSRect)hintImageFrameForFrame:(NSRect)cellFrame { - // We'll draw the entire image - const NSSize imageRect([hintIcon_ size]); - +- (NSRect)imageFrameForFrame:(NSRect)cellFrame + withImageView:(LocationBarViewMac::LocationBarImageView*)image_view { + if (!image_view->IsVisible()) { + return NSZeroRect; + } + const NSSize imageRect = [image_view->GetImage() size]; CGFloat labelWidth = 0; - if (hintIconLabel_) { - labelWidth = ceil([hintIconLabel_ size].width) + kHintXOffset; + NSAttributedString* label = image_view->GetLabel(); + if (label) { + labelWidth = ceil([label size].width) + kHintXOffset; } // Move the rect that we're drawing into to the far right, minus - // enough space for the label (if present) + // enough space for the label (if present). cellFrame.origin.x += cellFrame.size.width - imageRect.width; cellFrame.origin.x -= labelWidth; // Add back the padding - cellFrame.origin.x -= kHintIconHorizontalPad; + cellFrame.origin.x -= kIconHorizontalPad; // Center the image vertically in the frame cellFrame.origin.y += @@ -333,6 +316,20 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { return cellFrame; } +- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame { + if (!security_image_view_) { + return NSZeroRect; + } + return [self imageFrameForFrame:cellFrame withImageView:security_image_view_]; +} + +// For NSTextFieldCell this is the area within the borders. For our +// purposes, we count the info decorations as being part of the +// border. +- (NSRect)drawingRectForBounds:(NSRect)theRect { + return [super drawingRectForBounds:[self textFrameForFrame:theRect]]; +} + - (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { DCHECK(hintString_); @@ -374,28 +371,32 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { [keywordString_.get() drawInRect:infoFrame]; } -- (void)drawHintIconWithFrame:(NSRect)cellFrame - inView:(NSView*)controlView { +- (void)drawImageView:(LocationBarViewMac::LocationBarImageView*)image_view + withFrame:(NSRect)cellFrame + inView:(NSView*)controlView { // If there's a label, draw it to the right of the icon. CGFloat labelWidth = 0; - if (hintIconLabel_) { - labelWidth = ceil([hintIconLabel_ size].width) + kHintXOffset; + NSAttributedString* label = image_view->GetLabel(); + if (label) { + labelWidth = ceil([label size].width) + kHintXOffset; NSRect textFrame(NSMakeRect(NSMaxX(cellFrame) - labelWidth, - cellFrame.origin.y + kHintIconLabelYOffset, + cellFrame.origin.y + kIconLabelYOffset, labelWidth, - cellFrame.size.height - kHintIconLabelYOffset)); - [hintIconLabel_.get() drawInRect:textFrame]; + cellFrame.size.height - kIconLabelYOffset)); + [label drawInRect:textFrame]; } - // We'll draw the entire image + // Draw the entire image. NSRect imageRect = NSZeroRect; - imageRect.size = [hintIcon_ size]; - const NSRect hintFrame([self hintImageFrameForFrame:cellFrame]); - [hintIcon_ setFlipped:[controlView isFlipped]]; - [hintIcon_ drawInRect:hintFrame - fromRect:imageRect - operation:NSCompositeSourceOver - fraction:1.0]; + NSImage* image = image_view->GetImage(); + image.size = [image size]; + NSRect imageFrame([self imageFrameForFrame:cellFrame + withImageView:image_view]); + [image setFlipped:[controlView isFlipped]]; + [image drawInRect:imageFrame + fromRect:imageRect + operation:NSCompositeSourceOver + fraction:1.0]; } - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { @@ -403,8 +404,10 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) { [self drawHintWithFrame:cellFrame inView:controlView]; } else if (keywordString_) { [self drawKeywordWithFrame:cellFrame inView:controlView]; - } else if (hintIcon_) { - [self drawHintIconWithFrame:cellFrame inView:controlView]; + } else if (security_image_view_ && security_image_view_->IsVisible()) { + [self drawImageView:security_image_view_ + withFrame:cellFrame + inView:controlView]; } [super drawInteriorWithFrame:cellFrame inView:controlView]; diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm index c56054c..3cc5703 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm @@ -21,7 +21,7 @@ const CGFloat kNarrowWidth(5.0); class AutocompleteTextFieldCellTest : public PlatformTest { public: - AutocompleteTextFieldCellTest() { + AutocompleteTextFieldCellTest() : security_image_view_(NULL, NULL) { // Make sure this is wide enough to play games with the cell // decorations. const NSRect frame = NSMakeRect(0, 0, kWidth, 30); @@ -31,11 +31,13 @@ class AutocompleteTextFieldCellTest : public PlatformTest { [cell setEditable:YES]; [cell setBordered:YES]; [view_ setCell:cell.get()]; + [cell setSecurityImageView:&security_image_view_]; [cocoa_helper_.contentView() addSubview:view_.get()]; } CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... scoped_nsobject<NSTextField> view_; + LocationBarViewMac::SecurityImageView security_image_view_; }; // Test adding/removing from the view hierarchy, mostly to ensure nothing @@ -173,8 +175,11 @@ TEST_F(AutocompleteTextFieldCellTest, TextFrame) { EXPECT_EQ(NSMaxX(bounds), NSMaxX(textFrame)); EXPECT_TRUE(NSContainsRect(cursorFrame, textFrame)); - // Hint icon takes up space on the right - [cell setHintIcon:[NSImage imageNamed:@"NSComputer"] label:nil color:nil]; + // Security icon takes up space on the right + security_image_view_.SetImageShown( + LocationBarViewMac::SecurityImageView::LOCK); + security_image_view_.SetVisible(true); + textFrame = [cell textFrameForFrame:bounds]; EXPECT_FALSE(NSIsEmptyRect(textFrame)); EXPECT_TRUE(NSContainsRect(bounds, textFrame)); @@ -236,7 +241,10 @@ TEST_F(AutocompleteTextFieldCellTest, DrawingRectForBounds) { EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect)); EXPECT_TRUE(NSEqualRects(drawingRect, originalDrawingRect)); - [cell setHintIcon:[NSImage imageNamed:@"NSComputer"] label:nil color:nil]; + security_image_view_.SetImageShown( + LocationBarViewMac::SecurityImageView::LOCK); + security_image_view_.SetVisible(true); + textFrame = [cell textFrameForFrame:bounds]; drawingRect = [cell drawingRectForBounds:bounds]; EXPECT_FALSE(NSIsEmptyRect(drawingRect)); @@ -248,17 +256,19 @@ TEST_F(AutocompleteTextFieldCellTest, HintImageFrame) { AutocompleteTextFieldCell* cell = static_cast<AutocompleteTextFieldCell*>([view_ cell]); const NSRect bounds([view_ bounds]); - scoped_nsobject<NSImage> hintIcon( - [[NSImage alloc] initWithSize:NSMakeSize(20, 20)]); + security_image_view_.SetImageShown( + LocationBarViewMac::SecurityImageView::LOCK); - NSRect iconRect = [cell hintImageFrameForFrame:bounds]; + security_image_view_.SetVisible(false); + NSRect iconRect = [cell securityImageFrameForFrame:bounds]; EXPECT_TRUE(NSIsEmptyRect(iconRect)); // Save the starting frame for after clear. const NSRect originalIconRect(iconRect); - [cell setHintIcon:hintIcon label:nil color:nil]; - iconRect = [cell hintImageFrameForFrame:bounds]; + security_image_view_.SetVisible(true); + iconRect = [cell securityImageFrameForFrame:bounds]; + EXPECT_FALSE(NSIsEmptyRect(iconRect)); EXPECT_TRUE(NSContainsRect(bounds, iconRect)); @@ -270,9 +280,26 @@ TEST_F(AutocompleteTextFieldCellTest, HintImageFrame) { NSRect textFrame = [cell textFrameForFrame:bounds]; EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect)); + // Now add a label. + NSFont* font = [NSFont controlContentFontOfSize:12.0]; + NSColor* color = [NSColor blackColor]; + security_image_view_.SetLabel(@"Label", font, color); + iconRect = [cell securityImageFrameForFrame:bounds]; + + EXPECT_FALSE(NSIsEmptyRect(iconRect)); + EXPECT_TRUE(NSContainsRect(bounds, iconRect)); + + // Make sure we are right of the |drawingRect|. + drawingRect = [cell drawingRectForBounds:bounds]; + EXPECT_LE(NSMaxX(drawingRect), NSMinX(iconRect)); + + // Make sure we're right of the |textFrame|. + textFrame = [cell textFrameForFrame:bounds]; + EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect)); + // Make sure we clear correctly. - [cell setHintIcon:nil label:nil color:nil]; - iconRect = [cell hintImageFrameForFrame:bounds]; + security_image_view_.SetVisible(false); + iconRect = [cell securityImageFrameForFrame:bounds]; EXPECT_TRUE(NSEqualRects(iconRect, originalIconRect)); EXPECT_TRUE(NSIsEmptyRect(iconRect)); } diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm index dfa4183..b4b5d0a 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm @@ -11,6 +11,7 @@ #import "chrome/browser/cocoa/autocomplete_text_field_editor.h" #import "chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" @@ -27,6 +28,14 @@ using ::testing::InSequence; @end namespace { +// Mock a SecurityImageView. +class MockSecurityImageView : public LocationBarViewMac::SecurityImageView { + public: + MockSecurityImageView(Profile* profile, ToolbarModel* model) + : LocationBarViewMac::SecurityImageView(profile, model) {} + + MOCK_METHOD0(OnMousePressed, bool()); +}; // Mock up an incrementing event number. NSUInteger eventNumber = 0; @@ -568,13 +577,18 @@ TEST_F(AutocompleteTextFieldTest, TripleClickSelectsAll) { TEST_F(AutocompleteTextFieldTest, SecurityIconMouseDown) { AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell]; - scoped_nsobject<NSImage> hintIcon( - [[NSImage alloc] initWithSize:NSMakeSize(20, 20)]); - [cell setHintIcon:hintIcon.get() label:nil color:nil]; - NSRect iconFrame([cell hintImageFrameForFrame:[field_ bounds]]); + + MockSecurityImageView security_image_view(NULL, NULL); + [cell setSecurityImageView:&security_image_view]; + security_image_view.SetImageShown( + LocationBarViewMac::SecurityImageView::LOCK); + security_image_view.SetVisible(true); + + NSRect iconFrame([cell securityImageFrameForFrame:[field_ bounds]]); NSPoint location(NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame))); NSEvent* event(Event(field_, location, NSLeftMouseDown, 1)); - EXPECT_CALL(field_observer_, OnSecurityIconClicked()); + + EXPECT_CALL(security_image_view, OnMousePressed()); [field_ mouseDown:event]; } diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h b/chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h index cfe3443..301cf34 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h +++ b/chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h @@ -39,7 +39,6 @@ class MockAutocompleteTextFieldObserver : public AutocompleteTextFieldObserver { MOCK_METHOD0(CanPasteAndGo, bool()); MOCK_METHOD0(GetPasteActionStringId, int()); MOCK_METHOD0(OnPasteAndGo, void()); - MOCK_METHOD0(OnSecurityIconClicked, void()); MOCK_METHOD0(OnFrameChanged, void()); }; diff --git a/chrome/browser/cocoa/location_bar_view_mac.h b/chrome/browser/cocoa/location_bar_view_mac.h index e305544..bafcde0 100644 --- a/chrome/browser/cocoa/location_bar_view_mac.h +++ b/chrome/browser/cocoa/location_bar_view_mac.h @@ -84,10 +84,82 @@ class LocationBarViewMac : public AutocompleteEditController, const bool show_search_hint, NSImage* image); + // Used to display a clickable icon in the location bar. + class LocationBarImageView { + public: + explicit LocationBarImageView() : image_(nil), + label_(nil), + visible_(false) {} + virtual ~LocationBarImageView() {} + + // Sets the image. + void SetImage(NSImage* image); + + // Sets the label text, font, and color. |text| may be nil; |color| and + // |font| are ignored if |text| is nil. + void SetLabel(NSString* text, NSFont* baseFont, NSColor* color); + + // Sets the visibility. SetImage() should be called with a valid image + // before the visibility is set to |true|. + void SetVisible(bool visible); + + const NSImage* GetImage() const { return image_; } + const NSAttributedString* GetLabel() const { return label_; } + bool IsVisible() const { return visible_; } + + virtual bool OnMousePressed() = 0; + + private: + scoped_nsobject<NSImage> image_; + + // The label shown next to the icon, or nil if none. + scoped_nsobject<NSAttributedString> label_; + + bool visible_; + + DISALLOW_COPY_AND_ASSIGN(LocationBarImageView); + }; + + // SecurityImageView is used to display the lock or warning icon when the + // current URL's scheme is https. + class SecurityImageView : public LocationBarImageView { + public: + enum Image { + LOCK = 0, + WARNING + }; + + SecurityImageView(Profile* profile, ToolbarModel* model); + virtual ~SecurityImageView(); + + // Sets the image to the appropriate icon. + void SetImageShown(Image image); + + // Shows the page info dialog. + virtual bool OnMousePressed(); + + private: + // The lock icon shown when using HTTPS. Loaded lazily, the first time it's + // needed. + scoped_nsobject<NSImage> lock_icon_; + + // The warning icon shown when HTTPS is broken. Loaded lazily, the first + // time it's needed. + scoped_nsobject<NSImage> warning_icon_; + + Profile* profile_; + ToolbarModel* model_; + + DISALLOW_COPY_AND_ASSIGN(SecurityImageView); + }; + private: - // Set the SSL icon we should be showing. + // Sets the SSL icon we should be showing. void SetSecurityIcon(ToolbarModel::Icon icon); + // Sets the label for the SSL icon. + void SetSecurityIconLabel(); + scoped_ptr<AutocompleteEditViewMac> edit_view_; CommandUpdater* command_updater_; // Weak, owned by Browser. @@ -102,6 +174,9 @@ class LocationBarViewMac : public AutocompleteEditController, // The user's desired disposition for how their input should be opened. WindowOpenDisposition disposition_; + // The view that shows the lock/warning when in HTTPS mode. + SecurityImageView security_image_view_; + Profile* profile_; ToolbarModel* toolbar_model_; // Weak, owned by Browser. diff --git a/chrome/browser/cocoa/location_bar_view_mac.mm b/chrome/browser/cocoa/location_bar_view_mac.mm index a4d2e64..c08633b 100644 --- a/chrome/browser/cocoa/location_bar_view_mac.mm +++ b/chrome/browser/cocoa/location_bar_view_mac.mm @@ -12,6 +12,7 @@ #include "chrome/browser/alternate_nav_url_fetcher.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" +#include "chrome/browser/browser_list.h" #import "chrome/browser/cocoa/autocomplete_text_field.h" #import "chrome/browser/cocoa/autocomplete_text_field_cell.h" #include "chrome/browser/cocoa/event_utils.h" @@ -19,6 +20,8 @@ #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/browser/tab_contents/tab_contents.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/skia_utils_mac.h" @@ -81,9 +84,12 @@ LocationBarViewMac::LocationBarViewMac( command_updater_(command_updater), field_(field), disposition_(CURRENT_TAB), + security_image_view_(profile, toolbar_model), profile_(profile), toolbar_model_(toolbar_model), transition_(PageTransition::TYPED) { + AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell]; + [cell setSecurityImageView:&security_image_view_]; } LocationBarViewMac::~LocationBarViewMac() { @@ -303,40 +309,120 @@ NSImage* LocationBarViewMac::GetTabButtonImage() { return tab_button_image_; } -void LocationBarViewMac::SetSecurityIcon(ToolbarModel::Icon security_icon) { - std::wstring info_text, info_tooltip; +void LocationBarViewMac::SetSecurityIconLabel() { + std::wstring info_text; + std::wstring info_tooltip; ToolbarModel::InfoTextType info_text_type = toolbar_model_->GetInfoText(&info_text, &info_tooltip); - NSColor* color = nil; - NSString* icon_label = nil; if (info_text_type == ToolbarModel::INFO_EV_TEXT) { - icon_label = base::SysWideToNSString(info_text); - color = - [NSColor colorWithCalibratedRed:kEvTextColorRedComponent - green:kEvTextColorGreenComponent - blue:kEvTextColorBlueComponent - alpha:1.0]; + NSString* icon_label = base::SysWideToNSString(info_text); + NSColor* color = [NSColor colorWithCalibratedRed:kEvTextColorRedComponent + green:kEvTextColorGreenComponent + blue:kEvTextColorBlueComponent + alpha:1.0]; + security_image_view_.SetLabel(icon_label, [field_ font], color); + } else { + security_image_view_.SetLabel(nil, nil, nil); } +} - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell]; - switch (security_icon) { +void LocationBarViewMac::SetSecurityIcon(ToolbarModel::Icon icon) { + switch (icon) { case ToolbarModel::LOCK_ICON: - [cell setHintIcon:rb.GetNSImageNamed(IDR_LOCK) - label:icon_label - color:color]; + security_image_view_.SetImageShown(SecurityImageView::LOCK); + security_image_view_.SetVisible(true); + SetSecurityIconLabel(); break; case ToolbarModel::WARNING_ICON: - [cell setHintIcon:rb.GetNSImageNamed(IDR_WARNING) - label:icon_label - color:color]; + security_image_view_.SetImageShown(SecurityImageView::WARNING); + security_image_view_.SetVisible(true); + SetSecurityIconLabel(); break; case ToolbarModel::NO_ICON: - [cell setHintIcon:nil label:nil color:nil]; + security_image_view_.SetVisible(false); break; default: NOTREACHED(); + security_image_view_.SetVisible(false); break; } [field_ resetFieldEditorFrameIfNeeded]; } + +// LocationBarImageView--------------------------------------------------------- + +void LocationBarViewMac::LocationBarImageView::SetImage(NSImage* image) { + image_.reset([image retain]); +} + +void LocationBarViewMac::LocationBarImageView::SetLabel(NSString* text, + NSFont* baseFont, + NSColor* color) { + // Create an attributed string for the label, if a label was given. + label_.reset(); + if (text) { + DCHECK(color); + DCHECK(baseFont); + NSFont* font = [NSFont fontWithDescriptor:[baseFont fontDescriptor] + size:[baseFont pointSize] - 2.0]; + NSDictionary* attributes = + [NSDictionary dictionaryWithObjectsAndKeys: + color, NSForegroundColorAttributeName, + font, NSFontAttributeName, + NULL]; + NSAttributedString* attrStr = + [[NSAttributedString alloc] initWithString:text attributes:attributes]; + label_.reset(attrStr); + } +} + +void LocationBarViewMac::LocationBarImageView::SetVisible(bool visible) { + DCHECK(!visible || image_); + visible_ = visible; +} + +// SecurityImageView------------------------------------------------------------ + +LocationBarViewMac::SecurityImageView::SecurityImageView( + Profile* profile, + ToolbarModel* model) + : lock_icon_(nil), + warning_icon_(nil), + profile_(profile), + model_(model) {} + +LocationBarViewMac::SecurityImageView::~SecurityImageView() {} + +void LocationBarViewMac::SecurityImageView::SetImageShown(Image image) { + switch (image) { + case LOCK: + if (!lock_icon_.get()) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + lock_icon_.reset([rb.GetNSImageNamed(IDR_LOCK) retain]); + } + SetImage(lock_icon_); + break; + case WARNING: + if (!warning_icon_.get()) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + warning_icon_.reset([rb.GetNSImageNamed(IDR_WARNING) retain]); + } + SetImage(warning_icon_); + break; + default: + NOTREACHED(); + break; + } +} + + +bool LocationBarViewMac::SecurityImageView::OnMousePressed() { + TabContents* tab = BrowserList::GetLastActive()->GetSelectedTabContents(); + NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); + if (!nav_entry) { + NOTREACHED(); + return true; + } + tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); + return true; +} |