OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/views/tabs/browser_tab_strip_controller.h" | 5 #include "chrome/browser/views/tabs/browser_tab_strip_controller.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "chrome/browser/profile.h" | 9 #include "chrome/browser/profile.h" |
10 #include "chrome/browser/metrics/user_metrics.h" | 10 #include "chrome/browser/metrics/user_metrics.h" |
11 #include "chrome/browser/renderer_host/render_view_host.h" | 11 #include "chrome/browser/renderer_host/render_view_host.h" |
12 #include "chrome/browser/tab_contents/tab_contents.h" | 12 #include "chrome/browser/tab_contents/tab_contents.h" |
| 13 #include "chrome/browser/tab_contents_wrapper.h" |
13 #include "chrome/browser/tab_menu_model.h" | 14 #include "chrome/browser/tab_menu_model.h" |
14 #include "chrome/browser/tabs/tab_strip_model.h" | 15 #include "chrome/browser/tabs/tab_strip_model.h" |
15 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/views/tabs/base_tab_strip.h" | 17 #include "chrome/browser/views/tabs/base_tab_strip.h" |
17 #include "chrome/browser/views/tabs/tab_renderer_data.h" | 18 #include "chrome/browser/views/tabs/tab_renderer_data.h" |
18 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
19 #include "chrome/common/notification_service.h" | 20 #include "chrome/common/notification_service.h" |
20 #include "chrome/common/url_constants.h" | 21 #include "chrome/common/url_constants.h" |
21 #include "views/controls/menu/menu_2.h" | 22 #include "views/controls/menu/menu_2.h" |
22 #include "views/widget/widget.h" | 23 #include "views/widget/widget.h" |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 return model_->ContainsIndex(model_index) && model_->IsTabPinned(model_index); | 193 return model_->ContainsIndex(model_index) && model_->IsTabPinned(model_index); |
193 } | 194 } |
194 | 195 |
195 bool BrowserTabStripController::IsTabCloseable(int model_index) const { | 196 bool BrowserTabStripController::IsTabCloseable(int model_index) const { |
196 return !model_->ContainsIndex(model_index) || | 197 return !model_->ContainsIndex(model_index) || |
197 model_->delegate()->CanCloseTab(); | 198 model_->delegate()->CanCloseTab(); |
198 } | 199 } |
199 | 200 |
200 bool BrowserTabStripController::IsNewTabPage(int model_index) const { | 201 bool BrowserTabStripController::IsNewTabPage(int model_index) const { |
201 return model_->ContainsIndex(model_index) && | 202 return model_->ContainsIndex(model_index) && |
202 model_->GetTabContentsAt(model_index)->GetURL() == | 203 model_->GetTabContentsAt(model_index)->tab_contents()->GetURL() == |
203 GURL(chrome::kChromeUINewTabURL); | 204 GURL(chrome::kChromeUINewTabURL); |
204 } | 205 } |
205 | 206 |
206 void BrowserTabStripController::SelectTab(int model_index) { | 207 void BrowserTabStripController::SelectTab(int model_index) { |
207 model_->SelectTabContentsAt(model_index, true); | 208 model_->SelectTabContentsAt(model_index, true); |
208 } | 209 } |
209 | 210 |
210 void BrowserTabStripController::CloseTab(int model_index) { | 211 void BrowserTabStripController::CloseTab(int model_index) { |
211 tabstrip_->PrepareForCloseAt(model_index); | 212 tabstrip_->PrepareForCloseAt(model_index); |
212 model_->CloseTabContentsAt(model_index, | 213 model_->CloseTabContentsAt(model_index, |
213 TabStripModel::CLOSE_USER_GESTURE | | 214 TabStripModel::CLOSE_USER_GESTURE | |
214 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); | 215 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); |
215 } | 216 } |
216 | 217 |
217 void BrowserTabStripController::ShowContextMenu(BaseTab* tab, | 218 void BrowserTabStripController::ShowContextMenu(BaseTab* tab, |
218 const gfx::Point& p) { | 219 const gfx::Point& p) { |
219 context_menu_contents_.reset(new TabContextMenuContents(tab, this)); | 220 context_menu_contents_.reset(new TabContextMenuContents(tab, this)); |
220 context_menu_contents_->RunMenuAt(p); | 221 context_menu_contents_->RunMenuAt(p); |
221 } | 222 } |
222 | 223 |
223 void BrowserTabStripController::UpdateLoadingAnimations() { | 224 void BrowserTabStripController::UpdateLoadingAnimations() { |
224 // Don't use the model count here as it's possible for this to be invoked | 225 // Don't use the model count here as it's possible for this to be invoked |
225 // before we've applied an update from the model (Browser::TabInsertedAt may | 226 // before we've applied an update from the model (Browser::TabInsertedAt may |
226 // be processed before us and invokes this). | 227 // be processed before us and invokes this). |
227 for (int tab_index = 0, tab_count = tabstrip_->tab_count(); | 228 for (int tab_index = 0, tab_count = tabstrip_->tab_count(); |
228 tab_index < tab_count; ++tab_index) { | 229 tab_index < tab_count; ++tab_index) { |
229 BaseTab* tab = tabstrip_->base_tab_at_tab_index(tab_index); | 230 BaseTab* tab = tabstrip_->base_tab_at_tab_index(tab_index); |
230 int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); | 231 int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); |
231 if (model_->ContainsIndex(model_index)) { | 232 if (model_->ContainsIndex(model_index)) { |
232 TabContents* contents = model_->GetTabContentsAt(model_index); | 233 TabContentsWrapper* contents = model_->GetTabContentsAt(model_index); |
233 tab->UpdateLoadingAnimation(TabContentsNetworkState(contents)); | 234 tab->UpdateLoadingAnimation( |
| 235 TabContentsNetworkState(contents->tab_contents())); |
234 } | 236 } |
235 } | 237 } |
236 } | 238 } |
237 | 239 |
238 int BrowserTabStripController::HasAvailableDragActions() const { | 240 int BrowserTabStripController::HasAvailableDragActions() const { |
239 return model_->delegate()->GetDragActions(); | 241 return model_->delegate()->GetDragActions(); |
240 } | 242 } |
241 | 243 |
242 void BrowserTabStripController::PerformDrop(bool drop_before, | 244 void BrowserTabStripController::PerformDrop(bool drop_before, |
243 int index, | 245 int index, |
244 const GURL& url) { | 246 const GURL& url) { |
245 if (drop_before) { | 247 if (drop_before) { |
246 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs"), | 248 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs"), |
247 model_->profile()); | 249 model_->profile()); |
248 | 250 |
249 // Insert a new tab. | 251 // Insert a new tab. |
250 TabContents* contents = model_->delegate()->CreateTabContentsForURL( | 252 TabContentsWrapper* contents = model_->delegate()->CreateTabContentsForURL( |
251 url, GURL(), model_->profile(), PageTransition::TYPED, false, NULL); | 253 url, GURL(), model_->profile(), PageTransition::TYPED, false, NULL); |
252 model_->AddTabContents(contents, index, PageTransition::GENERATED, | 254 model_->AddTabContents(contents, index, PageTransition::GENERATED, |
253 TabStripModel::ADD_SELECTED); | 255 TabStripModel::ADD_SELECTED); |
254 } else { | 256 } else { |
255 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), | 257 UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"), |
256 model_->profile()); | 258 model_->profile()); |
257 | 259 |
258 model_->GetTabContentsAt(index)->controller().LoadURL( | 260 model_->GetTabContentsAt(index)->controller().LoadURL( |
259 url, GURL(), PageTransition::GENERATED); | 261 url, GURL(), PageTransition::GENERATED); |
260 model_->SelectTabContentsAt(index, true); | 262 model_->SelectTabContentsAt(index, true); |
261 } | 263 } |
262 } | 264 } |
263 | 265 |
264 bool BrowserTabStripController::IsCompatibleWith(BaseTabStrip* other) const { | 266 bool BrowserTabStripController::IsCompatibleWith(BaseTabStrip* other) const { |
265 Profile* other_profile = | 267 Profile* other_profile = |
266 static_cast<BrowserTabStripController*>(other->controller())->profile(); | 268 static_cast<BrowserTabStripController*>(other->controller())->profile(); |
267 return other_profile == profile(); | 269 return other_profile == profile(); |
268 } | 270 } |
269 | 271 |
270 void BrowserTabStripController::CreateNewTab() { | 272 void BrowserTabStripController::CreateNewTab() { |
271 UserMetrics::RecordAction(UserMetricsAction("NewTab_Button"), | 273 UserMetrics::RecordAction(UserMetricsAction("NewTab_Button"), |
272 model_->profile()); | 274 model_->profile()); |
273 | 275 |
274 model_->delegate()->AddBlankTab(true); | 276 model_->delegate()->AddBlankTab(true); |
275 } | 277 } |
276 | 278 |
277 //////////////////////////////////////////////////////////////////////////////// | 279 //////////////////////////////////////////////////////////////////////////////// |
278 // BrowserTabStripController, TabStripModelObserver implementation: | 280 // BrowserTabStripController, TabStripModelObserver implementation: |
279 | 281 |
280 void BrowserTabStripController::TabInsertedAt(TabContents* contents, | 282 void BrowserTabStripController::TabInsertedAt(TabContentsWrapper* contents, |
281 int model_index, | 283 int model_index, |
282 bool foreground) { | 284 bool foreground) { |
283 DCHECK(contents); | 285 DCHECK(contents); |
284 DCHECK(model_index == TabStripModel::kNoTab || | 286 DCHECK(model_index == TabStripModel::kNoTab || |
285 model_->ContainsIndex(model_index)); | 287 model_->ContainsIndex(model_index)); |
286 // This tab may be attached to another browser window, we should notify | 288 // This tab may be attached to another browser window, we should notify |
287 // renderer. | 289 // renderer. |
288 contents->render_view_host()->UpdateBrowserWindowId( | 290 contents->render_view_host()->UpdateBrowserWindowId( |
289 contents->controller().window_id().id()); | 291 contents->controller().window_id().id()); |
290 | 292 |
291 TabRendererData data; | 293 TabRendererData data; |
292 SetTabRendererDataFromModel(contents, model_index, &data); | 294 SetTabRendererDataFromModel(contents->tab_contents(), model_index, &data); |
293 tabstrip_->AddTabAt(model_index, foreground, data); | 295 tabstrip_->AddTabAt(model_index, foreground, data); |
294 } | 296 } |
295 | 297 |
296 void BrowserTabStripController::TabDetachedAt(TabContents* contents, | 298 void BrowserTabStripController::TabDetachedAt(TabContentsWrapper* contents, |
297 int model_index) { | 299 int model_index) { |
298 tabstrip_->RemoveTabAt(model_index); | 300 tabstrip_->RemoveTabAt(model_index); |
299 } | 301 } |
300 | 302 |
301 void BrowserTabStripController::TabSelectedAt(TabContents* old_contents, | 303 void BrowserTabStripController::TabSelectedAt(TabContentsWrapper* old_contents, |
302 TabContents* contents, | 304 TabContentsWrapper* contents, |
303 int model_index, | 305 int model_index, |
304 bool user_gesture) { | 306 bool user_gesture) { |
305 tabstrip_->SelectTabAt(model_->GetIndexOfTabContents(old_contents), | 307 tabstrip_->SelectTabAt(model_->GetIndexOfTabContents(old_contents), |
306 model_index); | 308 model_index); |
307 } | 309 } |
308 | 310 |
309 void BrowserTabStripController::TabMoved(TabContents* contents, | 311 void BrowserTabStripController::TabMoved(TabContentsWrapper* contents, |
310 int from_model_index, | 312 int from_model_index, |
311 int to_model_index) { | 313 int to_model_index) { |
312 // Update the data first as the pinned state may have changed. | 314 // Update the data first as the pinned state may have changed. |
313 TabRendererData data; | 315 TabRendererData data; |
314 SetTabRendererDataFromModel(contents, to_model_index, &data); | 316 SetTabRendererDataFromModel(contents->tab_contents(), to_model_index, &data); |
315 tabstrip_->SetTabData(from_model_index, data); | 317 tabstrip_->SetTabData(from_model_index, data); |
316 | 318 |
317 tabstrip_->MoveTab(from_model_index, to_model_index); | 319 tabstrip_->MoveTab(from_model_index, to_model_index); |
318 } | 320 } |
319 | 321 |
320 void BrowserTabStripController::TabChangedAt(TabContents* contents, | 322 void BrowserTabStripController::TabChangedAt(TabContentsWrapper* contents, |
321 int model_index, | 323 int model_index, |
322 TabChangeType change_type) { | 324 TabChangeType change_type) { |
323 if (change_type == TITLE_NOT_LOADING) { | 325 if (change_type == TITLE_NOT_LOADING) { |
324 tabstrip_->TabTitleChangedNotLoading(model_index); | 326 tabstrip_->TabTitleChangedNotLoading(model_index); |
325 // We'll receive another notification of the change asynchronously. | 327 // We'll receive another notification of the change asynchronously. |
326 return; | 328 return; |
327 } | 329 } |
328 | 330 |
329 SetTabDataAt(contents, model_index); | 331 SetTabDataAt(contents, model_index); |
330 } | 332 } |
331 | 333 |
332 void BrowserTabStripController::TabReplacedAt(TabContents* old_contents, | 334 void BrowserTabStripController::TabReplacedAt(TabContentsWrapper* old_contents, |
333 TabContents* new_contents, | 335 TabContentsWrapper* new_contents, |
334 int model_index) { | 336 int model_index) { |
335 SetTabDataAt(new_contents, model_index); | 337 SetTabDataAt(new_contents, model_index); |
336 } | 338 } |
337 | 339 |
338 void BrowserTabStripController::TabPinnedStateChanged(TabContents* contents, | 340 void BrowserTabStripController::TabPinnedStateChanged( |
339 int model_index) { | 341 TabContentsWrapper* contents, |
| 342 int model_index) { |
340 // Currently none of the renderers render pinned state differently. | 343 // Currently none of the renderers render pinned state differently. |
341 } | 344 } |
342 | 345 |
343 void BrowserTabStripController::TabMiniStateChanged( | 346 void BrowserTabStripController::TabMiniStateChanged( |
344 TabContents* contents, | 347 TabContentsWrapper* contents, |
345 int model_index) { | 348 int model_index) { |
346 SetTabDataAt(contents, model_index); | 349 SetTabDataAt(contents, model_index); |
347 } | 350 } |
348 | 351 |
349 void BrowserTabStripController::TabBlockedStateChanged(TabContents* contents, | 352 void BrowserTabStripController::TabBlockedStateChanged( |
350 int model_index) { | 353 TabContentsWrapper* contents, |
| 354 int model_index) { |
351 SetTabDataAt(contents, model_index); | 355 SetTabDataAt(contents, model_index); |
352 } | 356 } |
353 | 357 |
354 void BrowserTabStripController::SetTabDataAt(TabContents* contents, | 358 void BrowserTabStripController::SetTabDataAt( |
355 int model_index) { | 359 TabContentsWrapper* contents, |
| 360 int model_index) { |
356 TabRendererData data; | 361 TabRendererData data; |
357 SetTabRendererDataFromModel(contents, model_index, &data); | 362 SetTabRendererDataFromModel(contents->tab_contents(), model_index, &data); |
358 tabstrip_->SetTabData(model_index, data); | 363 tabstrip_->SetTabData(model_index, data); |
359 } | 364 } |
360 | 365 |
361 void BrowserTabStripController::SetTabRendererDataFromModel( | 366 void BrowserTabStripController::SetTabRendererDataFromModel( |
362 TabContents* contents, | 367 TabContents* contents, |
363 int model_index, | 368 int model_index, |
364 TabRendererData* data) { | 369 TabRendererData* data) { |
365 SkBitmap* app_icon = NULL; | 370 SkBitmap* app_icon = NULL; |
366 | 371 |
367 // Extension App icons are slightly larger than favicons, so only allow | 372 // Extension App icons are slightly larger than favicons, so only allow |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 DCHECK(type.value == NotificationType::TAB_CLOSEABLE_STATE_CHANGED); | 424 DCHECK(type.value == NotificationType::TAB_CLOSEABLE_STATE_CHANGED); |
420 // Note that this notification may be fired during a model mutation and | 425 // Note that this notification may be fired during a model mutation and |
421 // possibly before the tabstrip has processed the change. | 426 // possibly before the tabstrip has processed the change. |
422 // Here, we just re-layout each existing tab to reflect the change in its | 427 // Here, we just re-layout each existing tab to reflect the change in its |
423 // closeable state, and then schedule paint for entire tabstrip. | 428 // closeable state, and then schedule paint for entire tabstrip. |
424 for (int i = 0; i < tabstrip_->tab_count(); ++i) { | 429 for (int i = 0; i < tabstrip_->tab_count(); ++i) { |
425 tabstrip_->base_tab_at_tab_index(i)->Layout(); | 430 tabstrip_->base_tab_at_tab_index(i)->Layout(); |
426 } | 431 } |
427 tabstrip_->SchedulePaint(); | 432 tabstrip_->SchedulePaint(); |
428 } | 433 } |
OLD | NEW |