// 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 "base/command_line.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/grit/generated_resources.h" #include "content/public/common/content_switches.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::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableDownloadResumption); } } // 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(command_id)); } bool DownloadShelfContextMenu::IsCommandIdChecked(int command_id) const { if (!download_commands_) return false; return download_commands_->IsCommandChecked( static_cast(command_id)); } bool DownloadShelfContextMenu::IsCommandIdVisible(int command_id) const { if (!download_commands_) return false; return download_commands_->IsCommandVisible( static_cast(command_id)); } void DownloadShelfContextMenu::ExecuteCommand(int command_id, int event_flags) { if (!download_commands_) return; download_commands_->ExecuteCommand( static_cast(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(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; } 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(); }