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 |