Index: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
index fd7ad450a8f03932f4b5cf648a967c7295cf1ebe..c09b8d45e10a89a4540ba158cf8c10f7c6c4f006 100644 |
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
@@ -27,6 +27,7 @@ |
#include "chrome/browser/sidebar/sidebar_container.h" |
#include "chrome/browser/sidebar/sidebar_manager.h" |
#include "chrome/browser/tabs/tab_strip_model.h" |
+#include "chrome/browser/tabs/tab_strip_selection_model.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_navigator.h" |
#include "chrome/browser/ui/find_bar/find_tab_helper.h" |
@@ -44,6 +45,7 @@ |
#include "chrome/browser/ui/find_bar/find_bar_controller.h" |
#include "chrome/browser/ui/title_prefix_matcher.h" |
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
+#include "chrome/browser/ui/tabs/tab_menu_model.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/pref_names.h" |
#include "content/browser/tab_contents/navigation_controller.h" |
@@ -622,7 +624,7 @@ class NotificationBridge : public NotificationObserver { |
// |index|, this returns |index| + 2. If there are no closing tabs, this will |
// return |index|. |
- (NSInteger)indexFromModelIndex:(NSInteger)index { |
- DCHECK(index >= 0); |
+ DCHECK_GE(index, 0); |
if (index < 0) |
return index; |
@@ -697,8 +699,18 @@ class NotificationBridge : public NotificationObserver { |
- (void)selectTab:(id)sender { |
DCHECK([sender isKindOfClass:[NSView class]]); |
int index = [self modelIndexForTabView:sender]; |
- if (tabStripModel_->ContainsIndex(index)) |
- tabStripModel_->SelectTabContentsAt(index, true); |
+ NSUInteger modifiers = [[NSApp currentEvent] modifierFlags]; |
+ if (tabStripModel_->ContainsIndex(index)) { |
+ if (modifiers & NSCommandKeyMask && modifiers & NSShiftKeyMask) { |
+ tabStripModel_->AddSelectionFromAnchorTo(index); |
+ } else if (modifiers & NSShiftKeyMask) { |
+ tabStripModel_->ExtendSelectionTo(index); |
+ } else if (modifiers & NSCommandKeyMask) { |
+ tabStripModel_->ToggleSelectionAt(index); |
+ } else if (!tabStripModel_->IsTabSelected(index)) { |
+ tabStripModel_->SelectTabContentsAt(index, true); |
+ } |
+ } |
} |
// Called when the user closes a tab. Asks the model to close the tab. |sender| |
@@ -771,6 +783,13 @@ class NotificationBridge : public NotificationObserver { |
return tabStripModel_->IsContextMenuCommandEnabled(index, command) ? YES : NO; |
} |
+// Returns a context menu model for a given controller. Caller owns the result. |
+- (ui::SimpleMenuModel*)contextMenuModelForController:(TabController*)controller |
+ menuDelegate:(ui::SimpleMenuModel::Delegate*)delegate { |
+ int index = [self modelIndexForTabView:[controller view]]; |
+ return new TabMenuModel(delegate, tabStripModel_, index); |
+} |
+ |
- (void)insertPlaceholderForTab:(TabView*)tab |
frame:(NSRect)frame |
yStretchiness:(CGFloat)yStretchiness { |
@@ -1150,7 +1169,7 @@ class NotificationBridge : public NotificationObserver { |
atIndex:(NSInteger)modelIndex |
userGesture:(bool)wasUserGesture { |
// Take closing tabs into account. |
- NSInteger index = [self indexFromModelIndex:modelIndex]; |
+ NSInteger activeIndex = [self indexFromModelIndex:modelIndex]; |
if (oldContents && oldContents != newContents) { |
int oldModelIndex = |
@@ -1165,17 +1184,26 @@ class NotificationBridge : public NotificationObserver { |
} |
} |
- // De-select all other tabs and select the new tab. |
+ // First get the vector of indices, which is allays sorted in ascending order. |
+ TabStripSelectionModel::SelectedIndices selection( |
+ tabStripModel_->selection_model().selected_indices()); |
+ // Iterate through all of the tabs, selecting each as necessary. |
+ TabStripSelectionModel::SelectedIndices::iterator iter = selection.begin(); |
int i = 0; |
for (TabController* current in tabArray_.get()) { |
- [current setSelected:(i == index) ? YES : NO]; |
+ BOOL selected = iter != selection.end() && |
+ [self indexFromModelIndex:*iter] == i; |
+ [current setSelected:selected]; |
+ [current setActive:i == activeIndex]; |
+ if (selected) |
+ ++iter; |
++i; |
} |
// Tell the new tab contents it is about to become the selected tab. Here it |
// can do things like make sure the toolbar is up to date. |
TabContentsController* newController = |
- [tabContentsArray_ objectAtIndex:index]; |
+ [tabContentsArray_ objectAtIndex:activeIndex]; |
[newController willBecomeSelectedTab]; |
// Relayout for new tabs and to let the selected tab grow to be larger in |
@@ -1511,19 +1539,19 @@ class NotificationBridge : public NotificationObserver { |
[self updateCommonTitlePrefix]; |
} |
-- (void)setFrameOfSelectedTab:(NSRect)frame { |
- NSView* view = [self selectedTabView]; |
+- (void)setFrameOfActiveTab:(NSRect)frame { |
+ NSView* view = [self activeTabView]; |
NSValue* identifier = [NSValue valueWithPointer:view]; |
[targetFrames_ setObject:[NSValue valueWithRect:frame] |
forKey:identifier]; |
[view setFrame:frame]; |
} |
-- (NSView*)selectedTabView { |
- int selectedIndex = tabStripModel_->selected_index(); |
+- (NSView*)activeTabView { |
+ int activeIndex = tabStripModel_->selected_index(); |
// Take closing tabs into account. They can't ever be selected. |
- selectedIndex = [self indexFromModelIndex:selectedIndex]; |
- return [self viewAtIndex:selectedIndex]; |
+ activeIndex = [self indexFromModelIndex:activeIndex]; |
+ return [self viewAtIndex:activeIndex]; |
} |
// Find the model index based on the x coordinate of the placeholder. If there |
@@ -1748,19 +1776,19 @@ class NotificationBridge : public NotificationObserver { |
// ones. |
NSMutableArray* subviews = [NSMutableArray arrayWithArray:permanentSubviews_]; |
- NSView* selectedTabView = nil; |
+ NSView* activeTabView = nil; |
// Go through tabs in reverse order, since |subviews| is bottom-to-top. |
for (TabController* tab in [tabArray_ reverseObjectEnumerator]) { |
NSView* tabView = [tab view]; |
- if ([tab selected]) { |
- DCHECK(!selectedTabView); |
- selectedTabView = tabView; |
+ if ([tab active]) { |
+ DCHECK(!activeTabView); |
+ activeTabView = tabView; |
} else { |
[subviews addObject:tabView]; |
} |
} |
- if (selectedTabView) { |
- [subviews addObject:selectedTabView]; |
+ if (activeTabView) { |
+ [subviews addObject:activeTabView]; |
} |
[tabStripView_ setSubviews:subviews]; |
[self setTabTrackingAreasEnabled:mouseInside_]; |