Chromium Code Reviews| 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/download/download_item_model.h" | 5 #include "chrome/browser/download/download_item_model.h" |
| 6 | 6 |
| 7 #include "base/i18n/number_formatting.h" | 7 #include "base/i18n/number_formatting.h" |
| 8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
| 9 #include "base/string16.h" | 9 #include "base/string16.h" |
| 10 #include "base/supports_user_data.h" | |
| 10 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 12 #include "base/time.h" | |
| 11 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 12 #include "base/time.h" | |
| 13 #include "chrome/browser/download/download_crx_util.h" | 14 #include "chrome/browser/download/download_crx_util.h" |
| 14 #include "chrome/common/time_format.h" | 15 #include "chrome/common/time_format.h" |
| 15 #include "content/public/browser/download_danger_type.h" | 16 #include "content/public/browser/download_danger_type.h" |
| 16 #include "content/public/browser/download_interrupt_reasons.h" | 17 #include "content/public/browser/download_interrupt_reasons.h" |
| 17 #include "content/public/browser/download_item.h" | 18 #include "content/public/browser/download_item.h" |
| 18 #include "grit/chromium_strings.h" | 19 #include "grit/chromium_strings.h" |
| 19 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 21 #include "ui/base/text/bytes_formatting.h" | 22 #include "ui/base/text/bytes_formatting.h" |
| 22 #include "ui/base/text/text_elider.h" | 23 #include "ui/base/text/text_elider.h" |
| 23 | 24 |
| 24 using base::TimeDelta; | 25 using base::TimeDelta; |
| 25 using content::DownloadItem; | 26 using content::DownloadItem; |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| 30 // Per DownloadItem data used by DownloadItemModel. The model doesn't keep any | |
| 31 // state since there could be multiple models associated with a single | |
| 32 // DownloadItem, and the lifetime of the model is shorter than the DownloadItem. | |
| 33 class DownloadItemModelData : public base::SupportsUserData::Data { | |
| 34 public: | |
| 35 // Get the DownloadItemModelData object for |download|. Returns NULL if | |
| 36 // there's no model data. | |
| 37 static const DownloadItemModelData* Get(const DownloadItem* download); | |
| 38 | |
| 39 // Get the DownloadItemModelData object for |download|. Creates a model data | |
| 40 // object if not found. Always returns a non-NULL pointer, unless OOM. | |
| 41 static DownloadItemModelData* GetOrCreate(DownloadItem* download); | |
| 42 | |
| 43 bool should_show_in_shelf() const { return should_show_in_shelf_; } | |
| 44 void set_should_show_in_shelf(bool should_show_in_shelf) { | |
| 45 should_show_in_shelf_ = should_show_in_shelf; | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 DownloadItemModelData(); | |
| 50 virtual ~DownloadItemModelData() {} | |
| 51 | |
| 52 static const char kKey[]; | |
| 53 | |
| 54 // Whether the download should be displayed in the download shelf. True by | |
| 55 // default. | |
| 56 bool should_show_in_shelf_; | |
| 57 }; | |
| 58 | |
| 59 // static | |
| 60 const char DownloadItemModelData::kKey[] = "DownloadItemModelData key"; | |
| 61 | |
| 62 // static | |
| 63 const DownloadItemModelData* DownloadItemModelData::Get( | |
| 64 const DownloadItem* download) { | |
| 65 return static_cast<const DownloadItemModelData*>(download->GetUserData(kKey)); | |
| 66 } | |
| 67 | |
| 68 // static | |
| 69 DownloadItemModelData* DownloadItemModelData::GetOrCreate( | |
| 70 DownloadItem* download) { | |
| 71 DownloadItemModelData* data = | |
| 72 static_cast<DownloadItemModelData*>(download->GetUserData(kKey)); | |
| 73 if (data == NULL) { | |
| 74 data = new DownloadItemModelData(); | |
| 75 download->SetUserData(kKey, data); | |
| 76 } | |
| 77 return data; | |
| 78 } | |
| 79 | |
| 80 DownloadItemModelData::DownloadItemModelData() | |
| 81 : should_show_in_shelf_(true) { | |
| 82 } | |
| 83 | |
| 29 string16 InterruptReasonStatusMessage(int reason) { | 84 string16 InterruptReasonStatusMessage(int reason) { |
| 30 int string_id = 0; | 85 int string_id = 0; |
| 31 | 86 |
| 32 switch (reason) { | 87 switch (reason) { |
| 33 case content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED: | 88 case content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED: |
| 34 string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_ACCESS_DENIED; | 89 string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_ACCESS_DENIED; |
| 35 break; | 90 break; |
| 36 case content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE: | 91 case content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE: |
| 37 string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_DISK_FULL; | 92 string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_DISK_FULL; |
| 38 break; | 93 break; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 : download_(download) { | 215 : download_(download) { |
| 161 } | 216 } |
| 162 | 217 |
| 163 DownloadItemModel::~DownloadItemModel() { | 218 DownloadItemModel::~DownloadItemModel() { |
| 164 } | 219 } |
| 165 | 220 |
| 166 void DownloadItemModel::CancelTask() { | 221 void DownloadItemModel::CancelTask() { |
| 167 download_->Cancel(true /* update history service */); | 222 download_->Cancel(true /* update history service */); |
| 168 } | 223 } |
| 169 | 224 |
| 225 string16 DownloadItemModel::GetInterruptReasonText() const { | |
| 226 if (download_->GetState() != DownloadItem::INTERRUPTED || | |
| 227 download_->GetLastReason() == | |
| 228 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED) { | |
| 229 return string16(); | |
| 230 } | |
| 231 return InterruptReasonMessage(download_->GetLastReason()); | |
| 232 } | |
| 233 | |
| 170 string16 DownloadItemModel::GetStatusText() const { | 234 string16 DownloadItemModel::GetStatusText() const { |
| 171 string16 status_text; | 235 string16 status_text; |
| 172 switch (download_->GetState()) { | 236 switch (download_->GetState()) { |
| 173 case DownloadItem::IN_PROGRESS: | 237 case DownloadItem::IN_PROGRESS: |
| 174 status_text = GetInProgressStatusString(); | 238 status_text = GetInProgressStatusString(); |
| 175 break; | 239 break; |
| 176 case DownloadItem::COMPLETE: | 240 case DownloadItem::COMPLETE: |
| 177 if (download_->GetFileExternallyRemoved()) { | 241 if (download_->GetFileExternallyRemoved()) { |
| 178 status_text = l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED); | 242 status_text = l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED); |
| 179 } else { | 243 } else { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 196 } | 260 } |
| 197 break; | 261 break; |
| 198 } | 262 } |
| 199 default: | 263 default: |
| 200 NOTREACHED(); | 264 NOTREACHED(); |
| 201 } | 265 } |
| 202 | 266 |
| 203 return status_text; | 267 return status_text; |
| 204 } | 268 } |
| 205 | 269 |
| 206 string16 DownloadItemModel::GetInterruptReasonText() const { | |
| 207 if (download_->GetState() != DownloadItem::INTERRUPTED || | |
| 208 download_->GetLastReason() == | |
| 209 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED) { | |
| 210 return string16(); | |
| 211 } | |
| 212 return InterruptReasonMessage(download_->GetLastReason()); | |
| 213 } | |
| 214 | |
| 215 string16 DownloadItemModel::GetTooltipText(const gfx::Font& font, | 270 string16 DownloadItemModel::GetTooltipText(const gfx::Font& font, |
| 216 int max_width) const { | 271 int max_width) const { |
| 217 string16 tooltip = ui::ElideFilename( | 272 string16 tooltip = ui::ElideFilename( |
| 218 download_->GetFileNameToReportUser(), font, max_width); | 273 download_->GetFileNameToReportUser(), font, max_width); |
| 219 content::DownloadInterruptReason reason = download_->GetLastReason(); | 274 content::DownloadInterruptReason reason = download_->GetLastReason(); |
| 220 if (download_->GetState() == DownloadItem::INTERRUPTED && | 275 if (download_->GetState() == DownloadItem::INTERRUPTED && |
| 221 reason != content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED) { | 276 reason != content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED) { |
| 222 tooltip += ASCIIToUTF16("\n"); | 277 tooltip += ASCIIToUTF16("\n"); |
| 223 tooltip += ui::ElideText(InterruptReasonStatusMessage(reason), | 278 tooltip += ui::ElideText(InterruptReasonStatusMessage(reason), |
| 224 font, max_width, ui::ELIDE_AT_END); | 279 font, max_width, ui::ELIDE_AT_END); |
| 225 } | 280 } |
| 226 return tooltip; | 281 return tooltip; |
| 227 } | 282 } |
| 228 | 283 |
| 229 // TODO(asanka,rdsmith): Once 'open' moves exclusively to the | |
| 230 // ChromeDownloadManagerDelegate, we should calculate the percentage here | |
| 231 // instead of calling into the DownloadItem. | |
| 232 int DownloadItemModel::PercentComplete() const { | |
| 233 return download_->PercentComplete(); | |
| 234 } | |
| 235 | |
| 236 string16 DownloadItemModel::GetWarningText(const gfx::Font& font, | 284 string16 DownloadItemModel::GetWarningText(const gfx::Font& font, |
| 237 int base_width) const { | 285 int base_width) const { |
| 238 // Should only be called if IsDangerous(). | 286 // Should only be called if IsDangerous(). |
| 239 DCHECK(IsDangerous()); | 287 DCHECK(IsDangerous()); |
| 240 switch (download_->GetDangerType()) { | 288 switch (download_->GetDangerType()) { |
| 241 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 289 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
| 242 return l10n_util::GetStringUTF16(IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); | 290 return l10n_util::GetStringUTF16(IDS_PROMPT_MALICIOUS_DOWNLOAD_URL); |
| 243 | 291 |
| 244 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 292 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
| 245 if (download_crx_util::IsExtensionDownload(*download_)) { | 293 if (download_crx_util::IsExtensionDownload(*download_)) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 DCHECK(IsDangerous()); | 325 DCHECK(IsDangerous()); |
| 278 if (download_->GetDangerType() == | 326 if (download_->GetDangerType() == |
| 279 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE && | 327 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE && |
| 280 download_crx_util::IsExtensionDownload(*download_)) { | 328 download_crx_util::IsExtensionDownload(*download_)) { |
| 281 return l10n_util::GetStringUTF16(IDS_CONTINUE_EXTENSION_DOWNLOAD); | 329 return l10n_util::GetStringUTF16(IDS_CONTINUE_EXTENSION_DOWNLOAD); |
| 282 } else { | 330 } else { |
| 283 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD); | 331 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD); |
| 284 } | 332 } |
| 285 } | 333 } |
| 286 | 334 |
| 335 int64 DownloadItemModel::GetCompletedBytes() const { | |
| 336 return download_->GetReceivedBytes(); | |
| 337 } | |
| 338 | |
| 339 int64 DownloadItemModel::GetTotalBytes() const { | |
| 340 return download_->AllDataSaved() ? download_->GetReceivedBytes() : | |
| 341 download_->GetTotalBytes(); | |
| 342 } | |
| 343 | |
| 344 // TODO(asanka,rdsmith): Once 'open' moves exclusively to the | |
| 345 // ChromeDownloadManagerDelegate, we should calculate the percentage here | |
| 346 // instead of calling into the DownloadItem. | |
|
Randy Smith (Not in Mondays)
2012/12/08 19:37:16
Despite the fact that this is just copied, the ind
asanka
2012/12/10 16:30:36
I originally added the +4 indent here because the
| |
| 347 int DownloadItemModel::PercentComplete() const { | |
| 348 return download_->PercentComplete(); | |
| 349 } | |
| 350 | |
| 351 bool DownloadItemModel::IsDangerous() const { | |
| 352 return download_->GetSafetyState() == DownloadItem::DANGEROUS; | |
| 353 } | |
| 354 | |
| 287 bool DownloadItemModel::IsMalicious() const { | 355 bool DownloadItemModel::IsMalicious() const { |
| 288 if (!IsDangerous()) | 356 if (!IsDangerous()) |
| 289 return false; | 357 return false; |
| 290 switch (download_->GetDangerType()) { | 358 switch (download_->GetDangerType()) { |
| 291 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: | 359 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: |
| 292 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: | 360 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: |
| 293 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: | 361 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: |
| 294 return true; | 362 return true; |
| 295 | 363 |
| 296 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: | 364 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS: |
| 297 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: | 365 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT: |
| 298 case content::DOWNLOAD_DANGER_TYPE_MAX: | 366 case content::DOWNLOAD_DANGER_TYPE_MAX: |
| 299 // We shouldn't get any of these due to the IsDangerous() test above. | 367 // We shouldn't get any of these due to the IsDangerous() test above. |
| 300 NOTREACHED(); | 368 NOTREACHED(); |
| 301 // Fallthrough. | 369 // Fallthrough. |
| 302 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: | 370 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: |
| 303 return false; | 371 return false; |
| 304 } | 372 } |
| 305 NOTREACHED(); | 373 NOTREACHED(); |
| 306 return false; | 374 return false; |
| 307 } | 375 } |
| 308 | 376 |
| 309 bool DownloadItemModel::IsDangerous() const { | 377 bool DownloadItemModel::ShouldShowInShelf() const { |
| 310 return download_->GetSafetyState() == DownloadItem::DANGEROUS; | 378 const DownloadItemModelData* data = DownloadItemModelData::Get(download_); |
| 379 return !data || data->should_show_in_shelf(); | |
| 311 } | 380 } |
| 312 | 381 |
| 313 int64 DownloadItemModel::GetTotalBytes() const { | 382 void DownloadItemModel::SetShouldShowInShelf(bool should_show) { |
| 314 return download_->AllDataSaved() ? download_->GetReceivedBytes() : | 383 DownloadItemModelData* data = DownloadItemModelData::GetOrCreate(download_); |
| 315 download_->GetTotalBytes(); | 384 data->set_should_show_in_shelf(should_show); |
| 316 } | |
| 317 | |
| 318 int64 DownloadItemModel::GetCompletedBytes() const { | |
| 319 return download_->GetReceivedBytes(); | |
| 320 } | 385 } |
| 321 | 386 |
| 322 string16 DownloadItemModel::GetProgressSizesString() const { | 387 string16 DownloadItemModel::GetProgressSizesString() const { |
| 323 string16 size_ratio; | 388 string16 size_ratio; |
| 324 int64 size = GetCompletedBytes(); | 389 int64 size = GetCompletedBytes(); |
| 325 int64 total = GetTotalBytes(); | 390 int64 total = GetTotalBytes(); |
| 326 if (total > 0) { | 391 if (total > 0) { |
| 327 ui::DataUnits amount_units = ui::GetByteDisplayUnits(total); | 392 ui::DataUnits amount_units = ui::GetByteDisplayUnits(total); |
| 328 string16 simple_size = ui::FormatBytesWithUnits(size, amount_units, false); | 393 string16 simple_size = ui::FormatBytesWithUnits(size, amount_units, false); |
| 329 | 394 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 } | 450 } |
| 386 | 451 |
| 387 // In progress download with no known time left and non-zero completed bytes: | 452 // In progress download with no known time left and non-zero completed bytes: |
| 388 // "100/120 MB" or "100 MB" | 453 // "100/120 MB" or "100 MB" |
| 389 if (GetCompletedBytes() > 0) | 454 if (GetCompletedBytes() > 0) |
| 390 return size_ratio; | 455 return size_ratio; |
| 391 | 456 |
| 392 // Instead of displaying "0 B" we say "Starting..." | 457 // Instead of displaying "0 B" we say "Starting..." |
| 393 return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING); | 458 return l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING); |
| 394 } | 459 } |
| OLD | NEW |