Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: chrome/browser/tabs/tab_strip_model.cc

Issue 10117016: Implementation for switching between recently used tabs using ctrl tilde or quoteleft. Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Added tab mru list manager class. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/tabs/tab_strip_model.h" 5 #include "chrome/browser/tabs/tab_strip_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 } 157 }
158 data->opener = &selected_contents->web_contents()->GetController(); 158 data->opener = &selected_contents->web_contents()->GetController();
159 } 159 }
160 160
161 contents_data_.insert(contents_data_.begin() + index, data); 161 contents_data_.insert(contents_data_.begin() + index, data);
162 162
163 selection_model_.IncrementFrom(index); 163 selection_model_.IncrementFrom(index);
164 164
165 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 165 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
166 TabInsertedAt(contents, index, active)); 166 TabInsertedAt(contents, index, active));
167 if (active)
168 tab_mru_list_manager_.ActivateContents(contents);
169 else
170 tab_mru_list_manager_.AppendContents(contents);
171
167 if (active) { 172 if (active) {
168 TabStripSelectionModel new_model; 173 TabStripSelectionModel new_model;
169 new_model.Copy(selection_model_); 174 new_model.Copy(selection_model_);
170 new_model.SetSelectedIndex(index); 175 new_model.SetSelectedIndex(index);
171 SetSelection(new_model, NOTIFY_DEFAULT); 176 SetSelection(new_model, NOTIFY_DEFAULT);
172 } 177 }
173 } 178 }
174 179
175 TabContentsWrapper* TabStripModel::ReplaceTabContentsAt( 180 TabContentsWrapper* TabStripModel::ReplaceTabContentsAt(
176 int index, 181 int index,
177 TabContentsWrapper* new_contents) { 182 TabContentsWrapper* new_contents) {
178 DCHECK(ContainsIndex(index)); 183 DCHECK(ContainsIndex(index));
179 TabContentsWrapper* old_contents = GetContentsAt(index); 184 TabContentsWrapper* old_contents = GetContentsAt(index);
180 185
181 ForgetOpenersAndGroupsReferencing( 186 ForgetOpenersAndGroupsReferencing(
182 &(old_contents->web_contents()->GetController())); 187 &(old_contents->web_contents()->GetController()));
183 188
184 contents_data_[index]->contents = new_contents; 189 contents_data_[index]->contents = new_contents;
185 190
186 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 191 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
187 TabReplacedAt(this, old_contents, new_contents, index)); 192 TabReplacedAt(this, old_contents, new_contents, index));
188 193
194 tab_mru_list_manager_.ReplaceContents(old_contents, new_contents);
195
189 // When the active tab contents is replaced send out selected notification 196 // When the active tab contents is replaced send out selected notification
190 // too. We do this as nearly all observers need to treat a replace of the 197 // too. We do this as nearly all observers need to treat a replace of the
191 // selected contents as selection changing. 198 // selected contents as selection changing.
192 if (active_index() == index) { 199 if (active_index() == index) {
193 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 200 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
194 ActiveTabChanged(old_contents, new_contents, 201 ActiveTabChanged(old_contents, new_contents,
195 active_index(), false)); 202 active_index(), false));
203 tab_mru_list_manager_.ActivateContents(new_contents);
196 } 204 }
197 return old_contents; 205 return old_contents;
198 } 206 }
199 207
200 void TabStripModel::ReplaceNavigationControllerAt( 208 void TabStripModel::ReplaceNavigationControllerAt(
201 int index, TabContentsWrapper* contents) { 209 int index, TabContentsWrapper* contents) {
202 // This appears to be OK with no flicker since no redraw event 210 // This appears to be OK with no flicker since no redraw event
203 // occurs between the call to add an additional tab and one to close 211 // occurs between the call to add an additional tab and one to close
204 // the previous tab. 212 // the previous tab.
205 InsertTabContentsAt(index + 1, contents, ADD_ACTIVE | ADD_INHERIT_GROUP); 213 InsertTabContentsAt(index + 1, contents, ADD_ACTIVE | ADD_INHERIT_GROUP);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 bool was_selected = IsTabSelected(index); 252 bool was_selected = IsTabSelected(index);
245 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); 253 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index);
246 delete contents_data_.at(index); 254 delete contents_data_.at(index);
247 contents_data_.erase(contents_data_.begin() + index); 255 contents_data_.erase(contents_data_.begin() + index);
248 ForgetOpenersAndGroupsReferencing( 256 ForgetOpenersAndGroupsReferencing(
249 &(removed_contents->web_contents()->GetController())); 257 &(removed_contents->web_contents()->GetController()));
250 if (empty()) 258 if (empty())
251 closing_all_ = true; 259 closing_all_ = true;
252 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 260 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
253 TabDetachedAt(removed_contents, index)); 261 TabDetachedAt(removed_contents, index));
262 tab_mru_list_manager_.RemoveContents(removed_contents);
254 if (empty()) { 263 if (empty()) {
255 selection_model_.Clear(); 264 selection_model_.Clear();
265 tab_mru_list_manager_.ClearContents();
256 // TabDetachedAt() might unregister observers, so send |TabStripEmtpy()| in 266 // TabDetachedAt() might unregister observers, so send |TabStripEmtpy()| in
257 // a second pass. 267 // a second pass.
258 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty()); 268 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty());
259 } else { 269 } else {
260 int old_active = active_index(); 270 int old_active = active_index();
261 selection_model_.DecrementFrom(index); 271 selection_model_.DecrementFrom(index);
262 TabStripSelectionModel old_model; 272 TabStripSelectionModel old_model;
263 old_model.Copy(selection_model_); 273 old_model.Copy(selection_model_);
264 if (index == old_active) { 274 if (index == old_active) {
265 NotifyIfTabDeactivated(removed_contents); 275 NotifyIfTabDeactivated(removed_contents);
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 } 760 }
751 761
752 void TabStripModel::SelectPreviousTab() { 762 void TabStripModel::SelectPreviousTab() {
753 SelectRelativeTab(false); 763 SelectRelativeTab(false);
754 } 764 }
755 765
756 void TabStripModel::SelectLastTab() { 766 void TabStripModel::SelectLastTab() {
757 ActivateTabAt(count() - 1, true); 767 ActivateTabAt(count() - 1, true);
758 } 768 }
759 769
770 void TabStripModel::SelectNextMRUTab() {
771 TabContentsWrapper* contents = tab_mru_list_manager_.GetNextMRUTab();
772 if (contents) {
773 ActivateTabAt(GetIndexOfTabContents(contents),true);
774 }
775 }
776
760 void TabStripModel::MoveTabNext() { 777 void TabStripModel::MoveTabNext() {
761 // TODO: this likely needs to be updated for multi-selection. 778 // TODO: this likely needs to be updated for multi-selection.
762 int new_index = std::min(active_index() + 1, count() - 1); 779 int new_index = std::min(active_index() + 1, count() - 1);
763 MoveTabContentsAt(active_index(), new_index, true); 780 MoveTabContentsAt(active_index(), new_index, true);
764 } 781 }
765 782
766 void TabStripModel::MoveTabPrevious() { 783 void TabStripModel::MoveTabPrevious() {
767 // TODO: this likely needs to be updated for multi-selection. 784 // TODO: this likely needs to be updated for multi-selection.
768 int new_index = std::max(active_index() - 1, 0); 785 int new_index = std::max(active_index() - 1, 0);
769 MoveTabContentsAt(active_index(), new_index, true); 786 MoveTabContentsAt(active_index(), new_index, true);
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 1218
1202 return retval; 1219 return retval;
1203 } 1220 }
1204 1221
1205 void TabStripModel::InternalCloseTab(TabContentsWrapper* contents, 1222 void TabStripModel::InternalCloseTab(TabContentsWrapper* contents,
1206 int index, 1223 int index,
1207 bool create_historical_tabs) { 1224 bool create_historical_tabs) {
1208 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1225 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1209 TabClosingAt(this, contents, index)); 1226 TabClosingAt(this, contents, index));
1210 1227
1228 tab_mru_list_manager_.RemoveContents(contents);
1229
1211 // Ask the delegate to save an entry for this tab in the historical tab 1230 // Ask the delegate to save an entry for this tab in the historical tab
1212 // database if applicable. 1231 // database if applicable.
1213 if (create_historical_tabs) 1232 if (create_historical_tabs)
1214 delegate_->CreateHistoricalTab(contents); 1233 delegate_->CreateHistoricalTab(contents);
1215 1234
1216 // Deleting the TabContentsWrapper will call back to us via 1235 // Deleting the TabContentsWrapper will call back to us via
1217 // NotificationObserver and detach it. 1236 // NotificationObserver and detach it.
1218 delete contents; 1237 delete contents;
1219 } 1238 }
1220 1239
(...skipping 12 matching lines...) Expand all
1233 1252
1234 void TabStripModel::NotifyIfActiveTabChanged( 1253 void TabStripModel::NotifyIfActiveTabChanged(
1235 TabContentsWrapper* old_contents, 1254 TabContentsWrapper* old_contents,
1236 NotifyTypes notify_types) { 1255 NotifyTypes notify_types) {
1237 TabContentsWrapper* new_contents = GetContentsAt(active_index()); 1256 TabContentsWrapper* new_contents = GetContentsAt(active_index());
1238 if (old_contents != new_contents) { 1257 if (old_contents != new_contents) {
1239 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1258 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1240 ActiveTabChanged(old_contents, new_contents, 1259 ActiveTabChanged(old_contents, new_contents,
1241 active_index(), 1260 active_index(),
1242 notify_types == NOTIFY_USER_GESTURE)); 1261 notify_types == NOTIFY_USER_GESTURE));
1262 tab_mru_list_manager_.ActivateContents(new_contents);
1243 // Activating a discarded tab reloads it, so it is no longer discarded. 1263 // Activating a discarded tab reloads it, so it is no longer discarded.
1244 contents_data_[active_index()]->discarded = false; 1264 contents_data_[active_index()]->discarded = false;
1245 } 1265 }
1246 } 1266 }
1247 1267
1248 void TabStripModel::NotifyIfActiveOrSelectionChanged( 1268 void TabStripModel::NotifyIfActiveOrSelectionChanged(
1249 TabContentsWrapper* old_contents, 1269 TabContentsWrapper* old_contents,
1250 NotifyTypes notify_types, 1270 NotifyTypes notify_types,
1251 const TabStripSelectionModel& old_model) { 1271 const TabStripSelectionModel& old_model) {
1252 NotifyIfActiveTabChanged(old_contents, notify_types); 1272 NotifyIfActiveTabChanged(old_contents, notify_types);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 void TabStripModel::ForgetOpenersAndGroupsReferencing( 1364 void TabStripModel::ForgetOpenersAndGroupsReferencing(
1345 const NavigationController* tab) { 1365 const NavigationController* tab) {
1346 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); 1366 for (TabContentsDataVector::const_iterator i = contents_data_.begin();
1347 i != contents_data_.end(); ++i) { 1367 i != contents_data_.end(); ++i) {
1348 if ((*i)->group == tab) 1368 if ((*i)->group == tab)
1349 (*i)->group = NULL; 1369 (*i)->group = NULL;
1350 if ((*i)->opener == tab) 1370 if ((*i)->opener == tab)
1351 (*i)->opener = NULL; 1371 (*i)->opener = NULL;
1352 } 1372 }
1353 } 1373 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698