OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 TabContentsWrapper* selected_contents = GetActiveTabContents(); | 135 TabContentsWrapper* selected_contents = GetActiveTabContents(); |
136 TabContentsData* data = new TabContentsData(contents); | 136 TabContentsData* data = new TabContentsData(contents); |
137 data->pinned = pin; | 137 data->pinned = pin; |
138 if ((add_types & ADD_INHERIT_GROUP) && selected_contents) { | 138 if ((add_types & ADD_INHERIT_GROUP) && selected_contents) { |
139 if (active) { | 139 if (active) { |
140 // Forget any existing relationships, we don't want to make things too | 140 // Forget any existing relationships, we don't want to make things too |
141 // confusing by having multiple groups active at the same time. | 141 // confusing by having multiple groups active at the same time. |
142 ForgetAllOpeners(); | 142 ForgetAllOpeners(); |
143 } | 143 } |
144 // Anything opened by a link we deem to have an opener. | 144 // Anything opened by a link we deem to have an opener. |
145 data->SetGroup(&selected_contents->controller()); | 145 data->SetGroup(&selected_contents->tab_contents()->controller()); |
146 } else if ((add_types & ADD_INHERIT_OPENER) && selected_contents) { | 146 } else if ((add_types & ADD_INHERIT_OPENER) && selected_contents) { |
147 if (active) { | 147 if (active) { |
148 // Forget any existing relationships, we don't want to make things too | 148 // Forget any existing relationships, we don't want to make things too |
149 // confusing by having multiple groups active at the same time. | 149 // confusing by having multiple groups active at the same time. |
150 ForgetAllOpeners(); | 150 ForgetAllOpeners(); |
151 } | 151 } |
152 data->opener = &selected_contents->controller(); | 152 data->opener = &selected_contents->tab_contents()->controller(); |
153 } | 153 } |
154 | 154 |
155 contents_data_.insert(contents_data_.begin() + index, data); | 155 contents_data_.insert(contents_data_.begin() + index, data); |
156 | 156 |
157 selection_model_.IncrementFrom(index); | 157 selection_model_.IncrementFrom(index); |
158 | 158 |
159 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 159 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
160 TabInsertedAt(contents, index, active)); | 160 TabInsertedAt(contents, index, active)); |
161 TabStripSelectionModel old_model; | 161 TabStripSelectionModel old_model; |
162 old_model.Copy(selection_model_); | 162 old_model.Copy(selection_model_); |
163 if (active) { | 163 if (active) { |
164 selection_model_.SetSelectedIndex(index); | 164 selection_model_.SetSelectedIndex(index); |
165 NotifyIfActiveOrSelectionChanged(selected_contents, false, old_model); | 165 NotifyIfActiveOrSelectionChanged(selected_contents, false, old_model); |
166 } | 166 } |
167 } | 167 } |
168 | 168 |
169 TabContentsWrapper* TabStripModel::ReplaceTabContentsAt( | 169 TabContentsWrapper* TabStripModel::ReplaceTabContentsAt( |
170 int index, | 170 int index, |
171 TabContentsWrapper* new_contents) { | 171 TabContentsWrapper* new_contents) { |
172 DCHECK(ContainsIndex(index)); | 172 DCHECK(ContainsIndex(index)); |
173 TabContentsWrapper* old_contents = GetContentsAt(index); | 173 TabContentsWrapper* old_contents = GetContentsAt(index); |
174 | 174 |
175 ForgetOpenersAndGroupsReferencing(&(old_contents->controller())); | 175 ForgetOpenersAndGroupsReferencing( |
| 176 &(old_contents->tab_contents()->controller())); |
176 | 177 |
177 contents_data_[index]->contents = new_contents; | 178 contents_data_[index]->contents = new_contents; |
178 | 179 |
179 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 180 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
180 TabReplacedAt(this, old_contents, new_contents, index)); | 181 TabReplacedAt(this, old_contents, new_contents, index)); |
181 | 182 |
182 // When the active tab contents is replaced send out selected notification | 183 // When the active tab contents is replaced send out selected notification |
183 // too. We do this as nearly all observers need to treat a replace of the | 184 // too. We do this as nearly all observers need to treat a replace of the |
184 // selected contents as selection changing. | 185 // selected contents as selection changing. |
185 if (active_index() == index) { | 186 if (active_index() == index) { |
(...skipping 18 matching lines...) Expand all Loading... |
204 TabContentsWrapper* TabStripModel::DiscardTabContentsAt(int index) { | 205 TabContentsWrapper* TabStripModel::DiscardTabContentsAt(int index) { |
205 DCHECK(ContainsIndex(index)); | 206 DCHECK(ContainsIndex(index)); |
206 TabContentsWrapper* null_contents = | 207 TabContentsWrapper* null_contents = |
207 new TabContentsWrapper( | 208 new TabContentsWrapper( |
208 new TabContents(profile(), | 209 new TabContents(profile(), |
209 NULL /* site_instance */, | 210 NULL /* site_instance */, |
210 MSG_ROUTING_NONE, | 211 MSG_ROUTING_NONE, |
211 NULL /* base_tab_contents */, | 212 NULL /* base_tab_contents */, |
212 NULL /* session_storage_namespace */)); | 213 NULL /* session_storage_namespace */)); |
213 TabContentsWrapper* old_contents = GetContentsAt(index); | 214 TabContentsWrapper* old_contents = GetContentsAt(index); |
214 NavigationEntry* old_nav_entry = old_contents->controller().GetActiveEntry(); | 215 NavigationEntry* old_nav_entry = |
| 216 old_contents->tab_contents()->controller().GetActiveEntry(); |
215 if (old_nav_entry) { | 217 if (old_nav_entry) { |
216 // Set the new tab contents to reload this URL when clicked. | 218 // Set the new tab contents to reload this URL when clicked. |
217 // This also allows the tab to keep drawing the favicon and page title. | 219 // This also allows the tab to keep drawing the favicon and page title. |
218 NavigationEntry* new_nav_entry = new NavigationEntry(*old_nav_entry); | 220 NavigationEntry* new_nav_entry = new NavigationEntry(*old_nav_entry); |
219 std::vector<NavigationEntry*> entries; | 221 std::vector<NavigationEntry*> entries; |
220 entries.push_back(new_nav_entry); | 222 entries.push_back(new_nav_entry); |
221 null_contents->controller().Restore(0, false, &entries); | 223 null_contents->tab_contents()->controller().Restore(0, false, &entries); |
222 } | 224 } |
223 ReplaceTabContentsAt(index, null_contents); | 225 ReplaceTabContentsAt(index, null_contents); |
224 // Mark the tab so it will reload when we click. | 226 // Mark the tab so it will reload when we click. |
225 contents_data_[index]->discarded = true; | 227 contents_data_[index]->discarded = true; |
226 delete old_contents; | 228 delete old_contents; |
227 return null_contents; | 229 return null_contents; |
228 } | 230 } |
229 | 231 |
230 TabContentsWrapper* TabStripModel::DetachTabContentsAt(int index) { | 232 TabContentsWrapper* TabStripModel::DetachTabContentsAt(int index) { |
231 if (contents_data_.empty()) | 233 if (contents_data_.empty()) |
232 return NULL; | 234 return NULL; |
233 | 235 |
234 DCHECK(ContainsIndex(index)); | 236 DCHECK(ContainsIndex(index)); |
235 | 237 |
236 TabContentsWrapper* removed_contents = GetContentsAt(index); | 238 TabContentsWrapper* removed_contents = GetContentsAt(index); |
237 bool was_selected = IsTabSelected(index); | 239 bool was_selected = IsTabSelected(index); |
238 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); | 240 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); |
239 delete contents_data_.at(index); | 241 delete contents_data_.at(index); |
240 contents_data_.erase(contents_data_.begin() + index); | 242 contents_data_.erase(contents_data_.begin() + index); |
241 ForgetOpenersAndGroupsReferencing(&(removed_contents->controller())); | 243 ForgetOpenersAndGroupsReferencing( |
| 244 &(removed_contents->tab_contents()->controller())); |
242 if (empty()) | 245 if (empty()) |
243 closing_all_ = true; | 246 closing_all_ = true; |
244 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 247 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
245 TabDetachedAt(removed_contents, index)); | 248 TabDetachedAt(removed_contents, index)); |
246 if (empty()) { | 249 if (empty()) { |
247 selection_model_.Clear(); | 250 selection_model_.Clear(); |
248 // TabDetachedAt() might unregister observers, so send |TabStripEmtpy()| in | 251 // TabDetachedAt() might unregister observers, so send |TabStripEmtpy()| in |
249 // a second pass. | 252 // a second pass. |
250 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty()); | 253 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty()); |
251 } else { | 254 } else { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 return index; | 380 return index; |
378 } | 381 } |
379 return kNoTab; | 382 return kNoTab; |
380 } | 383 } |
381 | 384 |
382 int TabStripModel::GetIndexOfController( | 385 int TabStripModel::GetIndexOfController( |
383 const NavigationController* controller) const { | 386 const NavigationController* controller) const { |
384 int index = 0; | 387 int index = 0; |
385 TabContentsDataVector::const_iterator iter = contents_data_.begin(); | 388 TabContentsDataVector::const_iterator iter = contents_data_.begin(); |
386 for (; iter != contents_data_.end(); ++iter, ++index) { | 389 for (; iter != contents_data_.end(); ++iter, ++index) { |
387 if (&(*iter)->contents->controller() == controller) | 390 if (&(*iter)->contents->tab_contents()->controller() == controller) |
388 return index; | 391 return index; |
389 } | 392 } |
390 return kNoTab; | 393 return kNoTab; |
391 } | 394 } |
392 | 395 |
393 void TabStripModel::UpdateTabContentsStateAt(int index, | 396 void TabStripModel::UpdateTabContentsStateAt(int index, |
394 TabStripModelObserver::TabChangeType change_type) { | 397 TabStripModelObserver::TabChangeType change_type) { |
395 DCHECK(ContainsIndex(index)); | 398 DCHECK(ContainsIndex(index)); |
396 | 399 |
397 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 400 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 delegate()->AddBlankTabAt(context_index + 1, true); | 837 delegate()->AddBlankTabAt(context_index + 1, true); |
835 break; | 838 break; |
836 | 839 |
837 case CommandReload: { | 840 case CommandReload: { |
838 UserMetrics::RecordAction(UserMetricsAction("TabContextMenu_Reload")); | 841 UserMetrics::RecordAction(UserMetricsAction("TabContextMenu_Reload")); |
839 std::vector<int> indices = GetIndicesForCommand(context_index); | 842 std::vector<int> indices = GetIndicesForCommand(context_index); |
840 for (size_t i = 0; i < indices.size(); ++i) { | 843 for (size_t i = 0; i < indices.size(); ++i) { |
841 TabContentsWrapper* tab = GetTabContentsAt(indices[i]); | 844 TabContentsWrapper* tab = GetTabContentsAt(indices[i]); |
842 if (tab && tab->tab_contents()->delegate()->CanReloadContents( | 845 if (tab && tab->tab_contents()->delegate()->CanReloadContents( |
843 tab->tab_contents())) { | 846 tab->tab_contents())) { |
844 tab->controller().Reload(true); | 847 tab->tab_contents()->controller().Reload(true); |
845 } | 848 } |
846 } | 849 } |
847 break; | 850 break; |
848 } | 851 } |
849 | 852 |
850 case CommandDuplicate: { | 853 case CommandDuplicate: { |
851 UserMetrics::RecordAction(UserMetricsAction("TabContextMenu_Duplicate")); | 854 UserMetrics::RecordAction(UserMetricsAction("TabContextMenu_Duplicate")); |
852 std::vector<int> indices = GetIndicesForCommand(context_index); | 855 std::vector<int> indices = GetIndicesForCommand(context_index); |
853 // Copy the TabContents off as the indices will change as tabs are | 856 // Copy the TabContents off as the indices will change as tabs are |
854 // duplicated. | 857 // duplicated. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 if (GetTabContentsAt(i)->tab_contents()->GetURL().host() == domain) | 1080 if (GetTabContentsAt(i)->tab_contents()->GetURL().host() == domain) |
1078 indices->push_back(i); | 1081 indices->push_back(i); |
1079 } | 1082 } |
1080 } | 1083 } |
1081 | 1084 |
1082 void TabStripModel::GetIndicesWithSameOpener(int index, | 1085 void TabStripModel::GetIndicesWithSameOpener(int index, |
1083 std::vector<int>* indices) { | 1086 std::vector<int>* indices) { |
1084 NavigationController* opener = contents_data_[index]->group; | 1087 NavigationController* opener = contents_data_[index]->group; |
1085 if (!opener) { | 1088 if (!opener) { |
1086 // If there is no group, find all tabs with the selected tab as the opener. | 1089 // If there is no group, find all tabs with the selected tab as the opener. |
1087 opener = &(GetTabContentsAt(index)->controller()); | 1090 opener = &(GetTabContentsAt(index)->tab_contents()->controller()); |
1088 if (!opener) | 1091 if (!opener) |
1089 return; | 1092 return; |
1090 } | 1093 } |
1091 for (int i = 0; i < count(); ++i) { | 1094 for (int i = 0; i < count(); ++i) { |
1092 if (i == index) | 1095 if (i == index) |
1093 continue; | 1096 continue; |
1094 if (contents_data_[i]->group == opener || | 1097 if (contents_data_[i]->group == opener || |
1095 &(GetTabContentsAt(i)->controller()) == opener) { | 1098 &(GetTabContentsAt(i)->tab_contents()->controller()) == opener) { |
1096 indices->push_back(i); | 1099 indices->push_back(i); |
1097 } | 1100 } |
1098 } | 1101 } |
1099 } | 1102 } |
1100 | 1103 |
1101 std::vector<int> TabStripModel::GetIndicesForCommand(int index) const { | 1104 std::vector<int> TabStripModel::GetIndicesForCommand(int index) const { |
1102 if (!IsTabSelected(index)) { | 1105 if (!IsTabSelected(index)) { |
1103 std::vector<int> indices; | 1106 std::vector<int> indices; |
1104 indices.push_back(index); | 1107 indices.push_back(index); |
1105 return indices; | 1108 return indices; |
1106 } | 1109 } |
1107 return selection_model_.selected_indices(); | 1110 return selection_model_.selected_indices(); |
1108 } | 1111 } |
1109 | 1112 |
1110 bool TabStripModel::IsNewTabAtEndOfTabStrip( | 1113 bool TabStripModel::IsNewTabAtEndOfTabStrip( |
1111 TabContentsWrapper* contents) const { | 1114 TabContentsWrapper* contents) const { |
1112 const GURL& url = contents->tab_contents()->GetURL(); | 1115 const GURL& url = contents->tab_contents()->GetURL(); |
1113 return url.SchemeIs(chrome::kChromeUIScheme) && | 1116 return url.SchemeIs(chrome::kChromeUIScheme) && |
1114 url.host() == chrome::kChromeUINewTabHost && | 1117 url.host() == chrome::kChromeUINewTabHost && |
1115 contents == GetContentsAt(count() - 1) && | 1118 contents == GetContentsAt(count() - 1) && |
1116 contents->controller().entry_count() == 1; | 1119 contents->tab_contents()->controller().entry_count() == 1; |
1117 } | 1120 } |
1118 | 1121 |
1119 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices, | 1122 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices, |
1120 uint32 close_types) { | 1123 uint32 close_types) { |
1121 if (in_indices.empty()) | 1124 if (in_indices.empty()) |
1122 return true; | 1125 return true; |
1123 | 1126 |
1124 std::vector<int> indices(in_indices); | 1127 std::vector<int> indices(in_indices); |
1125 bool retval = delegate_->CanCloseContents(&indices); | 1128 bool retval = delegate_->CanCloseContents(&indices); |
1126 if (indices.empty()) | 1129 if (indices.empty()) |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 void TabStripModel::ForgetOpenersAndGroupsReferencing( | 1321 void TabStripModel::ForgetOpenersAndGroupsReferencing( |
1319 const NavigationController* tab) { | 1322 const NavigationController* tab) { |
1320 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); | 1323 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); |
1321 i != contents_data_.end(); ++i) { | 1324 i != contents_data_.end(); ++i) { |
1322 if ((*i)->group == tab) | 1325 if ((*i)->group == tab) |
1323 (*i)->group = NULL; | 1326 (*i)->group = NULL; |
1324 if ((*i)->opener == tab) | 1327 if ((*i)->opener == tab) |
1325 (*i)->opener = NULL; | 1328 (*i)->opener = NULL; |
1326 } | 1329 } |
1327 } | 1330 } |
OLD | NEW |