OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |