1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
#include "content/public/browser/web_contents.h"
///////////////////////////////////////////////////////////////////////////////
// TabStripModelOrderController, public:
TabStripModelOrderController::TabStripModelOrderController(
TabStripModel* tabstrip)
: tabstrip_(tabstrip) {
tabstrip_->AddObserver(this);
}
TabStripModelOrderController::~TabStripModelOrderController() {
tabstrip_->RemoveObserver(this);
}
int TabStripModelOrderController::DetermineInsertionIndex(
ui::PageTransition transition,
bool foreground) {
int tab_count = tabstrip_->count();
if (!tab_count)
return 0;
// NOTE: TabStripModel enforces that all non-mini-tabs occur after mini-tabs,
// so we don't have to check here too.
if (transition == ui::PAGE_TRANSITION_LINK &&
tabstrip_->active_index() != -1) {
if (foreground) {
// If the page was opened in the foreground by a link click in another
// tab, insert it adjacent to the tab that opened that link.
return tabstrip_->active_index() + 1;
}
content::WebContents* opener = tabstrip_->GetActiveWebContents();
// Get the index of the next item opened by this tab, and insert after
// it...
int index = tabstrip_->GetIndexOfLastWebContentsOpenedBy(
opener, tabstrip_->active_index());
if (index != TabStripModel::kNoTab)
return index + 1;
// Otherwise insert adjacent to opener...
return tabstrip_->active_index() + 1;
}
// In other cases, such as Ctrl+T, open at the end of the strip.
return tabstrip_->count();
}
int TabStripModelOrderController::DetermineNewSelectedIndex(
int removing_index) const {
int tab_count = tabstrip_->count();
DCHECK(removing_index >= 0 && removing_index < tab_count);
content::WebContents* parent_opener =
tabstrip_->GetOpenerOfWebContentsAt(removing_index);
// First see if the index being removed has any "child" tabs. If it does, we
// want to select the first in that child group, not the next tab in the same
// group of the removed tab.
content::WebContents* removed_contents =
tabstrip_->GetWebContentsAt(removing_index);
// The parent opener should never be the same as the controller being removed.
DCHECK(parent_opener != removed_contents);
int index = tabstrip_->GetIndexOfNextWebContentsOpenedBy(removed_contents,
removing_index,
false);
if (index != TabStripModel::kNoTab)
return GetValidIndex(index, removing_index);
if (parent_opener) {
// If the tab was in a group, shift selection to the next tab in the group.
int index = tabstrip_->GetIndexOfNextWebContentsOpenedBy(parent_opener,
removing_index,
false);
if (index != TabStripModel::kNoTab)
return GetValidIndex(index, removing_index);
// If we can't find a subsequent group member, just fall back to the
// parent_opener itself. Note that we use "group" here since opener is
// reset by select operations..
index = tabstrip_->GetIndexOfWebContents(parent_opener);
if (index != TabStripModel::kNoTab)
return GetValidIndex(index, removing_index);
}
// No opener set, fall through to the default handler...
int selected_index = tabstrip_->active_index();
if (selected_index >= (tab_count - 1))
return selected_index - 1;
return selected_index;
}
void TabStripModelOrderController::ActiveTabChanged(
content::WebContents* old_contents,
content::WebContents* new_contents,
int index,
int reason) {
content::WebContents* old_opener = NULL;
if (old_contents) {
int index = tabstrip_->GetIndexOfWebContents(old_contents);
if (index != TabStripModel::kNoTab) {
old_opener = tabstrip_->GetOpenerOfWebContentsAt(index);
// Forget any group/opener relationships that need to be reset whenever
// selection changes (see comment in TabStripModel::AddWebContentsAt).
if (tabstrip_->ShouldResetGroupOnSelect(old_contents))
tabstrip_->ForgetGroup(old_contents);
}
}
content::WebContents* new_opener = tabstrip_->GetOpenerOfWebContentsAt(index);
if ((reason & CHANGE_REASON_USER_GESTURE) && new_opener != old_opener &&
((old_contents == NULL && new_opener == NULL) ||
new_opener != old_contents) &&
((new_contents == NULL && old_opener == NULL) ||
old_opener != new_contents)) {
tabstrip_->ForgetAllOpeners();
}
}
///////////////////////////////////////////////////////////////////////////////
// TabStripModelOrderController, private:
int TabStripModelOrderController::GetValidIndex(
int index, int removing_index) const {
if (removing_index < index)
index = std::max(0, index - 1);
return index;
}
|