diff options
author | arv@chromium.org <arv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 00:55:50 +0000 |
---|---|---|
committer | arv@chromium.org <arv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 00:55:50 +0000 |
commit | 5ed4ba5f65ce49c736bb16ddff31948c17c5938e (patch) | |
tree | 35f65274447876453c22ad46f7b2ef6ab53e4830 /chrome/browser/dom_ui/downloads_dom_handler.cc | |
parent | abcfb02cc5b7605049855bf0a1c53e445f51be4b (diff) | |
download | chromium_src-5ed4ba5f65ce49c736bb16ddff31948c17c5938e.zip chromium_src-5ed4ba5f65ce49c736bb16ddff31948c17c5938e.tar.gz chromium_src-5ed4ba5f65ce49c736bb16ddff31948c17c5938e.tar.bz2 |
Adds a new command line switch called new-new-tab-page which enables
the prototype new new tab page.
Split the DownloadsDOMHandler into its own file.
The prototype is rough and has bugs. Don't file any bugs on it!
TEST=Run with the command line above and you should see an alternative
new tab page.
Review URL: http://codereview.chromium.org/115426
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/dom_ui/downloads_dom_handler.cc')
-rw-r--r-- | chrome/browser/dom_ui/downloads_dom_handler.cc | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/chrome/browser/dom_ui/downloads_dom_handler.cc b/chrome/browser/dom_ui/downloads_dom_handler.cc new file mode 100644 index 0000000..ea56c07 --- /dev/null +++ b/chrome/browser/dom_ui/downloads_dom_handler.cc @@ -0,0 +1,334 @@ +// Copyright (c) 2006-2009 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/dom_ui/downloads_dom_handler.h" + +#include "app/l10n_util.h" +#include "base/gfx/png_encoder.h" +#include "base/string_piece.h" +#include "base/thread.h" +#include "base/time_format.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager.h" +#include "chrome/browser/dom_ui/fileicon_source.h" +#if defined(OS_WIN) +// TODO(port): re-enable when download_util is ported +#include "chrome/browser/download/download_util.h" +#endif +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/profile.h" +#include "chrome/common/jstemplate_builder.h" +#include "chrome/common/time_format.h" +#include "chrome/common/url_constants.h" +#include "grit/browser_resources.h" +#include "grit/generated_resources.h" + +namespace { + +// Maximum number of downloads to show. TODO(glen): Remove this and instead +// stuff the downloads down the pipe slowly. +static const int kMaxDownloads = 150; + +// Sort DownloadItems into descending order by their start time. +class DownloadItemSorter : public std::binary_function<DownloadItem*, + DownloadItem*, + bool> { + public: + bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) { + return lhs->start_time() > rhs->start_time(); + } +}; + +} // namespace + +DownloadsDOMHandler::DownloadsDOMHandler(DOMUI* dom_ui, DownloadManager* dlm) + : DOMMessageHandler(dom_ui), + search_text_(), + download_manager_(dlm) { + dom_ui_->RegisterMessageCallback("getDownloads", + NewCallback(this, &DownloadsDOMHandler::HandleGetDownloads)); + dom_ui_->RegisterMessageCallback("openFile", + NewCallback(this, &DownloadsDOMHandler::HandleOpenFile)); + + dom_ui_->RegisterMessageCallback("drag", + NewCallback(this, &DownloadsDOMHandler::HandleDrag)); + + dom_ui_->RegisterMessageCallback("saveDangerous", + NewCallback(this, &DownloadsDOMHandler::HandleSaveDangerous)); + dom_ui_->RegisterMessageCallback("discardDangerous", + NewCallback(this, &DownloadsDOMHandler::HandleDiscardDangerous)); + dom_ui_->RegisterMessageCallback("show", + NewCallback(this, &DownloadsDOMHandler::HandleShow)); + dom_ui_->RegisterMessageCallback("togglepause", + NewCallback(this, &DownloadsDOMHandler::HandlePause)); + dom_ui_->RegisterMessageCallback("resume", + NewCallback(this, &DownloadsDOMHandler::HandlePause)); + dom_ui_->RegisterMessageCallback("cancel", + NewCallback(this, &DownloadsDOMHandler::HandleCancel)); + dom_ui_->RegisterMessageCallback("clearAll", + NewCallback(this, &DownloadsDOMHandler::HandleClearAll)); + + + // Create our fileicon data source. + g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(&chrome_url_data_manager, + &ChromeURLDataManager::AddDataSource, + new FileIconSource())); +} + +DownloadsDOMHandler::~DownloadsDOMHandler() { + ClearDownloadItems(); + download_manager_->RemoveObserver(this); +} + +// DownloadsDOMHandler, public: ----------------------------------------------- + +void DownloadsDOMHandler::Init() { + download_manager_->AddObserver(this); +} + +void DownloadsDOMHandler::OnDownloadUpdated(DownloadItem* download) { + // Get the id for the download. Our downloads are sorted latest to first, + // and the id is the index into that list. We should be careful of sync + // errors between the UI and the download_items_ list (we may wish to use + // something other than 'id'). + OrderedDownloads::iterator it = find(download_items_.begin(), + download_items_.end(), + download); + if (it == download_items_.end()) + return; + const int id = static_cast<int>(it - download_items_.begin()); + + ListValue results_value; + results_value.Append(CreateDownloadItemValue(download, id)); + dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value); +} + +// A download has started or been deleted. Query our DownloadManager for the +// current set of downloads, which will call us back in SetDownloads once it +// has retrieved them. +void DownloadsDOMHandler::ModelChanged() { + ClearDownloadItems(); + download_manager_->GetDownloads(this, search_text_); +} + +void DownloadsDOMHandler::SetDownloads( + std::vector<DownloadItem*>& downloads) { + ClearDownloadItems(); + + // Swap new downloads in. + download_items_.swap(downloads); + sort(download_items_.begin(), download_items_.end(), DownloadItemSorter()); + + // Scan for any in progress downloads and add ourself to them as an observer. + for (OrderedDownloads::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + if (static_cast<int>(it - download_items_.begin()) > kMaxDownloads) + break; + + DownloadItem* download = *it; + if (download->state() == DownloadItem::IN_PROGRESS) { + // We want to know what happens as the download progresses. + download->AddObserver(this); + } else if (download->safety_state() == DownloadItem::DANGEROUS) { + // We need to be notified when the user validates the dangerous download. + download->AddObserver(this); + } + } + + SendCurrentDownloads(); +} + +void DownloadsDOMHandler::HandleGetDownloads(const Value* value) { + std::wstring new_search = ExtractStringValue(value); + if (search_text_.compare(new_search) != 0) { + search_text_ = new_search; + ClearDownloadItems(); + download_manager_->GetDownloads(this, search_text_); + } else { + SendCurrentDownloads(); + } +} + +void DownloadsDOMHandler::HandleOpenFile(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + download_manager_->OpenDownload(file, NULL); +} + +void DownloadsDOMHandler::HandleDrag(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) { + IconManager* im = g_browser_process->icon_manager(); + SkBitmap* icon = im->LookupIcon(file->full_path(), IconLoader::NORMAL); + download_util::DragDownload(file, icon); + } +} + +void DownloadsDOMHandler::HandleSaveDangerous(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + download_manager_->DangerousDownloadValidated(file); +} + +void DownloadsDOMHandler::HandleDiscardDangerous(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + file->Remove(true); +} + +void DownloadsDOMHandler::HandleShow(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + download_manager_->ShowDownloadInShell(file); +} + +void DownloadsDOMHandler::HandlePause(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + file->TogglePause(); +} + +void DownloadsDOMHandler::HandleCancel(const Value* value) { + DownloadItem* file = GetDownloadByValue(value); + if (file) + file->Cancel(true); +} + +void DownloadsDOMHandler::HandleClearAll(const Value* value) { + download_manager_->RemoveAllDownloads(); +} + +// DownloadsDOMHandler, private: ---------------------------------------------- + +void DownloadsDOMHandler::SendCurrentDownloads() { + ListValue results_value; + for (OrderedDownloads::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + int index = static_cast<int>(it - download_items_.begin()); + if (index > kMaxDownloads) + break; + results_value.Append(CreateDownloadItemValue(*it,index)); + } + + dom_ui_->CallJavascriptFunction(L"downloadsList", results_value); +} + +DictionaryValue* DownloadsDOMHandler::CreateDownloadItemValue( + DownloadItem* download, int id) { + DictionaryValue* file_value = new DictionaryValue(); + + file_value->SetInteger(L"started", + static_cast<int>(download->start_time().ToTimeT())); + file_value->SetString(L"since_string", + TimeFormat::RelativeDate(download->start_time(), NULL)); + file_value->SetString(L"date_string", + base::TimeFormatShortDate(download->start_time())); + file_value->SetInteger(L"id", id); + file_value->SetString(L"file_path", download->full_path().ToWStringHack()); + file_value->SetString(L"file_name", download->GetFileName().ToWStringHack()); + file_value->SetString(L"url", download->url().spec()); + + if (download->state() == DownloadItem::IN_PROGRESS) { + if (download->safety_state() == DownloadItem::DANGEROUS) { + file_value->SetString(L"state", L"DANGEROUS"); + } else if (download->is_paused()) { + file_value->SetString(L"state", L"PAUSED"); + } else { + file_value->SetString(L"state", L"IN_PROGRESS"); + } + + file_value->SetString(L"progress_status_text", + GetProgressStatusText(download)); + + file_value->SetInteger(L"percent", + static_cast<int>(download->PercentComplete())); + file_value->SetInteger(L"received", + static_cast<int>(download->received_bytes())); + } else if (download->state() == DownloadItem::CANCELLED) { + file_value->SetString(L"state", L"CANCELLED"); + } else if (download->state() == DownloadItem::COMPLETE) { + if (download->safety_state() == DownloadItem::DANGEROUS) { + file_value->SetString(L"state", L"DANGEROUS"); + } else { + file_value->SetString(L"state", L"COMPLETE"); + } + } + + file_value->SetInteger(L"total", + static_cast<int>(download->total_bytes())); + + return file_value; +} + +void DownloadsDOMHandler::ClearDownloadItems() { + // Clear out old state and remove self as observer for each download. + for (OrderedDownloads::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + (*it)->RemoveObserver(this); + } + download_items_.clear(); +} + +DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) { + for (OrderedDownloads::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + if (static_cast<int>(it - download_items_.begin() == id)) { + return (*it); + } + } + + return NULL; +} + +DownloadItem* DownloadsDOMHandler::GetDownloadByValue(const Value* value) { + int id; + if (ExtractIntegerValue(value, &id)) { + return GetDownloadById(id); + } + return NULL; +} + +std::wstring DownloadsDOMHandler::GetProgressStatusText( + DownloadItem* download) { + int64 total = download->total_bytes(); + int64 size = download->received_bytes(); + DataUnits amount_units = GetByteDisplayUnits(size); + std::wstring received_size = FormatBytes(size, amount_units, true); + std::wstring amount = received_size; + + // Adjust both strings for the locale direction since we don't yet know which + // string we'll end up using for constructing the final progress string. + std::wstring amount_localized; + if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) { + amount.assign(amount_localized); + received_size.assign(amount_localized); + } + + if (total) { + amount_units = GetByteDisplayUnits(total); + std::wstring total_text = FormatBytes(total, amount_units, true); + std::wstring total_text_localized; + if (l10n_util::AdjustStringForLocaleDirection(total_text, + &total_text_localized)) + total_text.assign(total_text_localized); + + amount = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SIZE, + received_size, + total_text); + } else { + amount.assign(received_size); + } + amount_units = GetByteDisplayUnits(download->CurrentSpeed()); + std::wstring speed_text = FormatSpeed(download->CurrentSpeed(), + amount_units, true); + std::wstring speed_text_localized; + if (l10n_util::AdjustStringForLocaleDirection(speed_text, + &speed_text_localized)) + speed_text.assign(speed_text_localized); + + return l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SPEED, + speed_text, + amount); +} |