| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 10 matching lines...) Expand all Loading... |
| 21 #include "chrome/browser/metrics/user_metrics.h" | 21 #include "chrome/browser/metrics/user_metrics.h" |
| 22 #include "chrome/browser/profile.h" | 22 #include "chrome/browser/profile.h" |
| 23 #import "chrome/browser/cocoa/browser_window_controller.h" | 23 #import "chrome/browser/cocoa/browser_window_controller.h" |
| 24 #import "chrome/browser/cocoa/constrained_window_mac.h" | 24 #import "chrome/browser/cocoa/constrained_window_mac.h" |
| 25 #import "chrome/browser/cocoa/tab_strip_view.h" | 25 #import "chrome/browser/cocoa/tab_strip_view.h" |
| 26 #import "chrome/browser/cocoa/tab_contents_controller.h" | 26 #import "chrome/browser/cocoa/tab_contents_controller.h" |
| 27 #import "chrome/browser/cocoa/tab_controller.h" | 27 #import "chrome/browser/cocoa/tab_controller.h" |
| 28 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" | 28 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" |
| 29 #import "chrome/browser/cocoa/tab_view.h" | 29 #import "chrome/browser/cocoa/tab_view.h" |
| 30 #import "chrome/browser/cocoa/throbber_view.h" | 30 #import "chrome/browser/cocoa/throbber_view.h" |
| 31 #include "chrome/browser/debugger/devtools_window.h" |
| 31 #include "chrome/browser/net/url_fixer_upper.h" | 32 #include "chrome/browser/net/url_fixer_upper.h" |
| 32 #include "chrome/browser/tab_contents/navigation_controller.h" | 33 #include "chrome/browser/tab_contents/navigation_controller.h" |
| 33 #include "chrome/browser/tab_contents/navigation_entry.h" | 34 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 34 #include "chrome/browser/tab_contents/tab_contents.h" | 35 #include "chrome/browser/tab_contents/tab_contents.h" |
| 35 #include "chrome/browser/tab_contents/tab_contents_view.h" | 36 #include "chrome/browser/tab_contents/tab_contents_view.h" |
| 36 #include "chrome/browser/tabs/tab_strip_model.h" | 37 #include "chrome/browser/tabs/tab_strip_model.h" |
| 37 #include "grit/app_resources.h" | 38 #include "grit/app_resources.h" |
| 38 #include "grit/generated_resources.h" | 39 #include "grit/generated_resources.h" |
| 39 #include "grit/theme_resources.h" | 40 #include "grit/theme_resources.h" |
| 40 #include "skia/ext/skia_utils_mac.h" | 41 #include "skia/ext/skia_utils_mac.h" |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 } | 455 } |
| 455 | 456 |
| 456 // (Private) Returns the number of open, unpinned tabs. | 457 // (Private) Returns the number of open, unpinned tabs. |
| 457 - (NSInteger)numberOfOpenUnpinnedTabs { | 458 - (NSInteger)numberOfOpenUnpinnedTabs { |
| 458 NSInteger number = [self numberOfOpenTabs] - [self numberOfOpenPinnedTabs]; | 459 NSInteger number = [self numberOfOpenTabs] - [self numberOfOpenPinnedTabs]; |
| 459 DCHECK_GE(number, 0); | 460 DCHECK_GE(number, 0); |
| 460 return number; | 461 return number; |
| 461 } | 462 } |
| 462 | 463 |
| 463 // Given an index into the tab model, returns the index into the tab controller | 464 // Given an index into the tab model, returns the index into the tab controller |
| 464 // array accounting for tabs that are currently closing. For example, if there | 465 // or tab contents controller array accounting for tabs that are currently |
| 465 // are two tabs in the process of closing before |index|, this returns | 466 // closing. For example, if there are two tabs in the process of closing before |
| 466 // |index| + 2. If there are no closing tabs, this will return |index|. | 467 // |index|, this returns |index| + 2. If there are no closing tabs, this will |
| 468 // return |index|. |
| 467 - (NSInteger)indexFromModelIndex:(NSInteger)index { | 469 - (NSInteger)indexFromModelIndex:(NSInteger)index { |
| 470 DCHECK(index >= 0); |
| 471 if (index < 0) |
| 472 return index; |
| 473 |
| 468 NSInteger i = 0; | 474 NSInteger i = 0; |
| 469 for (TabController* controller in tabArray_.get()) { | 475 for (TabController* controller in tabArray_.get()) { |
| 470 if ([closingControllers_ containsObject:controller]) { | 476 if ([closingControllers_ containsObject:controller]) { |
| 471 DCHECK([(TabView*)[controller view] isClosing]); | 477 DCHECK([(TabView*)[controller view] isClosing]); |
| 472 ++index; | 478 ++index; |
| 473 } | 479 } |
| 474 if (i == index) // No need to check anything after, it has no effect. | 480 if (i == index) // No need to check anything after, it has no effect. |
| 475 break; | 481 break; |
| 476 ++i; | 482 ++i; |
| 477 } | 483 } |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 TabContentsController* oldController = | 936 TabContentsController* oldController = |
| 931 [tabContentsArray_ objectAtIndex:index]; | 937 [tabContentsArray_ objectAtIndex:index]; |
| 932 [oldController willBecomeUnselectedTab]; | 938 [oldController willBecomeUnselectedTab]; |
| 933 oldContents->view()->StoreFocus(); | 939 oldContents->view()->StoreFocus(); |
| 934 oldContents->WasHidden(); | 940 oldContents->WasHidden(); |
| 935 } | 941 } |
| 936 } | 942 } |
| 937 | 943 |
| 938 // Swap in the contents for the new tab. | 944 // Swap in the contents for the new tab. |
| 939 [self swapInTabAtIndex:modelIndex]; | 945 [self swapInTabAtIndex:modelIndex]; |
| 946 [self updateDevToolsForContents:newContents]; |
| 940 | 947 |
| 941 if (newContents) { | 948 if (newContents) { |
| 942 newContents->DidBecomeSelected(); | 949 newContents->DidBecomeSelected(); |
| 943 newContents->view()->RestoreFocus(); | 950 newContents->view()->RestoreFocus(); |
| 944 | 951 |
| 945 if (newContents->find_ui_active()) | 952 if (newContents->find_ui_active()) |
| 946 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 953 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); |
| 947 } | 954 } |
| 948 } | 955 } |
| 949 | 956 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1036 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1030 | 1037 |
| 1031 TabController* tab = [tabArray_ objectAtIndex:index]; | 1038 TabController* tab = [tabArray_ objectAtIndex:index]; |
| 1032 if (tabStripModel_->count() > 0) { | 1039 if (tabStripModel_->count() > 0) { |
| 1033 [self startClosingTabWithAnimation:tab]; | 1040 [self startClosingTabWithAnimation:tab]; |
| 1034 [self layoutTabs]; | 1041 [self layoutTabs]; |
| 1035 } else { | 1042 } else { |
| 1036 [self removeTab:tab]; | 1043 [self removeTab:tab]; |
| 1037 } | 1044 } |
| 1038 | 1045 |
| 1046 // Does nothing, purely for consistency with the windows/linux code. |
| 1047 [self updateDevToolsForContents:NULL]; |
| 1048 |
| 1039 // Send a broadcast that the number of tabs have changed. | 1049 // Send a broadcast that the number of tabs have changed. |
| 1040 [[NSNotificationCenter defaultCenter] | 1050 [[NSNotificationCenter defaultCenter] |
| 1041 postNotificationName:kTabStripNumberOfTabsChanged | 1051 postNotificationName:kTabStripNumberOfTabsChanged |
| 1042 object:self]; | 1052 object:self]; |
| 1043 } | 1053 } |
| 1044 | 1054 |
| 1045 // A helper routine for creating an NSImageView to hold the fav icon for | 1055 // A helper routine for creating an NSImageView to hold the fav icon for |
| 1046 // |contents|. | 1056 // |contents|. |
| 1047 - (NSImageView*)favIconImageViewForContents:(TabContents*)contents { | 1057 - (NSImageView*)favIconImageViewForContents:(TabContents*)contents { |
| 1048 NSRect iconFrame = NSMakeRect(0, 0, 16, 16); | 1058 NSRect iconFrame = NSMakeRect(0, 0, 16, 16); |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 } | 1609 } |
| 1600 } | 1610 } |
| 1601 | 1611 |
| 1602 - (GTMWindowSheetController*)sheetController { | 1612 - (GTMWindowSheetController*)sheetController { |
| 1603 if (!sheetController_.get()) | 1613 if (!sheetController_.get()) |
| 1604 sheetController_.reset([[GTMWindowSheetController alloc] | 1614 sheetController_.reset([[GTMWindowSheetController alloc] |
| 1605 initWithWindow:[switchView_ window] delegate:self]); | 1615 initWithWindow:[switchView_ window] delegate:self]); |
| 1606 return sheetController_.get(); | 1616 return sheetController_.get(); |
| 1607 } | 1617 } |
| 1608 | 1618 |
| 1619 - (TabContentsController*)activeTabContentsController { |
| 1620 int modelIndex = tabStripModel_->selected_index(); |
| 1621 if (modelIndex < 0) |
| 1622 return nil; |
| 1623 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1624 if (index < 0 || |
| 1625 index >= (NSInteger)[tabContentsArray_ count]) |
| 1626 return nil; |
| 1627 return [tabContentsArray_ objectAtIndex:index]; |
| 1628 } |
| 1629 |
| 1609 - (void)gtm_systemRequestsVisibilityForView:(NSView*)view { | 1630 - (void)gtm_systemRequestsVisibilityForView:(NSView*)view { |
| 1610 // This implementation is required by GTMWindowSheetController. | 1631 // This implementation is required by GTMWindowSheetController. |
| 1611 | 1632 |
| 1612 // Raise window... | 1633 // Raise window... |
| 1613 [[switchView_ window] makeKeyAndOrderFront:self]; | 1634 [[switchView_ window] makeKeyAndOrderFront:self]; |
| 1614 | 1635 |
| 1615 // ...and raise a tab with a sheet. | 1636 // ...and raise a tab with a sheet. |
| 1616 NSInteger index = [self modelIndexForContentsView:view]; | 1637 NSInteger index = [self modelIndexForContentsView:view]; |
| 1617 DCHECK(index >= 0); | 1638 DCHECK(index >= 0); |
| 1618 if (index >= 0) | 1639 if (index >= 0) |
| 1619 tabStripModel_->SelectTabContentsAt(index, false /* not a user gesture */); | 1640 tabStripModel_->SelectTabContentsAt(index, false /* not a user gesture */); |
| 1620 } | 1641 } |
| 1621 | 1642 |
| 1622 - (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window { | 1643 - (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window { |
| 1623 // TODO(thakis, avi): Figure out how to make this work when tabs are dragged | 1644 // TODO(thakis, avi): Figure out how to make this work when tabs are dragged |
| 1624 // out or if fullscreen mode is toggled. | 1645 // out or if fullscreen mode is toggled. |
| 1625 | 1646 |
| 1626 // View hierarchy of the contents view: | 1647 // View hierarchy of the contents view: |
| 1627 // NSView -- switchView, same for all tabs | 1648 // NSView -- switchView, same for all tabs |
| 1628 // +- NSView -- TabContentsController's view | 1649 // +- NSView -- TabContentsController's view |
| 1629 // +- NSBox | 1650 // +- NSSplitView |
| 1630 // +- TabContentsViewCocoa | 1651 // +- TabContentsViewCocoa |
| 1631 // We use the TabContentsController's view in |swapInTabAtIndex|, so we have | 1652 // We use the TabContentsController's view in |swapInTabAtIndex|, so we have |
| 1632 // to pass it to the sheet controller here. | 1653 // to pass it to the sheet controller here. |
| 1633 NSView* tabContentsView = | 1654 NSView* tabContentsView = |
| 1634 [[window->owner()->GetNativeView() superview] superview]; | 1655 [[window->owner()->GetNativeView() superview] superview]; |
| 1635 | 1656 |
| 1636 // TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets | 1657 // TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets |
| 1637 // between windows. Until then, we have to prevent having to move a tabsheet | 1658 // between windows. Until then, we have to prevent having to move a tabsheet |
| 1638 // between windows, e.g. no tearing off of tabs. | 1659 // between windows, e.g. no tearing off of tabs. |
| 1639 NSInteger modelIndex = [self modelIndexForContentsView:tabContentsView]; | 1660 NSInteger modelIndex = [self modelIndexForContentsView:tabContentsView]; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 } else if (removedVisibleSheet && tab == [self selectedTabView]) { | 1714 } else if (removedVisibleSheet && tab == [self selectedTabView]) { |
| 1694 // Show next sheet | 1715 // Show next sheet |
| 1695 NSWindowController* controller = [[tab window] windowController]; | 1716 NSWindowController* controller = [[tab window] windowController]; |
| 1696 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 1717 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); |
| 1697 windows.front()->Realize( | 1718 windows.front()->Realize( |
| 1698 static_cast<BrowserWindowController*>(controller)); | 1719 static_cast<BrowserWindowController*>(controller)); |
| 1699 } | 1720 } |
| 1700 } | 1721 } |
| 1701 } | 1722 } |
| 1702 | 1723 |
| 1724 - (void)updateDevToolsForContents:(TabContents*)contents { |
| 1725 int modelIndex = tabStripModel_->GetIndexOfTabContents(contents); |
| 1726 |
| 1727 // This happens e.g. if one hits cmd-q with a docked devtools window open. |
| 1728 if (modelIndex == TabStripModel::kNoTab) |
| 1729 return; |
| 1730 |
| 1731 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1732 DCHECK_GE(index, 0); |
| 1733 DCHECK_LT(index, (NSInteger)[tabContentsArray_ count]); |
| 1734 if (index < 0 || index >= (NSInteger)[tabContentsArray_ count]) |
| 1735 return; |
| 1736 |
| 1737 TabContentsController* tabController = |
| 1738 [tabContentsArray_ objectAtIndex:index]; |
| 1739 TabContents* devtoolsContents = contents ? |
| 1740 DevToolsWindow::GetDevToolsContents(contents) : NULL; |
| 1741 [tabController showDevToolsContents:devtoolsContents]; |
| 1742 } |
| 1743 |
| 1703 @end | 1744 @end |
| OLD | NEW |