|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "chrome/browser/download/download_shelf_context_menu.h" | 
|  |  | 
|  | #include "build/build_config.h" | 
|  | #include "chrome/browser/download/download_item_model.h" | 
|  | #include "chrome/grit/generated_resources.h" | 
|  | #include "content/public/common/content_features.h" | 
|  | #include "extensions/common/extension.h" | 
|  | #include "ui/base/l10n/l10n_util.h" | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | #include "chrome/browser/ui/pdf/adobe_reader_info_win.h" | 
|  | #endif | 
|  |  | 
|  | using content::DownloadItem; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Returns true if downloads resumption is enabled. | 
|  | bool IsDownloadResumptionEnabled() { | 
|  | return base::FeatureList::IsEnabled(features::kDownloadResumption); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | DownloadShelfContextMenu::~DownloadShelfContextMenu() { | 
|  | DetachFromDownloadItem(); | 
|  | } | 
|  |  | 
|  | DownloadShelfContextMenu::DownloadShelfContextMenu(DownloadItem* download_item) | 
|  | : download_item_(download_item), | 
|  | download_commands_(new DownloadCommands(download_item)) { | 
|  | DCHECK(download_item_); | 
|  | download_item_->AddObserver(this); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetMenuModel() { | 
|  | ui::SimpleMenuModel* model = NULL; | 
|  |  | 
|  | if (!download_item_) | 
|  | return NULL; | 
|  |  | 
|  | DownloadItemModel download_model(download_item_); | 
|  | // We shouldn't be opening a context menu for a dangerous download, unless it | 
|  | // is a malicious download. | 
|  | DCHECK(!download_model.IsDangerous() || download_model.MightBeMalicious()); | 
|  |  | 
|  | if (download_model.IsMalicious()) | 
|  | model = GetMaliciousMenuModel(); | 
|  | else if (download_model.MightBeMalicious()) | 
|  | model = GetMaybeMaliciousMenuModel(); | 
|  | else if (download_item_->GetState() == DownloadItem::COMPLETE) | 
|  | model = GetFinishedMenuModel(); | 
|  | else if (download_item_->GetState() == DownloadItem::INTERRUPTED) | 
|  | model = GetInterruptedMenuModel(); | 
|  | else if (download_item_->IsPaused()) | 
|  | model = GetInProgressPausedMenuModel(); | 
|  | else | 
|  | model = GetInProgressMenuModel(); | 
|  | return model; | 
|  | } | 
|  |  | 
|  | bool DownloadShelfContextMenu::IsCommandIdEnabled(int command_id) const { | 
|  | if (!download_commands_) | 
|  | return false; | 
|  |  | 
|  | return download_commands_->IsCommandEnabled( | 
|  | static_cast<DownloadCommands::Command>(command_id)); | 
|  | } | 
|  |  | 
|  | bool DownloadShelfContextMenu::IsCommandIdChecked(int command_id) const { | 
|  | if (!download_commands_) | 
|  | return false; | 
|  |  | 
|  | return download_commands_->IsCommandChecked( | 
|  | static_cast<DownloadCommands::Command>(command_id)); | 
|  | } | 
|  |  | 
|  | bool DownloadShelfContextMenu::IsCommandIdVisible(int command_id) const { | 
|  | if (!download_commands_) | 
|  | return false; | 
|  |  | 
|  | return download_commands_->IsCommandVisible( | 
|  | static_cast<DownloadCommands::Command>(command_id)); | 
|  | } | 
|  |  | 
|  | void DownloadShelfContextMenu::ExecuteCommand(int command_id, int event_flags) { | 
|  | if (!download_commands_) | 
|  | return; | 
|  |  | 
|  | download_commands_->ExecuteCommand( | 
|  | static_cast<DownloadCommands::Command>(command_id)); | 
|  | } | 
|  |  | 
|  | bool DownloadShelfContextMenu::GetAcceleratorForCommandId( | 
|  | int command_id, | 
|  | ui::Accelerator* accelerator) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool DownloadShelfContextMenu::IsItemForCommandIdDynamic(int command_id) const { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | base::string16 DownloadShelfContextMenu::GetLabelForCommandId( | 
|  | int command_id) const { | 
|  | int id = -1; | 
|  |  | 
|  | switch (static_cast<DownloadCommands::Command>(command_id)) { | 
|  | case DownloadCommands::OPEN_WHEN_COMPLETE: | 
|  | if (download_item_ && !download_item_->IsDone()) | 
|  | id = IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE; | 
|  | else | 
|  | id = IDS_DOWNLOAD_MENU_OPEN; | 
|  | break; | 
|  | case DownloadCommands::PAUSE: | 
|  | id = IDS_DOWNLOAD_MENU_PAUSE_ITEM; | 
|  | break; | 
|  | case DownloadCommands::RESUME: | 
|  | id = IDS_DOWNLOAD_MENU_RESUME_ITEM; | 
|  | break; | 
|  | case DownloadCommands::SHOW_IN_FOLDER: | 
|  | id = IDS_DOWNLOAD_MENU_SHOW; | 
|  | break; | 
|  | case DownloadCommands::DISCARD: | 
|  | id = IDS_DOWNLOAD_MENU_DISCARD; | 
|  | break; | 
|  | case DownloadCommands::KEEP: | 
|  | id = IDS_DOWNLOAD_MENU_KEEP; | 
|  | break; | 
|  | case DownloadCommands::ALWAYS_OPEN_TYPE: { | 
|  | if (download_commands_) { | 
|  | bool can_open_pdf_in_system_viewer = | 
|  | download_commands_->CanOpenPdfInSystemViewer(); | 
|  | #if defined(OS_WIN) | 
|  | if (can_open_pdf_in_system_viewer) { | 
|  | id = IsAdobeReaderDefaultPDFViewer() | 
|  | ? IDS_DOWNLOAD_MENU_ALWAYS_OPEN_PDF_IN_READER | 
|  | : IDS_DOWNLOAD_MENU_PLATFORM_OPEN_ALWAYS; | 
|  | break; | 
|  | } | 
|  | #elif defined(OS_MACOSX) || defined(OS_LINUX) | 
|  | if (can_open_pdf_in_system_viewer) { | 
|  | id = IDS_DOWNLOAD_MENU_PLATFORM_OPEN_ALWAYS; | 
|  | break; | 
|  | } | 
|  | #endif | 
|  | } | 
|  | id = IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE; | 
|  | break; | 
|  | } | 
|  | case DownloadCommands::PLATFORM_OPEN: | 
|  | id = IDS_DOWNLOAD_MENU_PLATFORM_OPEN; | 
|  | break; | 
|  | case DownloadCommands::CANCEL: | 
|  | id = IDS_DOWNLOAD_MENU_CANCEL; | 
|  | break; | 
|  | case DownloadCommands::LEARN_MORE_SCANNING: | 
|  | id = IDS_DOWNLOAD_MENU_LEARN_MORE_SCANNING; | 
|  | break; | 
|  | case DownloadCommands::LEARN_MORE_INTERRUPTED: | 
|  | id = IDS_DOWNLOAD_MENU_LEARN_MORE_INTERRUPTED; | 
|  | break; | 
|  | case DownloadCommands::COPY_TO_CLIPBOARD: | 
|  | // This command is implemented only for Donwload Notification. | 
|  | NOTREACHED(); | 
|  | break; | 
|  | } | 
|  | CHECK(id != -1); | 
|  | return l10n_util::GetStringUTF16(id); | 
|  | } | 
|  |  | 
|  | void DownloadShelfContextMenu::DetachFromDownloadItem() { | 
|  | if (!download_item_) | 
|  | return; | 
|  |  | 
|  | download_commands_.reset(); | 
|  | download_item_->RemoveObserver(this); | 
|  | download_item_ = NULL; | 
|  | } | 
|  |  | 
|  | void DownloadShelfContextMenu::OnDownloadDestroyed(DownloadItem* download) { | 
|  | DCHECK(download_item_ == download); | 
|  | DetachFromDownloadItem(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetInProgressMenuModel() { | 
|  | if (in_progress_download_menu_model_) | 
|  | return in_progress_download_menu_model_.get(); | 
|  |  | 
|  | in_progress_download_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  |  | 
|  | in_progress_download_menu_model_->AddCheckItem( | 
|  | DownloadCommands::OPEN_WHEN_COMPLETE, | 
|  | GetLabelForCommandId(DownloadCommands::OPEN_WHEN_COMPLETE)); | 
|  | in_progress_download_menu_model_->AddCheckItem( | 
|  | DownloadCommands::ALWAYS_OPEN_TYPE, | 
|  | GetLabelForCommandId(DownloadCommands::ALWAYS_OPEN_TYPE)); | 
|  | in_progress_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | in_progress_download_menu_model_->AddItem( | 
|  | DownloadCommands::PAUSE, GetLabelForCommandId(DownloadCommands::PAUSE)); | 
|  | in_progress_download_menu_model_->AddItem( | 
|  | DownloadCommands::SHOW_IN_FOLDER, | 
|  | GetLabelForCommandId(DownloadCommands::SHOW_IN_FOLDER)); | 
|  | in_progress_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | in_progress_download_menu_model_->AddItem( | 
|  | DownloadCommands::CANCEL, GetLabelForCommandId(DownloadCommands::CANCEL)); | 
|  |  | 
|  | return in_progress_download_menu_model_.get(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetInProgressPausedMenuModel() { | 
|  | if (in_progress_download_paused_menu_model_) | 
|  | return in_progress_download_paused_menu_model_.get(); | 
|  |  | 
|  | in_progress_download_paused_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  |  | 
|  | in_progress_download_paused_menu_model_->AddCheckItem( | 
|  | DownloadCommands::OPEN_WHEN_COMPLETE, | 
|  | GetLabelForCommandId(DownloadCommands::OPEN_WHEN_COMPLETE)); | 
|  | in_progress_download_paused_menu_model_->AddCheckItem( | 
|  | DownloadCommands::ALWAYS_OPEN_TYPE, | 
|  | GetLabelForCommandId(DownloadCommands::ALWAYS_OPEN_TYPE)); | 
|  | in_progress_download_paused_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | in_progress_download_paused_menu_model_->AddItem( | 
|  | DownloadCommands::RESUME, GetLabelForCommandId(DownloadCommands::RESUME)); | 
|  | in_progress_download_paused_menu_model_->AddItem( | 
|  | DownloadCommands::SHOW_IN_FOLDER, | 
|  | GetLabelForCommandId(DownloadCommands::SHOW_IN_FOLDER)); | 
|  | in_progress_download_paused_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | in_progress_download_paused_menu_model_->AddItem( | 
|  | DownloadCommands::CANCEL, GetLabelForCommandId(DownloadCommands::CANCEL)); | 
|  |  | 
|  | return in_progress_download_paused_menu_model_.get(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetFinishedMenuModel() { | 
|  | if (finished_download_menu_model_) | 
|  | return finished_download_menu_model_.get(); | 
|  |  | 
|  | finished_download_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  |  | 
|  | finished_download_menu_model_->AddItem( | 
|  | DownloadCommands::OPEN_WHEN_COMPLETE, | 
|  | GetLabelForCommandId(DownloadCommands::OPEN_WHEN_COMPLETE)); | 
|  | finished_download_menu_model_->AddCheckItem( | 
|  | DownloadCommands::ALWAYS_OPEN_TYPE, | 
|  | GetLabelForCommandId(DownloadCommands::ALWAYS_OPEN_TYPE)); | 
|  | finished_download_menu_model_->AddItem( | 
|  | DownloadCommands::PLATFORM_OPEN, | 
|  | GetLabelForCommandId(DownloadCommands::PLATFORM_OPEN)); | 
|  | finished_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | finished_download_menu_model_->AddItem( | 
|  | DownloadCommands::SHOW_IN_FOLDER, | 
|  | GetLabelForCommandId(DownloadCommands::SHOW_IN_FOLDER)); | 
|  | finished_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | finished_download_menu_model_->AddItem( | 
|  | DownloadCommands::CANCEL, GetLabelForCommandId(DownloadCommands::CANCEL)); | 
|  |  | 
|  | return finished_download_menu_model_.get(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetInterruptedMenuModel() { | 
|  | #if !defined(OS_WIN) | 
|  | // If resumption isn't enabled and we aren't on Windows, then none of the | 
|  | // options here are applicable. | 
|  | if (!IsDownloadResumptionEnabled()) | 
|  | return GetInProgressMenuModel(); | 
|  | #endif | 
|  |  | 
|  | if (interrupted_download_menu_model_) | 
|  | return interrupted_download_menu_model_.get(); | 
|  |  | 
|  | interrupted_download_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  |  | 
|  | if (IsDownloadResumptionEnabled()) { | 
|  | interrupted_download_menu_model_->AddItem( | 
|  | DownloadCommands::RESUME, | 
|  | GetLabelForCommandId(DownloadCommands::RESUME)); | 
|  | } | 
|  | #if defined(OS_WIN) | 
|  | // The Help Center article is currently Windows specific. | 
|  | // TODO(asanka): Enable this for other platforms when the article is expanded | 
|  | // for other platforms. | 
|  | interrupted_download_menu_model_->AddItem( | 
|  | DownloadCommands::LEARN_MORE_INTERRUPTED, | 
|  | GetLabelForCommandId(DownloadCommands::LEARN_MORE_INTERRUPTED)); | 
|  | #endif | 
|  | if (IsDownloadResumptionEnabled()) { | 
|  | interrupted_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | interrupted_download_menu_model_->AddItem( | 
|  | DownloadCommands::CANCEL, | 
|  | GetLabelForCommandId(DownloadCommands::CANCEL)); | 
|  | } | 
|  |  | 
|  | return interrupted_download_menu_model_.get(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetMaybeMaliciousMenuModel() { | 
|  | if (maybe_malicious_download_menu_model_) | 
|  | return maybe_malicious_download_menu_model_.get(); | 
|  |  | 
|  | maybe_malicious_download_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  |  | 
|  | maybe_malicious_download_menu_model_->AddItem( | 
|  | DownloadCommands::KEEP, GetLabelForCommandId(DownloadCommands::KEEP)); | 
|  | maybe_malicious_download_menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 
|  | maybe_malicious_download_menu_model_->AddItem( | 
|  | DownloadCommands::LEARN_MORE_SCANNING, | 
|  | GetLabelForCommandId(DownloadCommands::LEARN_MORE_SCANNING)); | 
|  | return maybe_malicious_download_menu_model_.get(); | 
|  | } | 
|  |  | 
|  | ui::SimpleMenuModel* DownloadShelfContextMenu::GetMaliciousMenuModel() { | 
|  | if (malicious_download_menu_model_) | 
|  | return malicious_download_menu_model_.get(); | 
|  |  | 
|  | malicious_download_menu_model_.reset(new ui::SimpleMenuModel(this)); | 
|  | malicious_download_menu_model_->AddItem( | 
|  | DownloadCommands::LEARN_MORE_SCANNING, | 
|  | GetLabelForCommandId(DownloadCommands::LEARN_MORE_SCANNING)); | 
|  |  | 
|  | return malicious_download_menu_model_.get(); | 
|  | } |