| 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" | |
| 22 #include "chrome/browser/metrics/user_metrics.h" | 21 #include "chrome/browser/metrics/user_metrics.h" |
| 23 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
| 24 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/debugger/devtools_window.h" | 24 #include "chrome/browser/debugger/devtools_window.h" |
| 26 #include "chrome/browser/net/url_fixer_upper.h" | 25 #include "chrome/browser/net/url_fixer_upper.h" |
| 27 #include "chrome/browser/sidebar/sidebar_container.h" | 26 #include "chrome/browser/sidebar/sidebar_container.h" |
| 28 #include "chrome/browser/sidebar/sidebar_manager.h" | 27 #include "chrome/browser/sidebar/sidebar_manager.h" |
| 29 #include "chrome/browser/tabs/tab_strip_model.h" | 28 #include "chrome/browser/tabs/tab_strip_model.h" |
| 30 #include "chrome/browser/ui/browser.h" | 29 #include "chrome/browser/ui/browser.h" |
| 31 #include "chrome/browser/ui/browser_navigator.h" | 30 #include "chrome/browser/ui/browser_navigator.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 bool animate_; | 147 bool animate_; |
| 149 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); | 148 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); |
| 150 }; | 149 }; |
| 151 | 150 |
| 152 } // namespace | 151 } // namespace |
| 153 | 152 |
| 154 @interface TabStripController (Private) | 153 @interface TabStripController (Private) |
| 155 - (void)addSubviewToPermanentList:(NSView*)aView; | 154 - (void)addSubviewToPermanentList:(NSView*)aView; |
| 156 - (void)regenerateSubviewList; | 155 - (void)regenerateSubviewList; |
| 157 - (NSInteger)indexForContentsView:(NSView*)view; | 156 - (NSInteger)indexForContentsView:(NSView*)view; |
| 158 - (void)updateFaviconForContents:(TabContentsWrapper*)contents | 157 - (void)updateFaviconForContents:(TabContents*)contents |
| 159 atIndex:(NSInteger)modelIndex; | 158 atIndex:(NSInteger)modelIndex; |
| 160 - (void)layoutTabsWithAnimation:(BOOL)animate | 159 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 161 regenerateSubviews:(BOOL)doUpdate; | 160 regenerateSubviews:(BOOL)doUpdate; |
| 162 - (void)animationDidStopForController:(TabController*)controller | 161 - (void)animationDidStopForController:(TabController*)controller |
| 163 finished:(BOOL)finished; | 162 finished:(BOOL)finished; |
| 164 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 163 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 165 - (NSInteger)numberOfOpenTabs; | 164 - (NSInteger)numberOfOpenTabs; |
| 166 - (NSInteger)numberOfOpenMiniTabs; | 165 - (NSInteger)numberOfOpenMiniTabs; |
| 167 - (NSInteger)numberOfOpenNonMiniTabs; | 166 - (NSInteger)numberOfOpenNonMiniTabs; |
| 168 - (void)mouseMoved:(NSEvent*)event; | 167 - (void)mouseMoved:(NSEvent*)event; |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1139 // Whenever |-layoutTabs| is called, it'll also add the new subview. |
| 1141 if (!inForeground) { | 1140 if (!inForeground) { |
| 1142 [self layoutTabs]; | 1141 [self layoutTabs]; |
| 1143 } | 1142 } |
| 1144 | 1143 |
| 1145 // During normal loading, we won't yet have a favicon and we'll get | 1144 // During normal loading, we won't yet have a favicon and we'll get |
| 1146 // subsequent state change notifications to show the throbber, but when we're | 1145 // subsequent state change notifications to show the throbber, but when we're |
| 1147 // dragging a tab out into a new window, we have to put the tab's favicon | 1146 // dragging a tab out into a new window, we have to put the tab's favicon |
| 1148 // into the right state up front as we won't be told to do it from anywhere | 1147 // into the right state up front as we won't be told to do it from anywhere |
| 1149 // else. | 1148 // else. |
| 1150 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1149 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; |
| 1151 | 1150 |
| 1152 [self updateCommonTitlePrefix]; | 1151 [self updateCommonTitlePrefix]; |
| 1153 | 1152 |
| 1154 // Send a broadcast that the number of tabs have changed. | 1153 // Send a broadcast that the number of tabs have changed. |
| 1155 [[NSNotificationCenter defaultCenter] | 1154 [[NSNotificationCenter defaultCenter] |
| 1156 postNotificationName:kTabStripNumberOfTabsChanged | 1155 postNotificationName:kTabStripNumberOfTabsChanged |
| 1157 object:self]; | 1156 object:self]; |
| 1158 } | 1157 } |
| 1159 | 1158 |
| 1160 // Called when a notification is received from the model to select a particular | 1159 // 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... |
| 1336 // Send a broadcast that the number of tabs have changed. | 1335 // Send a broadcast that the number of tabs have changed. |
| 1337 [[NSNotificationCenter defaultCenter] | 1336 [[NSNotificationCenter defaultCenter] |
| 1338 postNotificationName:kTabStripNumberOfTabsChanged | 1337 postNotificationName:kTabStripNumberOfTabsChanged |
| 1339 object:self]; | 1338 object:self]; |
| 1340 | 1339 |
| 1341 [delegate_ onTabDetachedWithContents:contents->tab_contents()]; | 1340 [delegate_ onTabDetachedWithContents:contents->tab_contents()]; |
| 1342 } | 1341 } |
| 1343 | 1342 |
| 1344 // A helper routine for creating an NSImageView to hold the favicon or app icon | 1343 // A helper routine for creating an NSImageView to hold the favicon or app icon |
| 1345 // for |contents|. | 1344 // for |contents|. |
| 1346 - (NSImageView*)iconImageViewForContents:(TabContentsWrapper*)contents { | 1345 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { |
| 1347 BOOL isApp = contents->extension_tab_helper()->is_app(); | 1346 TabContentsWrapper* wrapper = |
| 1347 TabContentsWrapper::GetCurrentWrapperForContents(contents); |
| 1348 BOOL isApp = wrapper->extension_tab_helper()->is_app(); |
| 1348 NSImage* image = nil; | 1349 NSImage* image = nil; |
| 1349 // Favicons come from the renderer, and the renderer draws everything in the | 1350 // Favicons come from the renderer, and the renderer draws everything in the |
| 1350 // system color space. | 1351 // system color space. |
| 1351 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); | 1352 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); |
| 1352 if (isApp) { | 1353 if (isApp) { |
| 1353 SkBitmap* icon = contents->extension_tab_helper()->GetExtensionAppIcon(); | 1354 SkBitmap* icon = wrapper->extension_tab_helper()->GetExtensionAppIcon(); |
| 1354 if (icon) | 1355 if (icon) |
| 1355 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); | 1356 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); |
| 1356 } else { | 1357 } else { |
| 1357 image = gfx::SkBitmapToNSImageWithColorSpace( | 1358 image = gfx::SkBitmapToNSImageWithColorSpace(contents->GetFavicon(), |
| 1358 contents->favicon_tab_helper()->GetFavicon(), colorSpace); | 1359 colorSpace); |
| 1359 } | 1360 } |
| 1360 | 1361 |
| 1361 // Either we don't have a valid favicon or there was some issue converting it | 1362 // Either we don't have a valid favicon or there was some issue converting it |
| 1362 // from an SkBitmap. Either way, just show the default. | 1363 // from an SkBitmap. Either way, just show the default. |
| 1363 if (!image) | 1364 if (!image) |
| 1364 image = defaultFavicon_.get(); | 1365 image = defaultFavicon_.get(); |
| 1365 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1366 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
| 1366 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | 1367 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; |
| 1367 [view setImage:image]; | 1368 [view setImage:image]; |
| 1368 return view; | 1369 return view; |
| 1369 } | 1370 } |
| 1370 | 1371 |
| 1371 // Updates the current loading state, replacing the icon view with a favicon, | 1372 // Updates the current loading state, replacing the icon view with a favicon, |
| 1372 // a throbber, the default icon, or nothing at all. | 1373 // a throbber, the default icon, or nothing at all. |
| 1373 - (void)updateFaviconForContents:(TabContentsWrapper*)contents | 1374 - (void)updateFaviconForContents:(TabContents*)contents |
| 1374 atIndex:(NSInteger)modelIndex { | 1375 atIndex:(NSInteger)modelIndex { |
| 1375 if (!contents) | 1376 if (!contents) |
| 1376 return; | 1377 return; |
| 1377 | 1378 |
| 1378 static NSImage* throbberWaitingImage = | 1379 static NSImage* throbberWaitingImage = |
| 1379 [ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1380 [ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1380 IDR_THROBBER_WAITING) retain]; | 1381 IDR_THROBBER_WAITING) retain]; |
| 1381 static NSImage* throbberLoadingImage = | 1382 static NSImage* throbberLoadingImage = |
| 1382 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_THROBBER) | 1383 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_THROBBER) |
| 1383 retain]; | 1384 retain]; |
| 1384 static NSImage* sadFaviconImage = | 1385 static NSImage* sadFaviconImage = |
| 1385 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_SAD_FAVICON) | 1386 [ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_SAD_FAVICON) |
| 1386 retain]; | 1387 retain]; |
| 1387 | 1388 |
| 1388 // Take closing tabs into account. | 1389 // Take closing tabs into account. |
| 1389 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1390 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1390 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1391 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1391 | 1392 |
| 1392 bool oldHasIcon = [tabController iconView] != nil; | 1393 bool oldHasIcon = [tabController iconView] != nil; |
| 1393 bool newHasIcon = contents->favicon_tab_helper()->ShouldDisplayFavicon() || | 1394 bool newHasIcon = contents->ShouldDisplayFavicon() || |
| 1394 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. | 1395 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. |
| 1395 | 1396 |
| 1396 TabLoadingState oldState = [tabController loadingState]; | 1397 TabLoadingState oldState = [tabController loadingState]; |
| 1397 TabLoadingState newState = kTabDone; | 1398 TabLoadingState newState = kTabDone; |
| 1398 NSImage* throbberImage = nil; | 1399 NSImage* throbberImage = nil; |
| 1399 if (contents->tab_contents()->is_crashed()) { | 1400 if (contents->is_crashed()) { |
| 1400 newState = kTabCrashed; | 1401 newState = kTabCrashed; |
| 1401 newHasIcon = true; | 1402 newHasIcon = true; |
| 1402 } else if (contents->tab_contents()->waiting_for_response()) { | 1403 } else if (contents->waiting_for_response()) { |
| 1403 newState = kTabWaiting; | 1404 newState = kTabWaiting; |
| 1404 throbberImage = throbberWaitingImage; | 1405 throbberImage = throbberWaitingImage; |
| 1405 } else if (contents->tab_contents()->is_loading()) { | 1406 } else if (contents->is_loading()) { |
| 1406 newState = kTabLoading; | 1407 newState = kTabLoading; |
| 1407 throbberImage = throbberLoadingImage; | 1408 throbberImage = throbberLoadingImage; |
| 1408 } | 1409 } |
| 1409 | 1410 |
| 1410 if (oldState != newState) | 1411 if (oldState != newState) |
| 1411 [tabController setLoadingState:newState]; | 1412 [tabController setLoadingState:newState]; |
| 1412 | 1413 |
| 1413 // While loading, this function is called repeatedly with the same state. | 1414 // While loading, this function is called repeatedly with the same state. |
| 1414 // To avoid expensive unnecessary view manipulation, only make changes when | 1415 // To avoid expensive unnecessary view manipulation, only make changes when |
| 1415 // the state is actually changing. When loading is complete (kTabDone), | 1416 // the state is actually changing. When loading is complete (kTabDone), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 // TODO(sky): make this work. | 1456 // TODO(sky): make this work. |
| 1456 // We'll receive another notification of the change asynchronously. | 1457 // We'll receive another notification of the change asynchronously. |
| 1457 return; | 1458 return; |
| 1458 } | 1459 } |
| 1459 | 1460 |
| 1460 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1461 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1461 | 1462 |
| 1462 if (change != TabStripModelObserver::LOADING_ONLY) | 1463 if (change != TabStripModelObserver::LOADING_ONLY) |
| 1463 [self setTabTitle:tabController withContents:contents->tab_contents()]; | 1464 [self setTabTitle:tabController withContents:contents->tab_contents()]; |
| 1464 | 1465 |
| 1465 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1466 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; |
| 1466 | 1467 |
| 1467 TabContentsController* updatedController = | 1468 TabContentsController* updatedController = |
| 1468 [tabContentsArray_ objectAtIndex:index]; | 1469 [tabContentsArray_ objectAtIndex:index]; |
| 1469 [updatedController tabDidChange:contents->tab_contents()]; | 1470 [updatedController tabDidChange:contents->tab_contents()]; |
| 1470 | 1471 |
| 1471 [self updateCommonTitlePrefix]; | 1472 [self updateCommonTitlePrefix]; |
| 1472 } | 1473 } |
| 1473 | 1474 |
| 1474 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1475 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
| 1475 // in sync with the tab strip model. It can also be pinned/unpinned | 1476 // in sync with the tab strip model. It can also be pinned/unpinned |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1509 DCHECK([tabController isKindOfClass:[TabController class]]); | 1510 DCHECK([tabController isKindOfClass:[TabController class]]); |
| 1510 | 1511 |
| 1511 // Don't do anything if the change was already picked up by the move event. | 1512 // Don't do anything if the change was already picked up by the move event. |
| 1512 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1513 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) |
| 1513 return; | 1514 return; |
| 1514 | 1515 |
| 1515 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1516 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1516 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1517 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1517 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1518 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1518 [tabController setUrl:contents->tab_contents()->GetURL()]; | 1519 [tabController setUrl:contents->tab_contents()->GetURL()]; |
| 1519 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1520 [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; |
| 1520 // If the tab is being restored and it's pinned, the mini state is set after | 1521 // If the tab is being restored and it's pinned, the mini state is set after |
| 1521 // the tab has already been rendered, so re-layout the tabstrip. In all other | 1522 // the tab has already been rendered, so re-layout the tabstrip. In all other |
| 1522 // cases, the state is set before the tab is rendered so this isn't needed. | 1523 // cases, the state is set before the tab is rendered so this isn't needed. |
| 1523 [self layoutTabs]; | 1524 [self layoutTabs]; |
| 1524 | 1525 |
| 1525 [self updateCommonTitlePrefix]; | 1526 [self updateCommonTitlePrefix]; |
| 1526 } | 1527 } |
| 1527 | 1528 |
| 1528 - (void)setFrameOfSelectedTab:(NSRect)frame { | 1529 - (void)setFrameOfSelectedTab:(NSRect)frame { |
| 1529 NSView* view = [self selectedTabView]; | 1530 NSView* view = [self selectedTabView]; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2102 } | 2103 } |
| 2103 | 2104 |
| 2104 NSString* menuTitle = | 2105 NSString* menuTitle = |
| 2105 l10n_util::GetNSStringWithFixup(IDS_PROFILES_CREATE_NEW_PROFILE_OPTION); | 2106 l10n_util::GetNSStringWithFixup(IDS_PROFILES_CREATE_NEW_PROFILE_OPTION); |
| 2106 [menu addItemWithTitle:menuTitle | 2107 [menu addItemWithTitle:menuTitle |
| 2107 action:NULL | 2108 action:NULL |
| 2108 keyEquivalent:@""]; | 2109 keyEquivalent:@""]; |
| 2109 } | 2110 } |
| 2110 | 2111 |
| 2111 @end | 2112 @end |
| OLD | NEW |