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/ui/views/download/download_item_view.h" | 5 #include "chrome/browser/ui/views/download/download_item_view.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 if (sampling_event_.get()) | 234 if (sampling_event_.get()) |
235 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kIgnore); | 235 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kIgnore); |
236 } | 236 } |
237 | 237 |
238 // Progress animation handlers. | 238 // Progress animation handlers. |
239 | 239 |
240 void DownloadItemView::StartDownloadProgress() { | 240 void DownloadItemView::StartDownloadProgress() { |
241 if (progress_timer_.IsRunning()) | 241 if (progress_timer_.IsRunning()) |
242 return; | 242 return; |
243 progress_start_time_ = base::TimeTicks::Now(); | 243 progress_start_time_ = base::TimeTicks::Now(); |
244 progress_timer_.Start( | 244 progress_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
245 FROM_HERE, | 245 DownloadShelf::kProgressRateMs), |
246 base::TimeDelta::FromMilliseconds(DownloadShelf::kProgressRateMs), | 246 base::Bind(&DownloadItemView::ProgressTimerFired, |
247 base::Bind(&DownloadItemView::SchedulePaint, base::Unretained(this))); | 247 base::Unretained(this))); |
248 } | 248 } |
249 | 249 |
250 void DownloadItemView::StopDownloadProgress() { | 250 void DownloadItemView::StopDownloadProgress() { |
251 if (!progress_timer_.IsRunning()) | 251 if (!progress_timer_.IsRunning()) |
252 return; | 252 return; |
253 previous_progress_elapsed_ += base::TimeTicks::Now() - progress_start_time_; | 253 previous_progress_elapsed_ += base::TimeTicks::Now() - progress_start_time_; |
254 progress_start_time_ = base::TimeTicks(); | 254 progress_start_time_ = base::TimeTicks(); |
255 progress_timer_.Stop(); | 255 progress_timer_.Stop(); |
256 } | 256 } |
257 | 257 |
258 void DownloadItemView::OnExtractIconComplete(gfx::Image* icon_bitmap) { | 258 void DownloadItemView::OnExtractIconComplete(gfx::Image* icon_bitmap) { |
259 if (icon_bitmap) | 259 if (icon_bitmap) |
260 shelf_->SchedulePaint(); | 260 shelf_->SchedulePaint(); |
261 } | 261 } |
262 | 262 |
263 // DownloadObserver interface. | 263 // DownloadObserver interface. |
264 | 264 |
265 // Update the progress graphic on the icon and our text status label | 265 // Update the progress graphic on the icon and our text status label |
266 // to reflect our current bytes downloaded, time remaining. | 266 // to reflect our current bytes downloaded, time remaining. |
267 void DownloadItemView::OnDownloadUpdated(DownloadItem* download_item) { | 267 void DownloadItemView::OnDownloadUpdated(DownloadItem* download_item) { |
268 DCHECK_EQ(download(), download_item); | 268 DCHECK_EQ(download(), download_item); |
269 | 269 |
270 if (!model_.ShouldShowInShelf()) { | 270 if (!model_.ShouldShowInShelf()) { |
271 shelf_->RemoveDownloadView(this); // This will delete us! | 271 shelf_->RemoveDownloadView(this); // This will delete us! |
272 return; | 272 return; |
273 } | 273 } |
274 | 274 |
275 if (IsShowingWarningDialog() && !model_.IsDangerous()) { | 275 if (IsShowingWarningDialog() != model_.IsDangerous()) { |
276 // We have been approved. | 276 ToggleWarningDialog(); |
277 ClearWarningDialog(); | |
278 } else if (!IsShowingWarningDialog() && model_.IsDangerous()) { | |
279 ShowWarningDialog(); | |
280 // Force the shelf to layout again as our size has changed. | |
281 shelf_->Layout(); | |
282 SchedulePaint(); | |
283 } else { | 277 } else { |
284 base::string16 status_text = model_.GetStatusText(); | |
285 switch (download()->GetState()) { | 278 switch (download()->GetState()) { |
286 case DownloadItem::IN_PROGRESS: | 279 case DownloadItem::IN_PROGRESS: |
287 download()->IsPaused() ? | 280 download()->IsPaused() ? StopDownloadProgress() |
288 StopDownloadProgress() : StartDownloadProgress(); | 281 : StartDownloadProgress(); |
289 LoadIconIfItemPathChanged(); | 282 LoadIconIfItemPathChanged(); |
290 break; | 283 break; |
291 case DownloadItem::INTERRUPTED: | 284 case DownloadItem::INTERRUPTED: |
292 StopDownloadProgress(); | 285 StopDownloadProgress(); |
293 complete_animation_.reset(new gfx::SlideAnimation(this)); | 286 complete_animation_.reset(new gfx::SlideAnimation(this)); |
294 complete_animation_->SetSlideDuration(kInterruptedAnimationDurationMs); | 287 complete_animation_->SetSlideDuration(kInterruptedAnimationDurationMs); |
295 complete_animation_->SetTweenType(gfx::Tween::LINEAR); | 288 complete_animation_->SetTweenType(gfx::Tween::LINEAR); |
296 complete_animation_->Show(); | 289 complete_animation_->Show(); |
297 SchedulePaint(); | |
298 LoadIcon(); | 290 LoadIcon(); |
299 break; | 291 break; |
300 case DownloadItem::COMPLETE: | 292 case DownloadItem::COMPLETE: |
301 if (model_.ShouldRemoveFromShelfWhenComplete()) { | 293 if (model_.ShouldRemoveFromShelfWhenComplete()) { |
302 shelf_->RemoveDownloadView(this); // This will delete us! | 294 shelf_->RemoveDownloadView(this); // This will delete us! |
303 return; | 295 return; |
304 } | 296 } |
305 StopDownloadProgress(); | 297 StopDownloadProgress(); |
306 complete_animation_.reset(new gfx::SlideAnimation(this)); | 298 complete_animation_.reset(new gfx::SlideAnimation(this)); |
307 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); | 299 complete_animation_->SetSlideDuration(kCompleteAnimationDurationMs); |
308 complete_animation_->SetTweenType(gfx::Tween::LINEAR); | 300 complete_animation_->SetTweenType(gfx::Tween::LINEAR); |
309 complete_animation_->Show(); | 301 complete_animation_->Show(); |
310 SchedulePaint(); | |
311 LoadIcon(); | 302 LoadIcon(); |
312 break; | 303 break; |
313 case DownloadItem::CANCELLED: | 304 case DownloadItem::CANCELLED: |
314 StopDownloadProgress(); | 305 StopDownloadProgress(); |
315 if (complete_animation_) | 306 if (complete_animation_) |
316 complete_animation_->Stop(); | 307 complete_animation_->Stop(); |
317 LoadIcon(); | 308 LoadIcon(); |
318 break; | 309 break; |
319 default: | 310 default: |
320 NOTREACHED(); | 311 NOTREACHED(); |
321 } | 312 } |
322 status_text_ = status_text; | 313 status_text_ = model_.GetStatusText(); |
| 314 SchedulePaint(); |
323 } | 315 } |
324 | 316 |
325 base::string16 new_tip = model_.GetTooltipText(font_list_, kTooltipMaxWidth); | 317 base::string16 new_tip = model_.GetTooltipText(font_list_, kTooltipMaxWidth); |
326 if (new_tip != tooltip_text_) { | 318 if (new_tip != tooltip_text_) { |
327 tooltip_text_ = new_tip; | 319 tooltip_text_ = new_tip; |
328 TooltipTextChanged(); | 320 TooltipTextChanged(); |
329 } | 321 } |
330 | 322 |
331 UpdateAccessibleName(); | 323 UpdateAccessibleName(); |
332 | |
333 // We use the parent's (DownloadShelfView's) SchedulePaint, since there | |
334 // are spaces between each DownloadItemView that the parent is responsible | |
335 // for painting. | |
336 shelf_->SchedulePaint(); | |
337 } | 324 } |
338 | 325 |
339 void DownloadItemView::OnDownloadDestroyed(DownloadItem* download) { | 326 void DownloadItemView::OnDownloadDestroyed(DownloadItem* download) { |
340 shelf_->RemoveDownloadView(this); // This will delete us! | 327 shelf_->RemoveDownloadView(this); // This will delete us! |
341 } | 328 } |
342 | 329 |
343 void DownloadItemView::OnDownloadOpened(DownloadItem* download) { | 330 void DownloadItemView::OnDownloadOpened(DownloadItem* download) { |
344 disabled_while_opening_ = true; | 331 disabled_while_opening_ = true; |
345 SetEnabled(false); | 332 SetEnabled(false); |
346 base::MessageLoop::current()->task_runner()->PostDelayedTask( | 333 base::MessageLoop::current()->task_runner()->PostDelayedTask( |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 | 1117 |
1131 AnimateStateTransition(body_state_, new_body_state, | 1118 AnimateStateTransition(body_state_, new_body_state, |
1132 body_hover_animation_.get()); | 1119 body_hover_animation_.get()); |
1133 AnimateStateTransition(drop_down_state_, new_drop_state, | 1120 AnimateStateTransition(drop_down_state_, new_drop_state, |
1134 drop_hover_animation_.get()); | 1121 drop_hover_animation_.get()); |
1135 body_state_ = new_body_state; | 1122 body_state_ = new_body_state; |
1136 drop_down_state_ = new_drop_state; | 1123 drop_down_state_ = new_drop_state; |
1137 SchedulePaint(); | 1124 SchedulePaint(); |
1138 } | 1125 } |
1139 | 1126 |
| 1127 void DownloadItemView::ToggleWarningDialog() { |
| 1128 if (model_.IsDangerous()) |
| 1129 ShowWarningDialog(); |
| 1130 else |
| 1131 ClearWarningDialog(); |
| 1132 |
| 1133 UpdateDropDownButtonPosition(); |
| 1134 |
| 1135 // Force the shelf to layout again as our size has changed. |
| 1136 shelf_->Layout(); |
| 1137 shelf_->SchedulePaint(); |
| 1138 } |
| 1139 |
1140 void DownloadItemView::ClearWarningDialog() { | 1140 void DownloadItemView::ClearWarningDialog() { |
1141 DCHECK(download()->GetDangerType() == | 1141 DCHECK(download()->GetDangerType() == |
1142 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); | 1142 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); |
1143 DCHECK(mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE); | 1143 DCHECK(mode_ == DANGEROUS_MODE || mode_ == MALICIOUS_MODE); |
1144 | 1144 |
1145 mode_ = NORMAL_MODE; | 1145 mode_ = NORMAL_MODE; |
1146 body_state_ = NORMAL; | 1146 body_state_ = NORMAL; |
1147 drop_down_state_ = NORMAL; | 1147 drop_down_state_ = NORMAL; |
1148 | 1148 |
1149 // ExperienceSampling: User proceeded through the warning. | 1149 // ExperienceSampling: User proceeded through the warning. |
1150 if (sampling_event_.get()) { | 1150 if (sampling_event_.get()) { |
1151 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed); | 1151 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed); |
1152 sampling_event_.reset(NULL); | 1152 sampling_event_.reset(NULL); |
1153 } | 1153 } |
1154 // Remove the views used by the warning dialog. | 1154 // Remove the views used by the warning dialog. |
1155 if (save_button_) { | 1155 if (save_button_) { |
1156 RemoveChildView(save_button_); | 1156 RemoveChildView(save_button_); |
1157 delete save_button_; | 1157 delete save_button_; |
1158 save_button_ = NULL; | 1158 save_button_ = NULL; |
1159 } | 1159 } |
1160 RemoveChildView(discard_button_); | 1160 RemoveChildView(discard_button_); |
1161 delete discard_button_; | 1161 delete discard_button_; |
1162 discard_button_ = NULL; | 1162 discard_button_ = NULL; |
1163 RemoveChildView(dangerous_download_label_); | 1163 RemoveChildView(dangerous_download_label_); |
1164 delete dangerous_download_label_; | 1164 delete dangerous_download_label_; |
1165 dangerous_download_label_ = NULL; | 1165 dangerous_download_label_ = NULL; |
1166 dangerous_download_label_sized_ = false; | 1166 dangerous_download_label_sized_ = false; |
1167 cached_button_size_.SetSize(0,0); | 1167 cached_button_size_.SetSize(0,0); |
1168 | 1168 |
1169 // Set the accessible name back to the status and filename instead of the | |
1170 // download warning. | |
1171 UpdateAccessibleName(); | |
1172 UpdateDropDownButtonPosition(); | |
1173 | |
1174 // We need to load the icon now that the download has the real path. | 1169 // We need to load the icon now that the download has the real path. |
1175 LoadIcon(); | 1170 LoadIcon(); |
1176 | |
1177 // Force the shelf to layout again as our size has changed. | |
1178 shelf_->Layout(); | |
1179 shelf_->SchedulePaint(); | |
1180 | |
1181 TooltipTextChanged(); | |
1182 } | 1171 } |
1183 | 1172 |
1184 void DownloadItemView::ShowWarningDialog() { | 1173 void DownloadItemView::ShowWarningDialog() { |
1185 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); | 1174 DCHECK(mode_ != DANGEROUS_MODE && mode_ != MALICIOUS_MODE); |
1186 time_download_warning_shown_ = base::Time::Now(); | 1175 time_download_warning_shown_ = base::Time::Now(); |
1187 content::DownloadDangerType danger_type = download()->GetDangerType(); | 1176 content::DownloadDangerType danger_type = download()->GetDangerType(); |
1188 RecordDangerousDownloadWarningShown(danger_type); | 1177 RecordDangerousDownloadWarningShown(danger_type); |
1189 #if defined(FULL_SAFE_BROWSING) | 1178 #if defined(FULL_SAFE_BROWSING) |
1190 if (model_.ShouldAllowDownloadFeedback()) { | 1179 if (model_.ShouldAllowDownloadFeedback()) { |
1191 safe_browsing::DownloadFeedbackService::RecordEligibleDownloadShown( | 1180 safe_browsing::DownloadFeedbackService::RecordEligibleDownloadShown( |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 warning_icon_ = rb.GetImageSkiaNamed(IDR_WARNING); | 1230 warning_icon_ = rb.GetImageSkiaNamed(IDR_WARNING); |
1242 } | 1231 } |
1243 base::string16 dangerous_label = | 1232 base::string16 dangerous_label = |
1244 model_.GetWarningText(font_list_, kTextWidth); | 1233 model_.GetWarningText(font_list_, kTextWidth); |
1245 dangerous_download_label_ = new views::Label(dangerous_label); | 1234 dangerous_download_label_ = new views::Label(dangerous_label); |
1246 dangerous_download_label_->SetMultiLine(true); | 1235 dangerous_download_label_->SetMultiLine(true); |
1247 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 1236 dangerous_download_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
1248 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); | 1237 dangerous_download_label_->SetAutoColorReadabilityEnabled(false); |
1249 AddChildView(dangerous_download_label_); | 1238 AddChildView(dangerous_download_label_); |
1250 SizeLabelToMinWidth(); | 1239 SizeLabelToMinWidth(); |
1251 UpdateDropDownButtonPosition(); | |
1252 TooltipTextChanged(); | |
1253 } | 1240 } |
1254 | 1241 |
1255 gfx::Size DownloadItemView::GetButtonSize() const { | 1242 gfx::Size DownloadItemView::GetButtonSize() const { |
1256 DCHECK(discard_button_ && (mode_ == MALICIOUS_MODE || save_button_)); | 1243 DCHECK(discard_button_ && (mode_ == MALICIOUS_MODE || save_button_)); |
1257 gfx::Size size; | 1244 gfx::Size size; |
1258 | 1245 |
1259 // We cache the size when successfully retrieved, not for performance reasons | 1246 // We cache the size when successfully retrieved, not for performance reasons |
1260 // but because if this DownloadItemView is being animated while the tab is | 1247 // but because if this DownloadItemView is being animated while the tab is |
1261 // not showing, the native buttons are not parented and their preferred size | 1248 // not showing, the native buttons are not parented and their preferred size |
1262 // is 0, messing-up the layout. | 1249 // is 0, messing-up the layout. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 void DownloadItemView::AnimateStateTransition(State from, State to, | 1378 void DownloadItemView::AnimateStateTransition(State from, State to, |
1392 gfx::SlideAnimation* animation) { | 1379 gfx::SlideAnimation* animation) { |
1393 if (from == NORMAL && to == HOT) { | 1380 if (from == NORMAL && to == HOT) { |
1394 animation->Show(); | 1381 animation->Show(); |
1395 } else if (from == HOT && to == NORMAL) { | 1382 } else if (from == HOT && to == NORMAL) { |
1396 animation->Hide(); | 1383 animation->Hide(); |
1397 } else if (from != to) { | 1384 } else if (from != to) { |
1398 animation->Reset((to == HOT) ? 1.0 : 0.0); | 1385 animation->Reset((to == HOT) ? 1.0 : 0.0); |
1399 } | 1386 } |
1400 } | 1387 } |
| 1388 |
| 1389 void DownloadItemView::ProgressTimerFired() { |
| 1390 // Only repaint for the indeterminate size case. Otherwise, we'll repaint only |
| 1391 // when there's an update notified via OnDownloadUpdated(). |
| 1392 if (model_.PercentComplete() < 0) |
| 1393 SchedulePaint(); |
| 1394 } |
OLD | NEW |