| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "app/mac/nsimage_cache.h" | 12 #include "app/mac/nsimage_cache.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/mac/mac_util.h" | 14 #include "base/mac/mac_util.h" |
| 15 #include "base/sys_string_conversions.h" | 15 #include "base/sys_string_conversions.h" |
| 16 #include "chrome/app/chrome_command_ids.h" | 16 #include "chrome/app/chrome_command_ids.h" |
| 17 #include "chrome/browser/autocomplete/autocomplete.h" | 17 #include "chrome/browser/autocomplete/autocomplete.h" |
| 18 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 18 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
| 19 #include "chrome/browser/autocomplete/autocomplete_match.h" | 19 #include "chrome/browser/autocomplete/autocomplete_match.h" |
| 20 #include "chrome/browser/extensions/extension_tab_helper.h" | 20 #include "chrome/browser/extensions/extension_tab_helper.h" |
| 21 #include "chrome/browser/favicon_tab_helper.h" |
| 21 #include "chrome/browser/metrics/user_metrics.h" | 22 #include "chrome/browser/metrics/user_metrics.h" |
| 22 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/debugger/devtools_window.h" | 25 #include "chrome/browser/debugger/devtools_window.h" |
| 25 #include "chrome/browser/net/url_fixer_upper.h" | 26 #include "chrome/browser/net/url_fixer_upper.h" |
| 26 #include "chrome/browser/sidebar/sidebar_container.h" | 27 #include "chrome/browser/sidebar/sidebar_container.h" |
| 27 #include "chrome/browser/sidebar/sidebar_manager.h" | 28 #include "chrome/browser/sidebar/sidebar_manager.h" |
| 28 #include "chrome/browser/tabs/tab_strip_model.h" | 29 #include "chrome/browser/tabs/tab_strip_model.h" |
| 29 #include "chrome/browser/ui/browser.h" | 30 #include "chrome/browser/ui/browser.h" |
| 30 #include "chrome/browser/ui/browser_navigator.h" | 31 #include "chrome/browser/ui/browser_navigator.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 bool animate_; | 148 bool animate_; |
| 148 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); | 149 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); |
| 149 }; | 150 }; |
| 150 | 151 |
| 151 } // namespace | 152 } // namespace |
| 152 | 153 |
| 153 @interface TabStripController (Private) | 154 @interface TabStripController (Private) |
| 154 - (void)addSubviewToPermanentList:(NSView*)aView; | 155 - (void)addSubviewToPermanentList:(NSView*)aView; |
| 155 - (void)regenerateSubviewList; | 156 - (void)regenerateSubviewList; |
| 156 - (NSInteger)indexForContentsView:(NSView*)view; | 157 - (NSInteger)indexForContentsView:(NSView*)view; |
| 157 - (void)updateFaviconForContents:(TabContents*)contents | 158 - (void)updateFaviconForContents:(TabContentsWrapper*)contents |
| 158 atIndex:(NSInteger)modelIndex; | 159 atIndex:(NSInteger)modelIndex; |
| 159 - (void)layoutTabsWithAnimation:(BOOL)animate | 160 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 160 regenerateSubviews:(BOOL)doUpdate; | 161 regenerateSubviews:(BOOL)doUpdate; |
| 161 - (void)animationDidStopForController:(TabController*)controller | 162 - (void)animationDidStopForController:(TabController*)controller |
| 162 finished:(BOOL)finished; | 163 finished:(BOOL)finished; |
| 163 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 164 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 164 - (NSInteger)numberOfOpenTabs; | 165 - (NSInteger)numberOfOpenTabs; |
| 165 - (NSInteger)numberOfOpenMiniTabs; | 166 - (NSInteger)numberOfOpenMiniTabs; |
| 166 - (NSInteger)numberOfOpenNonMiniTabs; | 167 - (NSInteger)numberOfOpenNonMiniTabs; |
| 167 - (void)mouseMoved:(NSEvent*)event; | 168 - (void)mouseMoved:(NSEvent*)event; |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1125 // Whenever |-layoutTabs| is called, it'll also add the new subview. |
| 1125 if (!inForeground) { | 1126 if (!inForeground) { |
| 1126 [self layoutTabs]; | 1127 [self layoutTabs]; |
| 1127 } | 1128 } |
| 1128 | 1129 |
| 1129 // During normal loading, we won't yet have a favicon and we'll get | 1130 // During normal loading, we won't yet have a favicon and we'll get |
| 1130 // subsequent state change notifications to show the throbber, but when we're | 1131 // subsequent state change notifications to show the throbber, but when we're |
| 1131 // dragging a tab out into a new window, we have to put the tab's favicon | 1132 // dragging a tab out into a new window, we have to put the tab's favicon |
| 1132 // into the right state up front as we won't be told to do it from anywhere | 1133 // into the right state up front as we won't be told to do it from anywhere |
| 1133 // else. | 1134 // else. |
| 1134 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; | 1135 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1135 | 1136 |
| 1136 [self updateCommonTitlePrefix]; | 1137 [self updateCommonTitlePrefix]; |
| 1137 | 1138 |
| 1138 // Send a broadcast that the number of tabs have changed. | 1139 // Send a broadcast that the number of tabs have changed. |
| 1139 [[NSNotificationCenter defaultCenter] | 1140 [[NSNotificationCenter defaultCenter] |
| 1140 postNotificationName:kTabStripNumberOfTabsChanged | 1141 postNotificationName:kTabStripNumberOfTabsChanged |
| 1141 object:self]; | 1142 object:self]; |
| 1142 } | 1143 } |
| 1143 | 1144 |
| 1144 // Called when a notification is received from the model to select a particular | 1145 // Called when a notification is received from the model to select a particular |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // Send a broadcast that the number of tabs have changed. | 1321 // Send a broadcast that the number of tabs have changed. |
| 1321 [[NSNotificationCenter defaultCenter] | 1322 [[NSNotificationCenter defaultCenter] |
| 1322 postNotificationName:kTabStripNumberOfTabsChanged | 1323 postNotificationName:kTabStripNumberOfTabsChanged |
| 1323 object:self]; | 1324 object:self]; |
| 1324 | 1325 |
| 1325 [delegate_ onTabDetachedWithContents:contents->tab_contents()]; | 1326 [delegate_ onTabDetachedWithContents:contents->tab_contents()]; |
| 1326 } | 1327 } |
| 1327 | 1328 |
| 1328 // A helper routine for creating an NSImageView to hold the favicon or app icon | 1329 // A helper routine for creating an NSImageView to hold the favicon or app icon |
| 1329 // for |contents|. | 1330 // for |contents|. |
| 1330 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 1331 - (NSImageView*)iconImageViewForContents:(TabContentsWrapper*)contents { |
| 1331 TabContentsWrapper* wrapper = | 1332 BOOL isApp = contents->extension_tab_helper()->is_app(); |
| 1332 TabContentsWrapper::GetCurrentWrapperForContents(contents); | |
| 1333 BOOL isApp = wrapper->extension_tab_helper()->is_app(); | |
| 1334 NSImage* image = nil; | 1333 NSImage* image = nil; |
| 1335 // Favicons come from the renderer, and the renderer draws everything in the | 1334 // Favicons come from the renderer, and the renderer draws everything in the |
| 1336 // system color space. | 1335 // system color space. |
| 1337 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); | 1336 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); |
| 1338 if (isApp) { | 1337 if (isApp) { |
| 1339 SkBitmap* icon = wrapper->extension_tab_helper()->GetExtensionAppIcon(); | 1338 SkBitmap* icon = contents->extension_tab_helper()->GetExtensionAppIcon(); |
| 1340 if (icon) | 1339 if (icon) |
| 1341 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); | 1340 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); |
| 1342 } else { | 1341 } else { |
| 1343 image = gfx::SkBitmapToNSImageWithColorSpace(contents->GetFavicon(), | 1342 image = gfx::SkBitmapToNSImageWithColorSpace( |
| 1344 colorSpace); | 1343 contents->favicon_tab_helper()->GetFavicon(), colorSpace); |
| 1345 } | 1344 } |
| 1346 | 1345 |
| 1347 // Either we don't have a valid favicon or there was some issue converting it | 1346 // Either we don't have a valid favicon or there was some issue converting it |
| 1348 // from an SkBitmap. Either way, just show the default. | 1347 // from an SkBitmap. Either way, just show the default. |
| 1349 if (!image) | 1348 if (!image) |
| 1350 image = defaultFavicon_.get(); | 1349 image = defaultFavicon_.get(); |
| 1351 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1350 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
| 1352 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | 1351 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; |
| 1353 [view setImage:image]; | 1352 [view setImage:image]; |
| 1354 return view; | 1353 return view; |
| 1355 } | 1354 } |
| 1356 | 1355 |
| 1357 // Updates the current loading state, replacing the icon view with a favicon, | 1356 // Updates the current loading state, replacing the icon view with a favicon, |
| 1358 // a throbber, the default icon, or nothing at all. | 1357 // a throbber, the default icon, or nothing at all. |
| 1359 - (void)updateFaviconForContents:(TabContents*)contents | 1358 - (void)updateFaviconForContents:(TabContentsWrapper*)contents |
| 1360 atIndex:(NSInteger)modelIndex { | 1359 atIndex:(NSInteger)modelIndex { |
| 1361 if (!contents) | 1360 if (!contents) |
| 1362 return; | 1361 return; |
| 1363 | 1362 |
| 1364 static NSImage* throbberWaitingImage = | 1363 static NSImage* throbberWaitingImage = |
| 1365 [ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1364 [ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1366 IDR_THROBBER_WAITING) retain]; | 1365 IDR_THROBBER_WAITING) retain]; |
| 1367 static NSImage* throbberLoadingImage = | 1366 static NSImage* throbberLoadingImage = |
| 1368 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_THROBBER) | 1367 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_THROBBER) |
| 1369 retain]; | 1368 retain]; |
| 1370 static NSImage* sadFaviconImage = | 1369 static NSImage* sadFaviconImage = |
| 1371 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_SAD_FAVICON) | 1370 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_SAD_FAVICON) |
| 1372 retain]; | 1371 retain]; |
| 1373 | 1372 |
| 1374 // Take closing tabs into account. | 1373 // Take closing tabs into account. |
| 1375 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1374 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1376 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1375 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1377 | 1376 |
| 1378 bool oldHasIcon = [tabController iconView] != nil; | 1377 bool oldHasIcon = [tabController iconView] != nil; |
| 1379 bool newHasIcon = contents->ShouldDisplayFavicon() || | 1378 bool newHasIcon = contents->favicon_tab_helper()->ShouldDisplayFavicon() || |
| 1380 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. | 1379 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. |
| 1381 | 1380 |
| 1382 TabLoadingState oldState = [tabController loadingState]; | 1381 TabLoadingState oldState = [tabController loadingState]; |
| 1383 TabLoadingState newState = kTabDone; | 1382 TabLoadingState newState = kTabDone; |
| 1384 NSImage* throbberImage = nil; | 1383 NSImage* throbberImage = nil; |
| 1385 if (contents->is_crashed()) { | 1384 if (contents->tab_contents()->is_crashed()) { |
| 1386 newState = kTabCrashed; | 1385 newState = kTabCrashed; |
| 1387 newHasIcon = true; | 1386 newHasIcon = true; |
| 1388 } else if (contents->waiting_for_response()) { | 1387 } else if (contents->tab_contents()->waiting_for_response()) { |
| 1389 newState = kTabWaiting; | 1388 newState = kTabWaiting; |
| 1390 throbberImage = throbberWaitingImage; | 1389 throbberImage = throbberWaitingImage; |
| 1391 } else if (contents->is_loading()) { | 1390 } else if (contents->tab_contents()->is_loading()) { |
| 1392 newState = kTabLoading; | 1391 newState = kTabLoading; |
| 1393 throbberImage = throbberLoadingImage; | 1392 throbberImage = throbberLoadingImage; |
| 1394 } | 1393 } |
| 1395 | 1394 |
| 1396 if (oldState != newState) | 1395 if (oldState != newState) |
| 1397 [tabController setLoadingState:newState]; | 1396 [tabController setLoadingState:newState]; |
| 1398 | 1397 |
| 1399 // While loading, this function is called repeatedly with the same state. | 1398 // While loading, this function is called repeatedly with the same state. |
| 1400 // To avoid expensive unnecessary view manipulation, only make changes when | 1399 // To avoid expensive unnecessary view manipulation, only make changes when |
| 1401 // the state is actually changing. When loading is complete (kTabDone), | 1400 // the state is actually changing. When loading is complete (kTabDone), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 // TODO(sky): make this work. | 1440 // TODO(sky): make this work. |
| 1442 // We'll receive another notification of the change asynchronously. | 1441 // We'll receive another notification of the change asynchronously. |
| 1443 return; | 1442 return; |
| 1444 } | 1443 } |
| 1445 | 1444 |
| 1446 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1445 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1447 | 1446 |
| 1448 if (change != TabStripModelObserver::LOADING_ONLY) | 1447 if (change != TabStripModelObserver::LOADING_ONLY) |
| 1449 [self setTabTitle:tabController withContents:contents->tab_contents()]; | 1448 [self setTabTitle:tabController withContents:contents->tab_contents()]; |
| 1450 | 1449 |
| 1451 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; | 1450 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1452 | 1451 |
| 1453 TabContentsController* updatedController = | 1452 TabContentsController* updatedController = |
| 1454 [tabContentsArray_ objectAtIndex:index]; | 1453 [tabContentsArray_ objectAtIndex:index]; |
| 1455 [updatedController tabDidChange:contents->tab_contents()]; | 1454 [updatedController tabDidChange:contents->tab_contents()]; |
| 1456 | 1455 |
| 1457 [self updateCommonTitlePrefix]; | 1456 [self updateCommonTitlePrefix]; |
| 1458 } | 1457 } |
| 1459 | 1458 |
| 1460 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1459 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
| 1461 // in sync with the tab strip model. It can also be pinned/unpinned | 1460 // in sync with the tab strip model. It can also be pinned/unpinned |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1493 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1495 DCHECK([tabController isKindOfClass:[TabController class]]); | 1494 DCHECK([tabController isKindOfClass:[TabController class]]); |
| 1496 | 1495 |
| 1497 // Don't do anything if the change was already picked up by the move event. | 1496 // Don't do anything if the change was already picked up by the move event. |
| 1498 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1497 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) |
| 1499 return; | 1498 return; |
| 1500 | 1499 |
| 1501 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1500 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1502 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1501 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1503 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1502 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1504 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; | 1503 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1505 // If the tab is being restored and it's pinned, the mini state is set after | 1504 // If the tab is being restored and it's pinned, the mini state is set after |
| 1506 // the tab has already been rendered, so re-layout the tabstrip. In all other | 1505 // the tab has already been rendered, so re-layout the tabstrip. In all other |
| 1507 // cases, the state is set before the tab is rendered so this isn't needed. | 1506 // cases, the state is set before the tab is rendered so this isn't needed. |
| 1508 [self layoutTabs]; | 1507 [self layoutTabs]; |
| 1509 | 1508 |
| 1510 [self updateCommonTitlePrefix]; | 1509 [self updateCommonTitlePrefix]; |
| 1511 } | 1510 } |
| 1512 | 1511 |
| 1513 - (void)setFrameOfSelectedTab:(NSRect)frame { | 1512 - (void)setFrameOfSelectedTab:(NSRect)frame { |
| 1514 NSView* view = [self selectedTabView]; | 1513 NSView* view = [self selectedTabView]; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2087 } | 2086 } |
| 2088 | 2087 |
| 2089 NSString* menuTitle = | 2088 NSString* menuTitle = |
| 2090 l10n_util::GetNSStringWithFixup(IDS_PROFILES_CREATE_NEW_PROFILE_OPTION); | 2089 l10n_util::GetNSStringWithFixup(IDS_PROFILES_CREATE_NEW_PROFILE_OPTION); |
| 2091 [menu addItemWithTitle:menuTitle | 2090 [menu addItemWithTitle:menuTitle |
| 2092 action:NULL | 2091 action:NULL |
| 2093 keyEquivalent:@""]; | 2092 keyEquivalent:@""]; |
| 2094 } | 2093 } |
| 2095 | 2094 |
| 2096 @end | 2095 @end |
| OLD | NEW |