| OLD | NEW | 
|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/cocoa/tab_strip_controller.h" | 5 #import "chrome/browser/cocoa/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> | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 30 #import "chrome/browser/cocoa/tab_view.h" | 30 #import "chrome/browser/cocoa/tab_view.h" | 
| 31 #import "chrome/browser/cocoa/throbber_view.h" | 31 #import "chrome/browser/cocoa/throbber_view.h" | 
| 32 #include "chrome/browser/debugger/devtools_window.h" | 32 #include "chrome/browser/debugger/devtools_window.h" | 
| 33 #include "chrome/browser/net/url_fixer_upper.h" | 33 #include "chrome/browser/net/url_fixer_upper.h" | 
| 34 #include "chrome/browser/sidebar/sidebar_container.h" | 34 #include "chrome/browser/sidebar/sidebar_container.h" | 
| 35 #include "chrome/browser/sidebar/sidebar_manager.h" | 35 #include "chrome/browser/sidebar/sidebar_manager.h" | 
| 36 #include "chrome/browser/tab_contents/navigation_controller.h" | 36 #include "chrome/browser/tab_contents/navigation_controller.h" | 
| 37 #include "chrome/browser/tab_contents/navigation_entry.h" | 37 #include "chrome/browser/tab_contents/navigation_entry.h" | 
| 38 #include "chrome/browser/tab_contents/tab_contents.h" | 38 #include "chrome/browser/tab_contents/tab_contents.h" | 
| 39 #include "chrome/browser/tab_contents/tab_contents_view.h" | 39 #include "chrome/browser/tab_contents/tab_contents_view.h" | 
|  | 40 #include "chrome/browser/tab_contents_wrapper.h" | 
| 40 #include "chrome/browser/tabs/tab_strip_model.h" | 41 #include "chrome/browser/tabs/tab_strip_model.h" | 
| 41 #include "chrome/browser/ui/browser_navigator.h" | 42 #include "chrome/browser/ui/browser_navigator.h" | 
| 42 #include "grit/app_resources.h" | 43 #include "grit/app_resources.h" | 
| 43 #include "grit/generated_resources.h" | 44 #include "grit/generated_resources.h" | 
| 44 #include "grit/theme_resources.h" | 45 #include "grit/theme_resources.h" | 
| 45 #include "skia/ext/skia_utils_mac.h" | 46 #include "skia/ext/skia_utils_mac.h" | 
| 46 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | 47 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | 
| 47 | 48 | 
| 48 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; | 49 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; | 
| 49 | 50 | 
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 369     // Set accessibility descriptions. http://openradar.appspot.com/7496255 | 370     // Set accessibility descriptions. http://openradar.appspot.com/7496255 | 
| 370     NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); | 371     NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); | 
| 371     [[newTabButton_ cell] | 372     [[newTabButton_ cell] | 
| 372         accessibilitySetOverrideValue:description | 373         accessibilitySetOverrideValue:description | 
| 373                          forAttribute:NSAccessibilityDescriptionAttribute]; | 374                          forAttribute:NSAccessibilityDescriptionAttribute]; | 
| 374 | 375 | 
| 375     // Controller may have been (re-)created by switching layout modes, which | 376     // Controller may have been (re-)created by switching layout modes, which | 
| 376     // means the tab model is already fully formed with tabs. Need to walk the | 377     // means the tab model is already fully formed with tabs. Need to walk the | 
| 377     // list and create the UI for each. | 378     // list and create the UI for each. | 
| 378     const int existingTabCount = tabStripModel_->count(); | 379     const int existingTabCount = tabStripModel_->count(); | 
| 379     const TabContents* selection = tabStripModel_->GetSelectedTabContents(); | 380     const TabContentsWrapper* selection = | 
|  | 381         tabStripModel_->GetSelectedTabContents(); | 
| 380     for (int i = 0; i < existingTabCount; ++i) { | 382     for (int i = 0; i < existingTabCount; ++i) { | 
| 381       TabContents* currentContents = tabStripModel_->GetTabContentsAt(i); | 383       TabContentsWrapper* currentContents = tabStripModel_->GetTabContentsAt(i); | 
| 382       [self insertTabWithContents:currentContents | 384       [self insertTabWithContents:currentContents | 
| 383                           atIndex:i | 385                           atIndex:i | 
| 384                      inForeground:NO]; | 386                      inForeground:NO]; | 
| 385       if (selection == currentContents) { | 387       if (selection == currentContents) { | 
| 386         // Must manually force a selection since the model won't send | 388         // Must manually force a selection since the model won't send | 
| 387         // selection messages in this scenario. | 389         // selection messages in this scenario. | 
| 388         [self selectTabWithContents:currentContents | 390         [self selectTabWithContents:currentContents | 
| 389                    previousContents:NULL | 391                    previousContents:NULL | 
| 390                             atIndex:i | 392                             atIndex:i | 
| 391                         userGesture:NO]; | 393                         userGesture:NO]; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 467   } | 469   } | 
| 468 | 470 | 
| 469   // New content is in place, delegate should adjust itself accordingly. | 471   // New content is in place, delegate should adjust itself accordingly. | 
| 470   [delegate_ onSelectTabWithContents:[controller tabContents]]; | 472   [delegate_ onSelectTabWithContents:[controller tabContents]]; | 
| 471 | 473 | 
| 472   // It also restores content autoresizing properties. | 474   // It also restores content autoresizing properties. | 
| 473   [controller ensureContentsVisible]; | 475   [controller ensureContentsVisible]; | 
| 474 | 476 | 
| 475   // Make sure the new tabs's sheets are visible (necessary when a background | 477   // Make sure the new tabs's sheets are visible (necessary when a background | 
| 476   // tab opened a sheet while it was in the background and now becomes active). | 478   // tab opened a sheet while it was in the background and now becomes active). | 
| 477   TabContents* newTab = tabStripModel_->GetTabContentsAt(modelIndex); | 479   TabContentsWrapper* newTab = tabStripModel_->GetTabContentsAt(modelIndex); | 
| 478   DCHECK(newTab); | 480   DCHECK(newTab); | 
| 479   if (newTab) { | 481   if (newTab) { | 
| 480     TabContents::ConstrainedWindowList::iterator it, end; | 482     TabContents::ConstrainedWindowList::iterator it, end; | 
| 481     end = newTab->constrained_window_end(); | 483     end = newTab->tab_contents()->constrained_window_end(); | 
| 482     NSWindowController* controller = [[newView window] windowController]; | 484     NSWindowController* controller = [[newView window] windowController]; | 
| 483     DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 485     DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 
| 484 | 486 | 
| 485     for (it = newTab->constrained_window_begin(); it != end; ++it) { | 487     for (it = newTab->tab_contents()->constrained_window_begin(); | 
|  | 488          it != end; | 
|  | 489          ++it) { | 
| 486       ConstrainedWindow* constrainedWindow = *it; | 490       ConstrainedWindow* constrainedWindow = *it; | 
| 487       static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( | 491       static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( | 
| 488           static_cast<BrowserWindowController*>(controller)); | 492           static_cast<BrowserWindowController*>(controller)); | 
| 489     } | 493     } | 
| 490   } | 494   } | 
| 491 | 495 | 
| 492   // Tell per-tab sheet manager about currently selected tab. | 496   // Tell per-tab sheet manager about currently selected tab. | 
| 493   if (sheetController_.get()) { | 497   if (sheetController_.get()) { | 
| 494     [sheetController_ setActiveView:newView]; | 498     [sheetController_ setActiveView:newView]; | 
| 495   } | 499   } | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 620 - (void)closeTab:(id)sender { | 624 - (void)closeTab:(id)sender { | 
| 621   DCHECK([sender isKindOfClass:[TabView class]]); | 625   DCHECK([sender isKindOfClass:[TabView class]]); | 
| 622   if ([hoveredTab_ isEqual:sender]) { | 626   if ([hoveredTab_ isEqual:sender]) { | 
| 623     hoveredTab_ = nil; | 627     hoveredTab_ = nil; | 
| 624   } | 628   } | 
| 625 | 629 | 
| 626   NSInteger index = [self modelIndexForTabView:sender]; | 630   NSInteger index = [self modelIndexForTabView:sender]; | 
| 627   if (!tabStripModel_->ContainsIndex(index)) | 631   if (!tabStripModel_->ContainsIndex(index)) | 
| 628     return; | 632     return; | 
| 629 | 633 | 
| 630   TabContents* contents = tabStripModel_->GetTabContentsAt(index); | 634   TabContentsWrapper* contents = tabStripModel_->GetTabContentsAt(index); | 
| 631   if (contents) | 635   if (contents) | 
| 632     UserMetrics::RecordAction(UserMetricsAction("CloseTab_Mouse"), | 636     UserMetrics::RecordAction(UserMetricsAction("CloseTab_Mouse"), | 
| 633                               contents->profile()); | 637                               contents->tab_contents()->profile()); | 
| 634   const NSInteger numberOfOpenTabs = [self numberOfOpenTabs]; | 638   const NSInteger numberOfOpenTabs = [self numberOfOpenTabs]; | 
| 635   if (numberOfOpenTabs > 1) { | 639   if (numberOfOpenTabs > 1) { | 
| 636     bool isClosingLastTab = index == numberOfOpenTabs - 1; | 640     bool isClosingLastTab = index == numberOfOpenTabs - 1; | 
| 637     if (!isClosingLastTab) { | 641     if (!isClosingLastTab) { | 
| 638       // Limit the width available for laying out tabs so that tabs are not | 642       // Limit the width available for laying out tabs so that tabs are not | 
| 639       // resized until a later time (when the mouse leaves the tab strip). | 643       // resized until a later time (when the mouse leaves the tab strip). | 
| 640       // However, if the tab being closed is a pinned tab, break out of | 644       // However, if the tab being closed is a pinned tab, break out of | 
| 641       // rapid-closure mode since the mouse is almost guaranteed not to be over | 645       // rapid-closure mode since the mouse is almost guaranteed not to be over | 
| 642       // the closebox of the adjacent tab (due to the difference in widths). | 646       // the closebox of the adjacent tab (due to the difference in widths). | 
| 643       // TODO(pinkerton): re-visit when handling tab overflow. | 647       // TODO(pinkerton): re-visit when handling tab overflow. | 
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 953   if (contents) | 957   if (contents) | 
| 954     titleString = base::SysUTF16ToNSString(contents->GetTitle()); | 958     titleString = base::SysUTF16ToNSString(contents->GetTitle()); | 
| 955   if (![titleString length]) { | 959   if (![titleString length]) { | 
| 956     titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); | 960     titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); | 
| 957   } | 961   } | 
| 958   [tab setTitle:titleString]; | 962   [tab setTitle:titleString]; | 
| 959 } | 963 } | 
| 960 | 964 | 
| 961 // Called when a notification is received from the model to insert a new tab | 965 // Called when a notification is received from the model to insert a new tab | 
| 962 // at |modelIndex|. | 966 // at |modelIndex|. | 
| 963 - (void)insertTabWithContents:(TabContents*)contents | 967 - (void)insertTabWithContents:(TabContentsWrapper*)contents | 
| 964                       atIndex:(NSInteger)modelIndex | 968                       atIndex:(NSInteger)modelIndex | 
| 965                  inForeground:(bool)inForeground { | 969                  inForeground:(bool)inForeground { | 
| 966   DCHECK(contents); | 970   DCHECK(contents); | 
| 967   DCHECK(modelIndex == TabStripModel::kNoTab || | 971   DCHECK(modelIndex == TabStripModel::kNoTab || | 
| 968          tabStripModel_->ContainsIndex(modelIndex)); | 972          tabStripModel_->ContainsIndex(modelIndex)); | 
| 969 | 973 | 
| 970   // Take closing tabs into account. | 974   // Take closing tabs into account. | 
| 971   NSInteger index = [self indexFromModelIndex:modelIndex]; | 975   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 972 | 976 | 
| 973   // Make a new tab. Load the contents of this tab from the nib and associate | 977   // Make a new tab. Load the contents of this tab from the nib and associate | 
| 974   // the new controller with |contents| so it can be looked up later. | 978   // the new controller with |contents| so it can be looked up later. | 
| 975   scoped_nsobject<TabContentsController> contentsController( | 979   scoped_nsobject<TabContentsController> contentsController( | 
| 976       [[TabContentsController alloc] initWithContents:contents delegate:self]); | 980       [[TabContentsController alloc] initWithContents:contents->tab_contents() | 
|  | 981                                              delegate:self]); | 
| 977   [tabContentsArray_ insertObject:contentsController atIndex:index]; | 982   [tabContentsArray_ insertObject:contentsController atIndex:index]; | 
| 978 | 983 | 
| 979   // Make a new tab and add it to the strip. Keep track of its controller. | 984   // Make a new tab and add it to the strip. Keep track of its controller. | 
| 980   TabController* newController = [self newTab]; | 985   TabController* newController = [self newTab]; | 
| 981   [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 986   [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 
| 982   [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 987   [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 
| 983   [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 988   [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 
| 984   [tabArray_ insertObject:newController atIndex:index]; | 989   [tabArray_ insertObject:newController atIndex:index]; | 
| 985   NSView* newView = [newController view]; | 990   NSView* newView = [newController view]; | 
| 986 | 991 | 
| 987   // Set the originating frame to just below the strip so that it animates | 992   // Set the originating frame to just below the strip so that it animates | 
| 988   // upwards as it's being initially layed out. Oddly, this works while doing | 993   // upwards as it's being initially layed out. Oddly, this works while doing | 
| 989   // something similar in |-layoutTabs| confuses the window server. | 994   // something similar in |-layoutTabs| confuses the window server. | 
| 990   [newView setFrame:NSOffsetRect([newView frame], | 995   [newView setFrame:NSOffsetRect([newView frame], | 
| 991                                  0, -[[self class] defaultTabHeight])]; | 996                                  0, -[[self class] defaultTabHeight])]; | 
| 992 | 997 | 
| 993   [self setTabTitle:newController withContents:contents]; | 998   [self setTabTitle:newController withContents:contents->tab_contents()]; | 
| 994 | 999 | 
| 995   // If a tab is being inserted, we can again use the entire tab strip width | 1000   // If a tab is being inserted, we can again use the entire tab strip width | 
| 996   // for layout. | 1001   // for layout. | 
| 997   availableResizeWidth_ = kUseFullAvailableWidth; | 1002   availableResizeWidth_ = kUseFullAvailableWidth; | 
| 998 | 1003 | 
| 999   // We don't need to call |-layoutTabs| if the tab will be in the foreground | 1004   // We don't need to call |-layoutTabs| if the tab will be in the foreground | 
| 1000   // because it will get called when the new tab is selected by the tab model. | 1005   // because it will get called when the new tab is selected by the tab model. | 
| 1001   // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1006   // Whenever |-layoutTabs| is called, it'll also add the new subview. | 
| 1002   if (!inForeground) { | 1007   if (!inForeground) { | 
| 1003     [self layoutTabs]; | 1008     [self layoutTabs]; | 
| 1004   } | 1009   } | 
| 1005 | 1010 | 
| 1006   // During normal loading, we won't yet have a favicon and we'll get | 1011   // During normal loading, we won't yet have a favicon and we'll get | 
| 1007   // subsequent state change notifications to show the throbber, but when we're | 1012   // subsequent state change notifications to show the throbber, but when we're | 
| 1008   // dragging a tab out into a new window, we have to put the tab's favicon | 1013   // dragging a tab out into a new window, we have to put the tab's favicon | 
| 1009   // into the right state up front as we won't be told to do it from anywhere | 1014   // into the right state up front as we won't be told to do it from anywhere | 
| 1010   // else. | 1015   // else. | 
| 1011   [self updateFavIconForContents:contents atIndex:modelIndex]; | 1016   [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; | 
| 1012 | 1017 | 
| 1013   // Send a broadcast that the number of tabs have changed. | 1018   // Send a broadcast that the number of tabs have changed. | 
| 1014   [[NSNotificationCenter defaultCenter] | 1019   [[NSNotificationCenter defaultCenter] | 
| 1015       postNotificationName:kTabStripNumberOfTabsChanged | 1020       postNotificationName:kTabStripNumberOfTabsChanged | 
| 1016                     object:self]; | 1021                     object:self]; | 
| 1017 } | 1022 } | 
| 1018 | 1023 | 
| 1019 // Called when a notification is received from the model to select a particular | 1024 // Called when a notification is received from the model to select a particular | 
| 1020 // tab. Swaps in the toolbar and content area associated with |newContents|. | 1025 // tab. Swaps in the toolbar and content area associated with |newContents|. | 
| 1021 - (void)selectTabWithContents:(TabContents*)newContents | 1026 - (void)selectTabWithContents:(TabContentsWrapper*)newContents | 
| 1022              previousContents:(TabContents*)oldContents | 1027              previousContents:(TabContentsWrapper*)oldContents | 
| 1023                       atIndex:(NSInteger)modelIndex | 1028                       atIndex:(NSInteger)modelIndex | 
| 1024                   userGesture:(bool)wasUserGesture { | 1029                   userGesture:(bool)wasUserGesture { | 
| 1025   // Take closing tabs into account. | 1030   // Take closing tabs into account. | 
| 1026   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1031   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1027 | 1032 | 
| 1028   if (oldContents) { | 1033   if (oldContents) { | 
| 1029     int oldModelIndex = | 1034     int oldModelIndex = | 
| 1030         browser_->GetIndexOfController(&(oldContents->controller())); | 1035         browser_->GetIndexOfController(&(oldContents->controller())); | 
| 1031     if (oldModelIndex != -1) {  // When closing a tab, the old tab may be gone. | 1036     if (oldModelIndex != -1) {  // When closing a tab, the old tab may be gone. | 
| 1032       NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; | 1037       NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; | 
| 1033       TabContentsController* oldController = | 1038       TabContentsController* oldController = | 
| 1034           [tabContentsArray_ objectAtIndex:oldIndex]; | 1039           [tabContentsArray_ objectAtIndex:oldIndex]; | 
| 1035       [oldController willBecomeUnselectedTab]; | 1040       [oldController willBecomeUnselectedTab]; | 
| 1036       oldContents->view()->StoreFocus(); | 1041       oldContents->view()->StoreFocus(); | 
| 1037       oldContents->WasHidden(); | 1042       oldContents->tab_contents()->WasHidden(); | 
| 1038     } | 1043     } | 
| 1039   } | 1044   } | 
| 1040 | 1045 | 
| 1041   // De-select all other tabs and select the new tab. | 1046   // De-select all other tabs and select the new tab. | 
| 1042   int i = 0; | 1047   int i = 0; | 
| 1043   for (TabController* current in tabArray_.get()) { | 1048   for (TabController* current in tabArray_.get()) { | 
| 1044     [current setSelected:(i == index) ? YES : NO]; | 1049     [current setSelected:(i == index) ? YES : NO]; | 
| 1045     ++i; | 1050     ++i; | 
| 1046   } | 1051   } | 
| 1047 | 1052 | 
| 1048   // Tell the new tab contents it is about to become the selected tab. Here it | 1053   // Tell the new tab contents it is about to become the selected tab. Here it | 
| 1049   // can do things like make sure the toolbar is up to date. | 1054   // can do things like make sure the toolbar is up to date. | 
| 1050   TabContentsController* newController = | 1055   TabContentsController* newController = | 
| 1051       [tabContentsArray_ objectAtIndex:index]; | 1056       [tabContentsArray_ objectAtIndex:index]; | 
| 1052   [newController willBecomeSelectedTab]; | 1057   [newController willBecomeSelectedTab]; | 
| 1053 | 1058 | 
| 1054   // Relayout for new tabs and to let the selected tab grow to be larger in | 1059   // Relayout for new tabs and to let the selected tab grow to be larger in | 
| 1055   // size than surrounding tabs if the user has many. This also raises the | 1060   // size than surrounding tabs if the user has many. This also raises the | 
| 1056   // selected tab to the top. | 1061   // selected tab to the top. | 
| 1057   [self layoutTabs]; | 1062   [self layoutTabs]; | 
| 1058 | 1063 | 
| 1059   // Swap in the contents for the new tab. | 1064   // Swap in the contents for the new tab. | 
| 1060   [self swapInTabAtIndex:modelIndex]; | 1065   [self swapInTabAtIndex:modelIndex]; | 
| 1061 | 1066 | 
| 1062   if (newContents) { | 1067   if (newContents) { | 
| 1063     newContents->DidBecomeSelected(); | 1068     newContents->tab_contents()->DidBecomeSelected(); | 
| 1064     newContents->view()->RestoreFocus(); | 1069     newContents->view()->RestoreFocus(); | 
| 1065 | 1070 | 
| 1066     if (newContents->find_ui_active()) | 1071     if (newContents->tab_contents()->find_ui_active()) | 
| 1067       browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 1072       browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 
| 1068   } | 1073   } | 
| 1069 } | 1074 } | 
| 1070 | 1075 | 
| 1071 - (void)tabReplacedWithContents:(TabContents*)newContents | 1076 - (void)tabReplacedWithContents:(TabContentsWrapper*)newContents | 
| 1072                previousContents:(TabContents*)oldContents | 1077                previousContents:(TabContentsWrapper*)oldContents | 
| 1073                         atIndex:(NSInteger)modelIndex { | 1078                         atIndex:(NSInteger)modelIndex { | 
| 1074   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1079   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1075   TabContentsController* oldController = | 1080   TabContentsController* oldController = | 
| 1076       [tabContentsArray_ objectAtIndex:index]; | 1081       [tabContentsArray_ objectAtIndex:index]; | 
| 1077   DCHECK_EQ(oldContents, [oldController tabContents]); | 1082   DCHECK_EQ(oldContents->tab_contents(), [oldController tabContents]); | 
| 1078 | 1083 | 
| 1079   // Simply create a new TabContentsController for |newContents| and place it | 1084   // Simply create a new TabContentsController for |newContents| and place it | 
| 1080   // into the array, replacing |oldContents|.  A TabSelectedAt notification will | 1085   // into the array, replacing |oldContents|.  A TabSelectedAt notification will | 
| 1081   // follow, at which point we will install the new view. | 1086   // follow, at which point we will install the new view. | 
| 1082   scoped_nsobject<TabContentsController> newController( | 1087   scoped_nsobject<TabContentsController> newController( | 
|  | 1088 <<<<<<< .mine | 
|  | 1089       [[TabContentsController alloc] | 
|  | 1090           initWithContents:newContents->tab_contents()]); | 
|  | 1091 ======= | 
| 1083       [[TabContentsController alloc] initWithContents:newContents | 1092       [[TabContentsController alloc] initWithContents:newContents | 
| 1084                                              delegate:self]); | 1093                                              delegate:self]); | 
|  | 1094 >>>>>>> .r66339 | 
| 1085 | 1095 | 
| 1086   // Bye bye, |oldController|. | 1096   // Bye bye, |oldController|. | 
| 1087   [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; | 1097   [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; | 
| 1088 | 1098 | 
| 1089   [delegate_ onReplaceTabWithContents:newContents]; | 1099   [delegate_ onReplaceTabWithContents:newContents->tab_contents()]; | 
| 1090 } | 1100 } | 
| 1091 | 1101 | 
| 1092 // Remove all knowledge about this tab and its associated controller, and remove | 1102 // Remove all knowledge about this tab and its associated controller, and remove | 
| 1093 // the view from the strip. | 1103 // the view from the strip. | 
| 1094 - (void)removeTab:(TabController*)controller { | 1104 - (void)removeTab:(TabController*)controller { | 
| 1095   NSUInteger index = [tabArray_ indexOfObject:controller]; | 1105   NSUInteger index = [tabArray_ indexOfObject:controller]; | 
| 1096 | 1106 | 
| 1097   // Release the tab contents controller so those views get destroyed. This | 1107   // Release the tab contents controller so those views get destroyed. This | 
| 1098   // will remove all the tab content Cocoa views from the hierarchy. A | 1108   // will remove all the tab content Cocoa views from the hierarchy. A | 
| 1099   // subsequent "select tab" notification will follow from the model. To | 1109   // subsequent "select tab" notification will follow from the model. To | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1164   NSRect newFrame = [tabView frame]; | 1174   NSRect newFrame = [tabView frame]; | 
| 1165   newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); | 1175   newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); | 
| 1166   ScopedNSAnimationContextGroup animationGroup(true); | 1176   ScopedNSAnimationContextGroup animationGroup(true); | 
| 1167   animationGroup.SetCurrentContextDuration(kAnimationDuration); | 1177   animationGroup.SetCurrentContextDuration(kAnimationDuration); | 
| 1168   [[tabView animator] setFrame:newFrame]; | 1178   [[tabView animator] setFrame:newFrame]; | 
| 1169 } | 1179 } | 
| 1170 | 1180 | 
| 1171 // Called when a notification is received from the model that the given tab | 1181 // Called when a notification is received from the model that the given tab | 
| 1172 // has gone away. Start an animation then force a layout to put everything | 1182 // has gone away. Start an animation then force a layout to put everything | 
| 1173 // in motion. | 1183 // in motion. | 
| 1174 - (void)tabDetachedWithContents:(TabContents*)contents | 1184 - (void)tabDetachedWithContents:(TabContentsWrapper*)contents | 
| 1175                         atIndex:(NSInteger)modelIndex { | 1185                         atIndex:(NSInteger)modelIndex { | 
| 1176   // Take closing tabs into account. | 1186   // Take closing tabs into account. | 
| 1177   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1187   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1178 | 1188 | 
| 1179   TabController* tab = [tabArray_ objectAtIndex:index]; | 1189   TabController* tab = [tabArray_ objectAtIndex:index]; | 
| 1180   if (tabStripModel_->count() > 0) { | 1190   if (tabStripModel_->count() > 0) { | 
| 1181     [self startClosingTabWithAnimation:tab]; | 1191     [self startClosingTabWithAnimation:tab]; | 
| 1182     [self layoutTabs]; | 1192     [self layoutTabs]; | 
| 1183   } else { | 1193   } else { | 
| 1184     [self removeTab:tab]; | 1194     [self removeTab:tab]; | 
| 1185   } | 1195   } | 
| 1186 | 1196 | 
| 1187   // Send a broadcast that the number of tabs have changed. | 1197   // Send a broadcast that the number of tabs have changed. | 
| 1188   [[NSNotificationCenter defaultCenter] | 1198   [[NSNotificationCenter defaultCenter] | 
| 1189       postNotificationName:kTabStripNumberOfTabsChanged | 1199       postNotificationName:kTabStripNumberOfTabsChanged | 
| 1190                     object:self]; | 1200                     object:self]; | 
| 1191 | 1201 | 
| 1192   [delegate_ onTabDetachedWithContents:contents]; | 1202   [delegate_ onTabDetachedWithContents:contents->tab_contents()]; | 
| 1193 } | 1203 } | 
| 1194 | 1204 | 
| 1195 // A helper routine for creating an NSImageView to hold the fav icon or app icon | 1205 // A helper routine for creating an NSImageView to hold the fav icon or app icon | 
| 1196 // for |contents|. | 1206 // for |contents|. | 
| 1197 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 1207 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 
| 1198   BOOL isApp = contents->is_app(); | 1208   BOOL isApp = contents->is_app(); | 
| 1199   NSImage* image = nil; | 1209   NSImage* image = nil; | 
| 1200   if (isApp) { | 1210   if (isApp) { | 
| 1201     SkBitmap* icon = contents->GetExtensionAppIcon(); | 1211     SkBitmap* icon = contents->GetExtensionAppIcon(); | 
| 1202     if (icon) | 1212     if (icon) | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1282       } | 1292       } | 
| 1283     } | 1293     } | 
| 1284 | 1294 | 
| 1285     [tabController setIconView:iconView]; | 1295     [tabController setIconView:iconView]; | 
| 1286   } | 1296   } | 
| 1287 } | 1297 } | 
| 1288 | 1298 | 
| 1289 // Called when a notification is received from the model that the given tab | 1299 // Called when a notification is received from the model that the given tab | 
| 1290 // has been updated. |loading| will be YES when we only want to update the | 1300 // has been updated. |loading| will be YES when we only want to update the | 
| 1291 // throbber state, not anything else about the (partially) loading tab. | 1301 // throbber state, not anything else about the (partially) loading tab. | 
| 1292 - (void)tabChangedWithContents:(TabContents*)contents | 1302 - (void)tabChangedWithContents:(TabContentsWrapper*)contents | 
| 1293                        atIndex:(NSInteger)modelIndex | 1303                        atIndex:(NSInteger)modelIndex | 
| 1294                     changeType:(TabStripModelObserver::TabChangeType)change { | 1304                     changeType:(TabStripModelObserver::TabChangeType)change { | 
| 1295   // Take closing tabs into account. | 1305   // Take closing tabs into account. | 
| 1296   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1306   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1297 | 1307 | 
| 1298   if (modelIndex == tabStripModel_->selected_index()) | 1308   if (modelIndex == tabStripModel_->selected_index()) | 
| 1299     [delegate_ onSelectedTabChange:change]; | 1309     [delegate_ onSelectedTabChange:change]; | 
| 1300 | 1310 | 
| 1301   if (change == TabStripModelObserver::TITLE_NOT_LOADING) { | 1311   if (change == TabStripModelObserver::TITLE_NOT_LOADING) { | 
| 1302     // TODO(sky): make this work. | 1312     // TODO(sky): make this work. | 
| 1303     // We'll receive another notification of the change asynchronously. | 1313     // We'll receive another notification of the change asynchronously. | 
| 1304     return; | 1314     return; | 
| 1305   } | 1315   } | 
| 1306 | 1316 | 
| 1307   TabController* tabController = [tabArray_ objectAtIndex:index]; | 1317   TabController* tabController = [tabArray_ objectAtIndex:index]; | 
| 1308 | 1318 | 
| 1309   if (change != TabStripModelObserver::LOADING_ONLY) | 1319   if (change != TabStripModelObserver::LOADING_ONLY) | 
| 1310     [self setTabTitle:tabController withContents:contents]; | 1320     [self setTabTitle:tabController withContents:contents->tab_contents()]; | 
| 1311 | 1321 | 
| 1312   [self updateFavIconForContents:contents atIndex:modelIndex]; | 1322   [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; | 
| 1313 | 1323 | 
| 1314   TabContentsController* updatedController = | 1324   TabContentsController* updatedController = | 
| 1315       [tabContentsArray_ objectAtIndex:index]; | 1325       [tabContentsArray_ objectAtIndex:index]; | 
| 1316   [updatedController tabDidChange:contents]; | 1326   [updatedController tabDidChange:contents->tab_contents()]; | 
| 1317 } | 1327 } | 
| 1318 | 1328 | 
| 1319 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1329 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 
| 1320 // in sync with the tab strip model. It can also be pinned/unpinned | 1330 // in sync with the tab strip model. It can also be pinned/unpinned | 
| 1321 // simultaneously, so we need to take care of that. | 1331 // simultaneously, so we need to take care of that. | 
| 1322 - (void)tabMovedWithContents:(TabContents*)contents | 1332 - (void)tabMovedWithContents:(TabContentsWrapper*)contents | 
| 1323                    fromIndex:(NSInteger)modelFrom | 1333                    fromIndex:(NSInteger)modelFrom | 
| 1324                      toIndex:(NSInteger)modelTo { | 1334                      toIndex:(NSInteger)modelTo { | 
| 1325   // Take closing tabs into account. | 1335   // Take closing tabs into account. | 
| 1326   NSInteger from = [self indexFromModelIndex:modelFrom]; | 1336   NSInteger from = [self indexFromModelIndex:modelFrom]; | 
| 1327   NSInteger to = [self indexFromModelIndex:modelTo]; | 1337   NSInteger to = [self indexFromModelIndex:modelTo]; | 
| 1328 | 1338 | 
| 1329   scoped_nsobject<TabContentsController> movedTabContentsController( | 1339   scoped_nsobject<TabContentsController> movedTabContentsController( | 
| 1330       [[tabContentsArray_ objectAtIndex:from] retain]); | 1340       [[tabContentsArray_ objectAtIndex:from] retain]); | 
| 1331   [tabContentsArray_ removeObjectAtIndex:from]; | 1341   [tabContentsArray_ removeObjectAtIndex:from]; | 
| 1332   [tabContentsArray_ insertObject:movedTabContentsController.get() | 1342   [tabContentsArray_ insertObject:movedTabContentsController.get() | 
| 1333                           atIndex:to]; | 1343                           atIndex:to]; | 
| 1334   scoped_nsobject<TabController> movedTabController( | 1344   scoped_nsobject<TabController> movedTabController( | 
| 1335       [[tabArray_ objectAtIndex:from] retain]); | 1345       [[tabArray_ objectAtIndex:from] retain]); | 
| 1336   DCHECK([movedTabController isKindOfClass:[TabController class]]); | 1346   DCHECK([movedTabController isKindOfClass:[TabController class]]); | 
| 1337   [tabArray_ removeObjectAtIndex:from]; | 1347   [tabArray_ removeObjectAtIndex:from]; | 
| 1338   [tabArray_ insertObject:movedTabController.get() atIndex:to]; | 1348   [tabArray_ insertObject:movedTabController.get() atIndex:to]; | 
| 1339 | 1349 | 
| 1340   // The tab moved, which means that the mini-tab state may have changed. | 1350   // The tab moved, which means that the mini-tab state may have changed. | 
| 1341   if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) | 1351   if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) | 
| 1342     [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; | 1352     [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; | 
| 1343 | 1353 | 
| 1344   [self layoutTabs]; | 1354   [self layoutTabs]; | 
| 1345 } | 1355 } | 
| 1346 | 1356 | 
| 1347 // Called when a tab is pinned or unpinned without moving. | 1357 // Called when a tab is pinned or unpinned without moving. | 
| 1348 - (void)tabMiniStateChangedWithContents:(TabContents*)contents | 1358 - (void)tabMiniStateChangedWithContents:(TabContentsWrapper*)contents | 
| 1349                                 atIndex:(NSInteger)modelIndex { | 1359                                 atIndex:(NSInteger)modelIndex { | 
| 1350   // Take closing tabs into account. | 1360   // Take closing tabs into account. | 
| 1351   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1361   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1352 | 1362 | 
| 1353   TabController* tabController = [tabArray_ objectAtIndex:index]; | 1363   TabController* tabController = [tabArray_ objectAtIndex:index]; | 
| 1354   DCHECK([tabController isKindOfClass:[TabController class]]); | 1364   DCHECK([tabController isKindOfClass:[TabController class]]); | 
| 1355 | 1365 | 
| 1356   // Don't do anything if the change was already picked up by the move event. | 1366   // Don't do anything if the change was already picked up by the move event. | 
| 1357   if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1367   if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 
| 1358     return; | 1368     return; | 
| 1359 | 1369 | 
| 1360   [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1370   [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 
| 1361   [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1371   [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 
| 1362   [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1372   [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 
| 1363   [self updateFavIconForContents:contents atIndex:modelIndex]; | 1373   [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; | 
| 1364   // If the tab is being restored and it's pinned, the mini state is set after | 1374   // If the tab is being restored and it's pinned, the mini state is set after | 
| 1365   // the tab has already been rendered, so re-layout the tabstrip. In all other | 1375   // the tab has already been rendered, so re-layout the tabstrip. In all other | 
| 1366   // cases, the state is set before the tab is rendered so this isn't needed. | 1376   // cases, the state is set before the tab is rendered so this isn't needed. | 
| 1367   [self layoutTabs]; | 1377   [self layoutTabs]; | 
| 1368 } | 1378 } | 
| 1369 | 1379 | 
| 1370 - (void)setFrameOfSelectedTab:(NSRect)frame { | 1380 - (void)setFrameOfSelectedTab:(NSRect)frame { | 
| 1371   NSView* view = [self selectedTabView]; | 1381   NSView* view = [self selectedTabView]; | 
| 1372   NSValue* identifier = [NSValue valueWithPointer:view]; | 1382   NSValue* identifier = [NSValue valueWithPointer:view]; | 
| 1373   [targetFrames_ setObject:[NSValue valueWithRect:frame] | 1383   [targetFrames_ setObject:[NSValue valueWithRect:frame] | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1427 | 1437 | 
| 1428 // Drop a given TabContents at the location of the current placeholder. If there | 1438 // Drop a given TabContents at the location of the current placeholder. If there | 
| 1429 // is no placeholder, it will go at the end. Used when dragging from another | 1439 // is no placeholder, it will go at the end. Used when dragging from another | 
| 1430 // window when we don't have access to the TabContents as part of our strip. | 1440 // window when we don't have access to the TabContents as part of our strip. | 
| 1431 // |frame| is in the coordinate system of the tab strip view and represents | 1441 // |frame| is in the coordinate system of the tab strip view and represents | 
| 1432 // where the user dropped the new tab so it can be animated into its correct | 1442 // where the user dropped the new tab so it can be animated into its correct | 
| 1433 // location when the tab is added to the model. If the tab was pinned in its | 1443 // location when the tab is added to the model. If the tab was pinned in its | 
| 1434 // previous window, setting |pinned| to YES will propagate that state to the | 1444 // previous window, setting |pinned| to YES will propagate that state to the | 
| 1435 // new window. Mini-tabs are either app or pinned tabs; the app state is stored | 1445 // new window. Mini-tabs are either app or pinned tabs; the app state is stored | 
| 1436 // by the |contents|, but the |pinned| state is the caller's responsibility. | 1446 // by the |contents|, but the |pinned| state is the caller's responsibility. | 
| 1437 - (void)dropTabContents:(TabContents*)contents | 1447 - (void)dropTabContents:(TabContentsWrapper*)contents | 
| 1438               withFrame:(NSRect)frame | 1448               withFrame:(NSRect)frame | 
| 1439             asPinnedTab:(BOOL)pinned { | 1449             asPinnedTab:(BOOL)pinned { | 
| 1440   int modelIndex = [self indexOfPlaceholder]; | 1450   int modelIndex = [self indexOfPlaceholder]; | 
| 1441 | 1451 | 
| 1442   // Mark that the new tab being created should start at |frame|. It will be | 1452   // Mark that the new tab being created should start at |frame|. It will be | 
| 1443   // reset as soon as the tab has been positioned. | 1453   // reset as soon as the tab has been positioned. | 
| 1444   droppedTabFrame_ = frame; | 1454   droppedTabFrame_ = frame; | 
| 1445 | 1455 | 
| 1446   // Insert it into this tab strip. We want it in the foreground and to not | 1456   // Insert it into this tab strip. We want it in the foreground and to not | 
| 1447   // inherit the current tab's group. | 1457   // inherit the current tab's group. | 
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1708       params.disposition = disposition; | 1718       params.disposition = disposition; | 
| 1709       params.tabstrip_index = index; | 1719       params.tabstrip_index = index; | 
| 1710       params.tabstrip_add_types = | 1720       params.tabstrip_add_types = | 
| 1711           TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; | 1721           TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; | 
| 1712       browser::Navigate(¶ms); | 1722       browser::Navigate(¶ms); | 
| 1713       break; | 1723       break; | 
| 1714     } | 1724     } | 
| 1715     case CURRENT_TAB: | 1725     case CURRENT_TAB: | 
| 1716       UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), | 1726       UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), | 
| 1717                                 browser_->profile()); | 1727                                 browser_->profile()); | 
| 1718       tabStripModel_->GetTabContentsAt(index)->OpenURL(url, GURL(), CURRENT_TAB, | 1728       tabStripModel_->GetTabContentsAt(index) | 
| 1719                                                        PageTransition::TYPED); | 1729           ->tab_contents()->OpenURL(url, GURL(), CURRENT_TAB, | 
|  | 1730                                     PageTransition::TYPED); | 
| 1720       tabStripModel_->SelectTabContentsAt(index, true); | 1731       tabStripModel_->SelectTabContentsAt(index, true); | 
| 1721       break; | 1732       break; | 
| 1722     default: | 1733     default: | 
| 1723       NOTIMPLEMENTED(); | 1734       NOTIMPLEMENTED(); | 
| 1724   } | 1735   } | 
| 1725 } | 1736 } | 
| 1726 | 1737 | 
| 1727 // (URLDropTargetController protocol) | 1738 // (URLDropTargetController protocol) | 
| 1728 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { | 1739 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { | 
| 1729   DCHECK_EQ(view, tabStripView_.get()); | 1740   DCHECK_EQ(view, tabStripView_.get()); | 
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1858   NSInteger index = [self indexFromModelIndex:modelIndex]; | 1869   NSInteger index = [self indexFromModelIndex:modelIndex]; | 
| 1859   BrowserWindowController* controller = | 1870   BrowserWindowController* controller = | 
| 1860       (BrowserWindowController*)[[switchView_ window] windowController]; | 1871       (BrowserWindowController*)[[switchView_ window] windowController]; | 
| 1861   DCHECK(index >= 0); | 1872   DCHECK(index >= 0); | 
| 1862   if (index >= 0) { | 1873   if (index >= 0) { | 
| 1863     [controller setTab:[self viewAtIndex:index] isDraggable:YES]; | 1874     [controller setTab:[self viewAtIndex:index] isDraggable:YES]; | 
| 1864   } | 1875   } | 
| 1865 } | 1876 } | 
| 1866 | 1877 | 
| 1867 @end | 1878 @end | 
| OLD | NEW | 
|---|