blob: 53dc0235bad8ccdd4586314bbadff16cca01b28b [file] [log] [blame]
// 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;
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 (interrupted_download_menu_model_)
return interrupted_download_menu_model_.get();
interrupted_download_menu_model_.reset(new ui::SimpleMenuModel(this));
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
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();
}