| 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 |